blob: 562036c113d6ae30eda17777dfc7716fb5eb8bd2 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098
99#define g_mode_rates_size (12)
100#define a_mode_rates_size (8)
101#define FREQ_BASE_80211G (2407)
102#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700103#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530104#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700105#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800106 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700107
108#define HDD2GHZCHAN(freq, chan, flag) { \
109 .band = IEEE80211_BAND_2GHZ, \
110 .center_freq = (freq), \
111 .hw_value = (chan),\
112 .flags = (flag), \
113 .max_antenna_gain = 0 ,\
114 .max_power = 30, \
115}
116
117#define HDD5GHZCHAN(freq, chan, flag) { \
118 .band = IEEE80211_BAND_5GHZ, \
119 .center_freq = (freq), \
120 .hw_value = (chan),\
121 .flags = (flag), \
122 .max_antenna_gain = 0 ,\
123 .max_power = 30, \
124}
125
126#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
127{\
128 .bitrate = rate, \
129 .hw_value = rate_id, \
130 .flags = flag, \
131}
132
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530133#ifdef WLAN_FEATURE_VOWIFI_11R
134#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
135#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
136#endif
137
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530138#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530139#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530140
Sunil Duttc69bccb2014-05-26 21:30:20 +0530141#ifdef WLAN_FEATURE_LINK_LAYER_STATS
142/*
143 * Used to allocate the size of 4096 for the link layer stats.
144 * The size of 4096 is considered assuming that all data per
145 * respective event fit with in the limit.Please take a call
146 * on the limit based on the data requirements on link layer
147 * statistics.
148 */
149#define LL_STATS_EVENT_BUF_SIZE 4096
150#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530151#ifdef WLAN_FEATURE_EXTSCAN
152/*
153 * Used to allocate the size of 4096 for the EXTScan NL data.
154 * The size of 4096 is considered assuming that all data per
155 * respective event fit with in the limit.Please take a call
156 * on the limit based on the data requirements.
157 */
158
159#define EXTSCAN_EVENT_BUF_SIZE 4096
160#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
161#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530162
Atul Mittal115287b2014-07-08 13:26:33 +0530163/*EXT TDLS*/
164/*
165 * Used to allocate the size of 4096 for the TDLS.
166 * The size of 4096 is considered assuming that all data per
167 * respective event fit with in the limit.Please take a call
168 * on the limit based on the data requirements on link layer
169 * statistics.
170 */
171#define EXTTDLS_EVENT_BUF_SIZE 4096
172
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530173static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700174{
175 WLAN_CIPHER_SUITE_WEP40,
176 WLAN_CIPHER_SUITE_WEP104,
177 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800178#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700179#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
180 WLAN_CIPHER_SUITE_KRK,
181 WLAN_CIPHER_SUITE_CCMP,
182#else
183 WLAN_CIPHER_SUITE_CCMP,
184#endif
185#ifdef FEATURE_WLAN_WAPI
186 WLAN_CIPHER_SUITE_SMS4,
187#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700188#ifdef WLAN_FEATURE_11W
189 WLAN_CIPHER_SUITE_AES_CMAC,
190#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700191};
192
193static inline int is_broadcast_ether_addr(const u8 *addr)
194{
195 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
196 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
197}
198
199static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530200{
Jeff Johnson295189b2012-06-20 16:38:30 -0700201 HDD2GHZCHAN(2412, 1, 0) ,
202 HDD2GHZCHAN(2417, 2, 0) ,
203 HDD2GHZCHAN(2422, 3, 0) ,
204 HDD2GHZCHAN(2427, 4, 0) ,
205 HDD2GHZCHAN(2432, 5, 0) ,
206 HDD2GHZCHAN(2437, 6, 0) ,
207 HDD2GHZCHAN(2442, 7, 0) ,
208 HDD2GHZCHAN(2447, 8, 0) ,
209 HDD2GHZCHAN(2452, 9, 0) ,
210 HDD2GHZCHAN(2457, 10, 0) ,
211 HDD2GHZCHAN(2462, 11, 0) ,
212 HDD2GHZCHAN(2467, 12, 0) ,
213 HDD2GHZCHAN(2472, 13, 0) ,
214 HDD2GHZCHAN(2484, 14, 0) ,
215};
216
Jeff Johnson295189b2012-06-20 16:38:30 -0700217static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
218{
219 HDD2GHZCHAN(2412, 1, 0) ,
220 HDD2GHZCHAN(2437, 6, 0) ,
221 HDD2GHZCHAN(2462, 11, 0) ,
222};
Jeff Johnson295189b2012-06-20 16:38:30 -0700223
224static struct ieee80211_channel hdd_channels_5_GHZ[] =
225{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700226 HDD5GHZCHAN(4920, 240, 0) ,
227 HDD5GHZCHAN(4940, 244, 0) ,
228 HDD5GHZCHAN(4960, 248, 0) ,
229 HDD5GHZCHAN(4980, 252, 0) ,
230 HDD5GHZCHAN(5040, 208, 0) ,
231 HDD5GHZCHAN(5060, 212, 0) ,
232 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700233 HDD5GHZCHAN(5180, 36, 0) ,
234 HDD5GHZCHAN(5200, 40, 0) ,
235 HDD5GHZCHAN(5220, 44, 0) ,
236 HDD5GHZCHAN(5240, 48, 0) ,
237 HDD5GHZCHAN(5260, 52, 0) ,
238 HDD5GHZCHAN(5280, 56, 0) ,
239 HDD5GHZCHAN(5300, 60, 0) ,
240 HDD5GHZCHAN(5320, 64, 0) ,
241 HDD5GHZCHAN(5500,100, 0) ,
242 HDD5GHZCHAN(5520,104, 0) ,
243 HDD5GHZCHAN(5540,108, 0) ,
244 HDD5GHZCHAN(5560,112, 0) ,
245 HDD5GHZCHAN(5580,116, 0) ,
246 HDD5GHZCHAN(5600,120, 0) ,
247 HDD5GHZCHAN(5620,124, 0) ,
248 HDD5GHZCHAN(5640,128, 0) ,
249 HDD5GHZCHAN(5660,132, 0) ,
250 HDD5GHZCHAN(5680,136, 0) ,
251 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800252#ifdef FEATURE_WLAN_CH144
253 HDD5GHZCHAN(5720,144, 0) ,
254#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700255 HDD5GHZCHAN(5745,149, 0) ,
256 HDD5GHZCHAN(5765,153, 0) ,
257 HDD5GHZCHAN(5785,157, 0) ,
258 HDD5GHZCHAN(5805,161, 0) ,
259 HDD5GHZCHAN(5825,165, 0) ,
260};
261
262static struct ieee80211_rate g_mode_rates[] =
263{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530264 HDD_G_MODE_RATETAB(10, 0x1, 0),
265 HDD_G_MODE_RATETAB(20, 0x2, 0),
266 HDD_G_MODE_RATETAB(55, 0x4, 0),
267 HDD_G_MODE_RATETAB(110, 0x8, 0),
268 HDD_G_MODE_RATETAB(60, 0x10, 0),
269 HDD_G_MODE_RATETAB(90, 0x20, 0),
270 HDD_G_MODE_RATETAB(120, 0x40, 0),
271 HDD_G_MODE_RATETAB(180, 0x80, 0),
272 HDD_G_MODE_RATETAB(240, 0x100, 0),
273 HDD_G_MODE_RATETAB(360, 0x200, 0),
274 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700275 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530276};
Jeff Johnson295189b2012-06-20 16:38:30 -0700277
278static struct ieee80211_rate a_mode_rates[] =
279{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530280 HDD_G_MODE_RATETAB(60, 0x10, 0),
281 HDD_G_MODE_RATETAB(90, 0x20, 0),
282 HDD_G_MODE_RATETAB(120, 0x40, 0),
283 HDD_G_MODE_RATETAB(180, 0x80, 0),
284 HDD_G_MODE_RATETAB(240, 0x100, 0),
285 HDD_G_MODE_RATETAB(360, 0x200, 0),
286 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700287 HDD_G_MODE_RATETAB(540, 0x800, 0),
288};
289
290static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
291{
292 .channels = hdd_channels_2_4_GHZ,
293 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
294 .band = IEEE80211_BAND_2GHZ,
295 .bitrates = g_mode_rates,
296 .n_bitrates = g_mode_rates_size,
297 .ht_cap.ht_supported = 1,
298 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
299 | IEEE80211_HT_CAP_GRN_FLD
300 | IEEE80211_HT_CAP_DSSSCCK40
301 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
302 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
303 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
304 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
305 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
306 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
307};
308
Jeff Johnson295189b2012-06-20 16:38:30 -0700309static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
310{
311 .channels = hdd_social_channels_2_4_GHZ,
312 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
313 .band = IEEE80211_BAND_2GHZ,
314 .bitrates = g_mode_rates,
315 .n_bitrates = g_mode_rates_size,
316 .ht_cap.ht_supported = 1,
317 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
318 | IEEE80211_HT_CAP_GRN_FLD
319 | IEEE80211_HT_CAP_DSSSCCK40
320 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
321 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
322 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
323 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
324 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
325 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
326};
Jeff Johnson295189b2012-06-20 16:38:30 -0700327
328static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
329{
330 .channels = hdd_channels_5_GHZ,
331 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
332 .band = IEEE80211_BAND_5GHZ,
333 .bitrates = a_mode_rates,
334 .n_bitrates = a_mode_rates_size,
335 .ht_cap.ht_supported = 1,
336 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
337 | IEEE80211_HT_CAP_GRN_FLD
338 | IEEE80211_HT_CAP_DSSSCCK40
339 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
340 | IEEE80211_HT_CAP_SGI_40
341 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
342 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
343 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
344 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
345 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
346 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
347};
348
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530349/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700350 TX/RX direction for each kind of interface */
351static const struct ieee80211_txrx_stypes
352wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
353 [NL80211_IFTYPE_STATION] = {
354 .tx = 0xffff,
355 .rx = BIT(SIR_MAC_MGMT_ACTION) |
356 BIT(SIR_MAC_MGMT_PROBE_REQ),
357 },
358 [NL80211_IFTYPE_AP] = {
359 .tx = 0xffff,
360 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
361 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
362 BIT(SIR_MAC_MGMT_PROBE_REQ) |
363 BIT(SIR_MAC_MGMT_DISASSOC) |
364 BIT(SIR_MAC_MGMT_AUTH) |
365 BIT(SIR_MAC_MGMT_DEAUTH) |
366 BIT(SIR_MAC_MGMT_ACTION),
367 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700368 [NL80211_IFTYPE_ADHOC] = {
369 .tx = 0xffff,
370 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
371 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
372 BIT(SIR_MAC_MGMT_PROBE_REQ) |
373 BIT(SIR_MAC_MGMT_DISASSOC) |
374 BIT(SIR_MAC_MGMT_AUTH) |
375 BIT(SIR_MAC_MGMT_DEAUTH) |
376 BIT(SIR_MAC_MGMT_ACTION),
377 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700378 [NL80211_IFTYPE_P2P_CLIENT] = {
379 .tx = 0xffff,
380 .rx = BIT(SIR_MAC_MGMT_ACTION) |
381 BIT(SIR_MAC_MGMT_PROBE_REQ),
382 },
383 [NL80211_IFTYPE_P2P_GO] = {
384 /* This is also same as for SoftAP */
385 .tx = 0xffff,
386 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
387 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
388 BIT(SIR_MAC_MGMT_PROBE_REQ) |
389 BIT(SIR_MAC_MGMT_DISASSOC) |
390 BIT(SIR_MAC_MGMT_AUTH) |
391 BIT(SIR_MAC_MGMT_DEAUTH) |
392 BIT(SIR_MAC_MGMT_ACTION),
393 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700394};
395
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800396#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800397static const struct ieee80211_iface_limit
398wlan_hdd_iface_limit[] = {
399 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800400 /* max = 3 ; Our driver create two interfaces during driver init
401 * wlan0 and p2p0 interfaces. p2p0 is considered as station
402 * interface until a group is formed. In JB architecture, once the
403 * group is formed, interface type of p2p0 is changed to P2P GO or
404 * Client.
405 * When supplicant remove the group, it first issue a set interface
406 * cmd to change the mode back to Station. In JB this works fine as
407 * we advertize two station type interface during driver init.
408 * Some vendors create separate interface for P2P GO/Client,
409 * after group formation(Third one). But while group remove
410 * supplicant first tries to change the mode(3rd interface) to STATION
411 * But as we advertized only two sta type interfaces nl80211 was
412 * returning error for the third one which was leading to failure in
413 * delete interface. Ideally while removing the group, supplicant
414 * should not try to change the 3rd interface mode to Station type.
415 * Till we get a fix in wpa_supplicant, we advertize max STA
416 * interface type to 3
417 */
418 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800419 .types = BIT(NL80211_IFTYPE_STATION),
420 },
421 {
422 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700423 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800424 },
425 {
426 .max = 1,
427 .types = BIT(NL80211_IFTYPE_P2P_GO) |
428 BIT(NL80211_IFTYPE_P2P_CLIENT),
429 },
430};
431
432/* By default, only single channel concurrency is allowed */
433static struct ieee80211_iface_combination
434wlan_hdd_iface_combination = {
435 .limits = wlan_hdd_iface_limit,
436 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800437 /*
438 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
439 * and p2p0 interfaces during driver init
440 * Some vendors create separate interface for P2P operations.
441 * wlan0: STA interface
442 * p2p0: P2P Device interface, action frames goes
443 * through this interface.
444 * p2p-xx: P2P interface, After GO negotiation this interface is
445 * created for p2p operations(GO/CLIENT interface).
446 */
447 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800448 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
449 .beacon_int_infra_match = false,
450};
451#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800452
Jeff Johnson295189b2012-06-20 16:38:30 -0700453static struct cfg80211_ops wlan_hdd_cfg80211_ops;
454
455/* Data rate 100KBPS based on IE Index */
456struct index_data_rate_type
457{
458 v_U8_t beacon_rate_index;
459 v_U16_t supported_rate[4];
460};
461
462/* 11B, 11G Rate table include Basic rate and Extended rate
463 The IDX field is the rate index
464 The HI field is the rate when RSSI is strong or being ignored
465 (in this case we report actual rate)
466 The MID field is the rate when RSSI is moderate
467 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
468 The LO field is the rate when RSSI is low
469 (in this case we don't report rates, actual current rate used)
470 */
471static const struct
472{
473 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700474 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700475} supported_data_rate[] =
476{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700477/* IDX HI HM LM LO (RSSI-based index */
478 {2, { 10, 10, 10, 0}},
479 {4, { 20, 20, 10, 0}},
480 {11, { 55, 20, 10, 0}},
481 {12, { 60, 55, 20, 0}},
482 {18, { 90, 55, 20, 0}},
483 {22, {110, 55, 20, 0}},
484 {24, {120, 90, 60, 0}},
485 {36, {180, 120, 60, 0}},
486 {44, {220, 180, 60, 0}},
487 {48, {240, 180, 90, 0}},
488 {66, {330, 180, 90, 0}},
489 {72, {360, 240, 90, 0}},
490 {96, {480, 240, 120, 0}},
491 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700492};
493
494/* MCS Based rate table */
495static struct index_data_rate_type supported_mcs_rate[] =
496{
497/* MCS L20 L40 S20 S40 */
498 {0, {65, 135, 72, 150}},
499 {1, {130, 270, 144, 300}},
500 {2, {195, 405, 217, 450}},
501 {3, {260, 540, 289, 600}},
502 {4, {390, 810, 433, 900}},
503 {5, {520, 1080, 578, 1200}},
504 {6, {585, 1215, 650, 1350}},
505 {7, {650, 1350, 722, 1500}}
506};
507
Leo Chang6f8870f2013-03-26 18:11:36 -0700508#ifdef WLAN_FEATURE_11AC
509
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530510#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700511
512struct index_vht_data_rate_type
513{
514 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530515 v_U16_t supported_VHT80_rate[2];
516 v_U16_t supported_VHT40_rate[2];
517 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700518};
519
520typedef enum
521{
522 DATA_RATE_11AC_MAX_MCS_7,
523 DATA_RATE_11AC_MAX_MCS_8,
524 DATA_RATE_11AC_MAX_MCS_9,
525 DATA_RATE_11AC_MAX_MCS_NA
526} eDataRate11ACMaxMcs;
527
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530528/* SSID broadcast type */
529typedef enum eSSIDBcastType
530{
531 eBCAST_UNKNOWN = 0,
532 eBCAST_NORMAL = 1,
533 eBCAST_HIDDEN = 2,
534} tSSIDBcastType;
535
Leo Chang6f8870f2013-03-26 18:11:36 -0700536/* MCS Based VHT rate table */
537static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
538{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530539/* MCS L80 S80 L40 S40 L20 S40*/
540 {0, {293, 325}, {135, 150}, {65, 72}},
541 {1, {585, 650}, {270, 300}, {130, 144}},
542 {2, {878, 975}, {405, 450}, {195, 217}},
543 {3, {1170, 1300}, {540, 600}, {260, 289}},
544 {4, {1755, 1950}, {810, 900}, {390, 433}},
545 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
546 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
547 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
548 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
549 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700550};
551#endif /* WLAN_FEATURE_11AC */
552
c_hpothu79aab322014-07-14 21:11:01 +0530553/*array index points to MCS and array value points respective rssi*/
554static int rssiMcsTbl[][10] =
555{
556/*MCS 0 1 2 3 4 5 6 7 8 9*/
557 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
558 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
559 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
560};
561
Jeff Johnson295189b2012-06-20 16:38:30 -0700562extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530563#ifdef FEATURE_WLAN_SCAN_PNO
564static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
565#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700566
Leo Chang9056f462013-08-01 19:21:11 -0700567#ifdef WLAN_NL80211_TESTMODE
568enum wlan_hdd_tm_attr
569{
570 WLAN_HDD_TM_ATTR_INVALID = 0,
571 WLAN_HDD_TM_ATTR_CMD = 1,
572 WLAN_HDD_TM_ATTR_DATA = 2,
573 WLAN_HDD_TM_ATTR_TYPE = 3,
574 /* keep last */
575 WLAN_HDD_TM_ATTR_AFTER_LAST,
576 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
577};
578
579enum wlan_hdd_tm_cmd
580{
581 WLAN_HDD_TM_CMD_WLAN_HB = 1,
582};
583
584#define WLAN_HDD_TM_DATA_MAX_LEN 5000
585
586static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
587{
588 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
589 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
590 .len = WLAN_HDD_TM_DATA_MAX_LEN },
591};
592#endif /* WLAN_NL80211_TESTMODE */
593
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800594#ifdef FEATURE_WLAN_CH_AVOID
595/*
596 * FUNCTION: wlan_hdd_send_avoid_freq_event
597 * This is called when wlan driver needs to send vendor specific
598 * avoid frequency range event to userspace
599 */
600int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
601 tHddAvoidFreqList *pAvoidFreqList)
602{
603 struct sk_buff *vendor_event;
604
605 ENTER();
606
607 if (!pHddCtx)
608 {
609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
610 "%s: HDD context is null", __func__);
611 return -1;
612 }
613
614 if (!pAvoidFreqList)
615 {
616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
617 "%s: pAvoidFreqList is null", __func__);
618 return -1;
619 }
620
621 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530622#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
623 NULL,
624#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800625 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530626 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800627 GFP_KERNEL);
628 if (!vendor_event)
629 {
630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
631 "%s: cfg80211_vendor_event_alloc failed", __func__);
632 return -1;
633 }
634
635 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
636 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
637
638 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
639
640 EXIT();
641 return 0;
642}
643#endif /* FEATURE_WLAN_CH_AVOID */
644
Srinivas Dasari030bad32015-02-18 23:23:54 +0530645/*
646 * FUNCTION: __wlan_hdd_cfg80211_nan_request
647 * This is called when wlan driver needs to send vendor specific
648 * nan request event.
649 */
650static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
651 struct wireless_dev *wdev,
652 const void *data, int data_len)
653{
654 tNanRequestReq nan_req;
655 VOS_STATUS status;
656 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530657 struct net_device *dev = wdev->netdev;
658 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
659 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530660 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
661
662 if (0 == data_len)
663 {
664 hddLog(VOS_TRACE_LEVEL_ERROR,
665 FL("NAN - Invalid Request, length = 0"));
666 return ret_val;
667 }
668
669 if (NULL == data)
670 {
671 hddLog(VOS_TRACE_LEVEL_ERROR,
672 FL("NAN - Invalid Request, data is NULL"));
673 return ret_val;
674 }
675
676 status = wlan_hdd_validate_context(pHddCtx);
677 if (0 != status)
678 {
679 hddLog(VOS_TRACE_LEVEL_ERROR,
680 FL("HDD context is not valid"));
681 return -EINVAL;
682 }
683
684 hddLog(LOG1, FL("Received NAN command"));
685 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
686 (tANI_U8 *)data, data_len);
687
688 /* check the NAN Capability */
689 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
690 {
691 hddLog(VOS_TRACE_LEVEL_ERROR,
692 FL("NAN is not supported by Firmware"));
693 return -EINVAL;
694 }
695
696 nan_req.request_data_len = data_len;
697 nan_req.request_data = data;
698
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530699 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530700 if (VOS_STATUS_SUCCESS == status)
701 {
702 ret_val = 0;
703 }
704 return ret_val;
705}
706
707/*
708 * FUNCTION: wlan_hdd_cfg80211_nan_request
709 * Wrapper to protect the nan vendor command from ssr
710 */
711static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
712 struct wireless_dev *wdev,
713 const void *data, int data_len)
714{
715 int ret;
716
717 vos_ssr_protect(__func__);
718 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
719 vos_ssr_unprotect(__func__);
720
721 return ret;
722}
723
724/*
725 * FUNCTION: wlan_hdd_cfg80211_nan_callback
726 * This is a callback function and it gets called
727 * when we need to report nan response event to
728 * upper layers.
729 */
730static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
731{
732 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
733 struct sk_buff *vendor_event;
734 int status;
735 tSirNanEvent *data;
736
737 ENTER();
738 if (NULL == msg)
739 {
740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
741 FL(" msg received here is null"));
742 return;
743 }
744 data = msg;
745
746 status = wlan_hdd_validate_context(pHddCtx);
747
748 if (0 != status)
749 {
750 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
751 FL("HDD context is not valid"));
752 return;
753 }
754
755 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530756#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
757 NULL,
758#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530759 data->event_data_len +
760 NLMSG_HDRLEN,
761 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
762 GFP_KERNEL);
763
764 if (!vendor_event)
765 {
766 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
767 FL("cfg80211_vendor_event_alloc failed"));
768 return;
769 }
770 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
771 data->event_data_len, data->event_data))
772 {
773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
774 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
775 kfree_skb(vendor_event);
776 return;
777 }
778 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
779 EXIT();
780}
781
782/*
783 * FUNCTION: wlan_hdd_cfg80211_nan_init
784 * This function is called to register the callback to sme layer
785 */
786inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
787{
788 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
789}
790
791
Sunil Duttc69bccb2014-05-26 21:30:20 +0530792#ifdef WLAN_FEATURE_LINK_LAYER_STATS
793
794static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
795 struct sk_buff *vendor_event)
796{
797 if (nla_put_u8(vendor_event,
798 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
799 stats->rate.preamble) ||
800 nla_put_u8(vendor_event,
801 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
802 stats->rate.nss) ||
803 nla_put_u8(vendor_event,
804 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
805 stats->rate.bw) ||
806 nla_put_u8(vendor_event,
807 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
808 stats->rate.rateMcsIdx) ||
809 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
810 stats->rate.bitrate ) ||
811 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
812 stats->txMpdu ) ||
813 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
814 stats->rxMpdu ) ||
815 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
816 stats->mpduLost ) ||
817 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
818 stats->retries) ||
819 nla_put_u32(vendor_event,
820 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
821 stats->retriesShort ) ||
822 nla_put_u32(vendor_event,
823 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
824 stats->retriesLong))
825 {
826 hddLog(VOS_TRACE_LEVEL_ERROR,
827 FL("QCA_WLAN_VENDOR_ATTR put fail"));
828 return FALSE;
829 }
830 return TRUE;
831}
832
833static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
834 struct sk_buff *vendor_event)
835{
836 u32 i = 0;
837 struct nlattr *rateInfo;
838 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
839 stats->type) ||
840 nla_put(vendor_event,
841 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
842 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
843 nla_put_u32(vendor_event,
844 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
845 stats->capabilities) ||
846 nla_put_u32(vendor_event,
847 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
848 stats->numRate))
849 {
850 hddLog(VOS_TRACE_LEVEL_ERROR,
851 FL("QCA_WLAN_VENDOR_ATTR put fail"));
852 goto error;
853 }
854
855 rateInfo = nla_nest_start(vendor_event,
856 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530857 if(!rateInfo)
858 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530859 for (i = 0; i < stats->numRate; i++)
860 {
861 struct nlattr *rates;
862 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
863 stats->rateStats +
864 (i * sizeof(tSirWifiRateStat)));
865 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530866 if(!rates)
867 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530868
869 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
870 {
871 hddLog(VOS_TRACE_LEVEL_ERROR,
872 FL("QCA_WLAN_VENDOR_ATTR put fail"));
873 return FALSE;
874 }
875 nla_nest_end(vendor_event, rates);
876 }
877 nla_nest_end(vendor_event, rateInfo);
878
879 return TRUE;
880error:
881 return FALSE;
882}
883
884static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
885 struct sk_buff *vendor_event)
886{
887 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
888 stats->ac ) ||
889 nla_put_u32(vendor_event,
890 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
891 stats->txMpdu ) ||
892 nla_put_u32(vendor_event,
893 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
894 stats->rxMpdu ) ||
895 nla_put_u32(vendor_event,
896 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
897 stats->txMcast ) ||
898 nla_put_u32(vendor_event,
899 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
900 stats->rxMcast ) ||
901 nla_put_u32(vendor_event,
902 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
903 stats->rxAmpdu ) ||
904 nla_put_u32(vendor_event,
905 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
906 stats->txAmpdu ) ||
907 nla_put_u32(vendor_event,
908 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
909 stats->mpduLost )||
910 nla_put_u32(vendor_event,
911 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
912 stats->retries ) ||
913 nla_put_u32(vendor_event,
914 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
915 stats->retriesShort ) ||
916 nla_put_u32(vendor_event,
917 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
918 stats->retriesLong ) ||
919 nla_put_u32(vendor_event,
920 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
921 stats->contentionTimeMin ) ||
922 nla_put_u32(vendor_event,
923 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
924 stats->contentionTimeMax ) ||
925 nla_put_u32(vendor_event,
926 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
927 stats->contentionTimeAvg ) ||
928 nla_put_u32(vendor_event,
929 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
930 stats->contentionNumSamples ))
931 {
932 hddLog(VOS_TRACE_LEVEL_ERROR,
933 FL("QCA_WLAN_VENDOR_ATTR put fail") );
934 return FALSE;
935 }
936 return TRUE;
937}
938
939static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
940 struct sk_buff *vendor_event)
941{
Dino Myclec8f3f332014-07-21 16:48:27 +0530942 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530943 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
944 nla_put(vendor_event,
945 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
946 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
947 nla_put_u32(vendor_event,
948 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
949 stats->state ) ||
950 nla_put_u32(vendor_event,
951 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
952 stats->roaming ) ||
953 nla_put_u32(vendor_event,
954 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
955 stats->capabilities ) ||
956 nla_put(vendor_event,
957 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
958 strlen(stats->ssid), stats->ssid) ||
959 nla_put(vendor_event,
960 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
961 WNI_CFG_BSSID_LEN, stats->bssid) ||
962 nla_put(vendor_event,
963 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
964 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
965 nla_put(vendor_event,
966 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
967 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
968 )
969 {
970 hddLog(VOS_TRACE_LEVEL_ERROR,
971 FL("QCA_WLAN_VENDOR_ATTR put fail") );
972 return FALSE;
973 }
974 return TRUE;
975}
976
Dino Mycle3b9536d2014-07-09 22:05:24 +0530977static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
978 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530979 struct sk_buff *vendor_event)
980{
981 int i = 0;
982 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530983 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
984 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530985 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530986
Sunil Duttc69bccb2014-05-26 21:30:20 +0530987 if (FALSE == put_wifi_interface_info(
988 &pWifiIfaceStat->info,
989 vendor_event))
990 {
991 hddLog(VOS_TRACE_LEVEL_ERROR,
992 FL("QCA_WLAN_VENDOR_ATTR put fail") );
993 return FALSE;
994
995 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530996 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
997 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
998 if (NULL == pWifiIfaceStatTL)
999 {
1000 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1001 return FALSE;
1002 }
1003
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301004 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1005 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1006 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1007 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1008
1009 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1010 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1011 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1012 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301013
1014 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1015 {
1016 if (VOS_STATUS_SUCCESS ==
1017 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1018 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1019 {
1020 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1021 * obtained from TL structure
1022 */
1023
1024 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1025 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301026 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1027
Srinivas Dasari98947432014-11-07 19:41:24 +05301028 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1029 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1030 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1031 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1032 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1033 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1034 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1035 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301036
Srinivas Dasari98947432014-11-07 19:41:24 +05301037 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1038 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1039 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1040 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1041 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1042 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1043 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1044 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301045
Srinivas Dasari98947432014-11-07 19:41:24 +05301046 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1047 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1048 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1049 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1050 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1051 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1052 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1053 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301054 }
1055 else
1056 {
1057 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1058 }
1059
Dino Mycle3b9536d2014-07-09 22:05:24 +05301060 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1061 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1062 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1063 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1064 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1065 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1066 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1067 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1068 }
1069 else
1070 {
1071 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1072 }
1073
1074
Sunil Duttc69bccb2014-05-26 21:30:20 +05301075
1076 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301077 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1078 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1079 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301080 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1081 pWifiIfaceStat->beaconRx) ||
1082 nla_put_u32(vendor_event,
1083 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1084 pWifiIfaceStat->mgmtRx) ||
1085 nla_put_u32(vendor_event,
1086 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1087 pWifiIfaceStat->mgmtActionRx) ||
1088 nla_put_u32(vendor_event,
1089 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1090 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301091 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301092 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1093 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301094 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301095 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1096 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301097 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301098 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1099 pWifiIfaceStat->rssiAck))
1100 {
1101 hddLog(VOS_TRACE_LEVEL_ERROR,
1102 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301103 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301104 return FALSE;
1105 }
1106
1107 wmmInfo = nla_nest_start(vendor_event,
1108 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301109 if(!wmmInfo)
1110 {
1111 vos_mem_free(pWifiIfaceStatTL);
1112 return FALSE;
1113 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301114 for (i = 0; i < WIFI_AC_MAX; i++)
1115 {
1116 struct nlattr *wmmStats;
1117 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301118 if(!wmmStats)
1119 {
1120 vos_mem_free(pWifiIfaceStatTL);
1121 return FALSE;
1122 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301123 if (FALSE == put_wifi_wmm_ac_stat(
1124 &pWifiIfaceStat->AccessclassStats[i],
1125 vendor_event))
1126 {
1127 hddLog(VOS_TRACE_LEVEL_ERROR,
1128 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301129 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301130 return FALSE;
1131 }
1132
1133 nla_nest_end(vendor_event, wmmStats);
1134 }
1135 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301136 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301137 return TRUE;
1138}
1139
1140static tSirWifiInterfaceMode
1141 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1142{
1143 switch (deviceMode)
1144 {
1145 case WLAN_HDD_INFRA_STATION:
1146 return WIFI_INTERFACE_STA;
1147 case WLAN_HDD_SOFTAP:
1148 return WIFI_INTERFACE_SOFTAP;
1149 case WLAN_HDD_P2P_CLIENT:
1150 return WIFI_INTERFACE_P2P_CLIENT;
1151 case WLAN_HDD_P2P_GO:
1152 return WIFI_INTERFACE_P2P_GO;
1153 case WLAN_HDD_IBSS:
1154 return WIFI_INTERFACE_IBSS;
1155 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301156 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301157 }
1158}
1159
1160static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1161 tpSirWifiInterfaceInfo pInfo)
1162{
1163 v_U8_t *staMac = NULL;
1164 hdd_station_ctx_t *pHddStaCtx;
1165 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1166 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1167
1168 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1169
1170 vos_mem_copy(pInfo->macAddr,
1171 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1172
1173 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1174 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1175 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1176 {
1177 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1178 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1179 {
1180 pInfo->state = WIFI_DISCONNECTED;
1181 }
1182 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1183 {
1184 hddLog(VOS_TRACE_LEVEL_ERROR,
1185 "%s: Session ID %d, Connection is in progress", __func__,
1186 pAdapter->sessionId);
1187 pInfo->state = WIFI_ASSOCIATING;
1188 }
1189 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1190 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1191 {
1192 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1193 hddLog(VOS_TRACE_LEVEL_ERROR,
1194 "%s: client " MAC_ADDRESS_STR
1195 " is in the middle of WPS/EAPOL exchange.", __func__,
1196 MAC_ADDR_ARRAY(staMac));
1197 pInfo->state = WIFI_AUTHENTICATING;
1198 }
1199 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1200 {
1201 pInfo->state = WIFI_ASSOCIATED;
1202 vos_mem_copy(pInfo->bssid,
1203 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1204 vos_mem_copy(pInfo->ssid,
1205 pHddStaCtx->conn_info.SSID.SSID.ssId,
1206 pHddStaCtx->conn_info.SSID.SSID.length);
1207 //NULL Terminate the string.
1208 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1209 }
1210 }
1211 vos_mem_copy(pInfo->countryStr,
1212 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1213
1214 vos_mem_copy(pInfo->apCountryStr,
1215 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1216
1217 return TRUE;
1218}
1219
1220/*
1221 * hdd_link_layer_process_peer_stats () - This function is called after
1222 * receiving Link Layer Peer statistics from FW.This function converts
1223 * the firmware data to the NL data and sends the same to the kernel/upper
1224 * layers.
1225 */
1226static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1227 v_VOID_t *pData)
1228{
1229 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1230 tpSirWifiRateStat pWifiRateStat;
1231 tpSirWifiPeerStat pWifiPeerStat;
1232 tpSirWifiPeerInfo pWifiPeerInfo;
1233 struct nlattr *peerInfo;
1234 struct sk_buff *vendor_event;
1235 int status, i;
1236
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301237 ENTER();
1238
Sunil Duttc69bccb2014-05-26 21:30:20 +05301239 status = wlan_hdd_validate_context(pHddCtx);
1240 if (0 != status)
1241 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301242 return;
1243 }
1244
1245 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1246
1247 hddLog(VOS_TRACE_LEVEL_INFO,
1248 "LL_STATS_PEER_ALL : numPeers %u",
1249 pWifiPeerStat->numPeers);
1250 {
1251 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1252 {
1253 pWifiPeerInfo = (tpSirWifiPeerInfo)
1254 ((uint8 *)pWifiPeerStat->peerInfo +
1255 ( i * sizeof(tSirWifiPeerInfo)));
1256
Dasari Srinivas1be0c4e2014-10-19 13:03:41 +05301257 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) {
1258 pWifiPeerInfo->type = WIFI_PEER_AP;
1259 }
1260 if (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) {
1261 pWifiPeerInfo->type = WIFI_PEER_P2P_GO;
1262 }
1263
Sunil Duttc69bccb2014-05-26 21:30:20 +05301264 hddLog(VOS_TRACE_LEVEL_INFO,
1265 " %d) LL_STATS Channel Stats "
1266 " Peer Type %u "
1267 " peerMacAddress %pM "
1268 " capabilities 0x%x "
1269 " numRate %u ",
1270 i,
1271 pWifiPeerInfo->type,
1272 pWifiPeerInfo->peerMacAddress,
1273 pWifiPeerInfo->capabilities,
1274 pWifiPeerInfo->numRate);
1275 {
1276 int j;
1277 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1278 {
1279 pWifiRateStat = (tpSirWifiRateStat)
1280 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1281 ( j * sizeof(tSirWifiRateStat)));
1282
1283 hddLog(VOS_TRACE_LEVEL_INFO,
1284 " peer Rate Stats "
1285 " preamble %u "
1286 " nss %u "
1287 " bw %u "
1288 " rateMcsIdx %u "
1289 " reserved %u "
1290 " bitrate %u "
1291 " txMpdu %u "
1292 " rxMpdu %u "
1293 " mpduLost %u "
1294 " retries %u "
1295 " retriesShort %u "
1296 " retriesLong %u",
1297 pWifiRateStat->rate.preamble,
1298 pWifiRateStat->rate.nss,
1299 pWifiRateStat->rate.bw,
1300 pWifiRateStat->rate.rateMcsIdx,
1301 pWifiRateStat->rate.reserved,
1302 pWifiRateStat->rate.bitrate,
1303 pWifiRateStat->txMpdu,
1304 pWifiRateStat->rxMpdu,
1305 pWifiRateStat->mpduLost,
1306 pWifiRateStat->retries,
1307 pWifiRateStat->retriesShort,
1308 pWifiRateStat->retriesLong);
1309 }
1310 }
1311 }
1312 }
1313
1314 /*
1315 * Allocate a size of 4096 for the peer stats comprising
1316 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1317 * sizeof (tSirWifiRateStat).Each field is put with an
1318 * NL attribute.The size of 4096 is considered assuming
1319 * that number of rates shall not exceed beyond 50 with
1320 * the sizeof (tSirWifiRateStat) being 32.
1321 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301322 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1323 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301324 if (!vendor_event)
1325 {
1326 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301327 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301328 __func__);
1329 return;
1330 }
1331 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301332 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1333 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1334 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301335 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1336 pWifiPeerStat->numPeers))
1337 {
1338 hddLog(VOS_TRACE_LEVEL_ERROR,
1339 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1340 kfree_skb(vendor_event);
1341 return;
1342 }
1343
1344 peerInfo = nla_nest_start(vendor_event,
1345 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301346 if(!peerInfo)
1347 {
1348 hddLog(VOS_TRACE_LEVEL_ERROR,
1349 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1350 __func__);
1351 kfree_skb(vendor_event);
1352 return;
1353 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301354
1355 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1356 pWifiPeerStat->peerInfo);
1357
1358 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1359 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301360 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301361 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301362
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301363 if(!peers)
1364 {
1365 hddLog(VOS_TRACE_LEVEL_ERROR,
1366 "%s: peer stats put fail",
1367 __func__);
1368 kfree_skb(vendor_event);
1369 return;
1370 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301371 if (FALSE == put_wifi_peer_info(
1372 pWifiPeerInfo, vendor_event))
1373 {
1374 hddLog(VOS_TRACE_LEVEL_ERROR,
1375 "%s: put_wifi_peer_info put fail", __func__);
1376 kfree_skb(vendor_event);
1377 return;
1378 }
1379
1380 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1381 pWifiPeerStat->peerInfo +
1382 (i * sizeof(tSirWifiPeerInfo)) +
1383 (numRate * sizeof (tSirWifiRateStat)));
1384 nla_nest_end(vendor_event, peers);
1385 }
1386 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301387 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301388 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301389}
1390
1391/*
1392 * hdd_link_layer_process_iface_stats () - This function is called after
1393 * receiving Link Layer Interface statistics from FW.This function converts
1394 * the firmware data to the NL data and sends the same to the kernel/upper
1395 * layers.
1396 */
1397static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1398 v_VOID_t *pData)
1399{
1400 tpSirWifiIfaceStat pWifiIfaceStat;
1401 struct sk_buff *vendor_event;
1402 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1403 int status;
1404
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301405 ENTER();
1406
Sunil Duttc69bccb2014-05-26 21:30:20 +05301407 status = wlan_hdd_validate_context(pHddCtx);
1408 if (0 != status)
1409 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301410 return;
1411 }
1412 /*
1413 * Allocate a size of 4096 for the interface stats comprising
1414 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1415 * assuming that all these fit with in the limit.Please take
1416 * a call on the limit based on the data requirements on
1417 * interface statistics.
1418 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301419 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1420 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301421 if (!vendor_event)
1422 {
1423 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301424 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301425 return;
1426 }
1427
1428 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1429
Dino Mycle3b9536d2014-07-09 22:05:24 +05301430
1431 if (FALSE == hdd_get_interface_info( pAdapter,
1432 &pWifiIfaceStat->info))
1433 {
1434 hddLog(VOS_TRACE_LEVEL_ERROR,
1435 FL("hdd_get_interface_info get fail") );
1436 kfree_skb(vendor_event);
1437 return;
1438 }
1439
1440 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1441 vendor_event))
1442 {
1443 hddLog(VOS_TRACE_LEVEL_ERROR,
1444 FL("put_wifi_iface_stats fail") );
1445 kfree_skb(vendor_event);
1446 return;
1447 }
1448
Sunil Duttc69bccb2014-05-26 21:30:20 +05301449 hddLog(VOS_TRACE_LEVEL_INFO,
1450 "WMI_LINK_STATS_IFACE Data");
1451
1452 hddLog(VOS_TRACE_LEVEL_INFO,
1453 "LL_STATS_IFACE: "
1454 " Mode %u "
1455 " MAC %pM "
1456 " State %u "
1457 " Roaming %u "
1458 " capabilities 0x%x "
1459 " SSID %s "
1460 " BSSID %pM",
1461 pWifiIfaceStat->info.mode,
1462 pWifiIfaceStat->info.macAddr,
1463 pWifiIfaceStat->info.state,
1464 pWifiIfaceStat->info.roaming,
1465 pWifiIfaceStat->info.capabilities,
1466 pWifiIfaceStat->info.ssid,
1467 pWifiIfaceStat->info.bssid);
1468
1469 hddLog(VOS_TRACE_LEVEL_INFO,
1470 " AP country str: %c%c%c",
1471 pWifiIfaceStat->info.apCountryStr[0],
1472 pWifiIfaceStat->info.apCountryStr[1],
1473 pWifiIfaceStat->info.apCountryStr[2]);
1474
1475
1476 hddLog(VOS_TRACE_LEVEL_INFO,
1477 " Country Str Association: %c%c%c",
1478 pWifiIfaceStat->info.countryStr[0],
1479 pWifiIfaceStat->info.countryStr[1],
1480 pWifiIfaceStat->info.countryStr[2]);
1481
1482 hddLog(VOS_TRACE_LEVEL_INFO,
1483 " beaconRx %u "
1484 " mgmtRx %u "
1485 " mgmtActionRx %u "
1486 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301487 " rssiMgmt %d "
1488 " rssiData %d "
1489 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301490 pWifiIfaceStat->beaconRx,
1491 pWifiIfaceStat->mgmtRx,
1492 pWifiIfaceStat->mgmtActionRx,
1493 pWifiIfaceStat->mgmtActionTx,
1494 pWifiIfaceStat->rssiMgmt,
1495 pWifiIfaceStat->rssiData,
1496 pWifiIfaceStat->rssiAck );
1497
1498
1499 {
1500 int i;
1501 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1502 {
1503 hddLog(VOS_TRACE_LEVEL_INFO,
1504
1505 " %d) LL_STATS IFACE: "
1506 " ac: %u txMpdu: %u "
1507 " rxMpdu: %u txMcast: %u "
1508 " rxMcast: %u rxAmpdu: %u "
1509 " txAmpdu: %u mpduLost: %u "
1510 " retries: %u retriesShort: %u "
1511 " retriesLong: %u contentionTimeMin: %u "
1512 " contentionTimeMax: %u contentionTimeAvg: %u "
1513 " contentionNumSamples: %u",
1514 i,
1515 pWifiIfaceStat->AccessclassStats[i].ac,
1516 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1517 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1518 pWifiIfaceStat->AccessclassStats[i].txMcast,
1519 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1520 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1521 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1522 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1523 pWifiIfaceStat->AccessclassStats[i].retries,
1524 pWifiIfaceStat->
1525 AccessclassStats[i].retriesShort,
1526 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1527 pWifiIfaceStat->
1528 AccessclassStats[i].contentionTimeMin,
1529 pWifiIfaceStat->
1530 AccessclassStats[i].contentionTimeMax,
1531 pWifiIfaceStat->
1532 AccessclassStats[i].contentionTimeAvg,
1533 pWifiIfaceStat->
1534 AccessclassStats[i].contentionNumSamples);
1535
1536 }
1537 }
1538
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301539 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301540
1541 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301542}
1543
1544/*
1545 * hdd_link_layer_process_radio_stats () - This function is called after
1546 * receiving Link Layer Radio statistics from FW.This function converts
1547 * the firmware data to the NL data and sends the same to the kernel/upper
1548 * layers.
1549 */
1550static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1551 v_VOID_t *pData)
1552{
1553 int status, i;
1554 tpSirWifiRadioStat pWifiRadioStat;
1555 tpSirWifiChannelStats pWifiChannelStats;
1556 struct sk_buff *vendor_event;
1557 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1558 struct nlattr *chList;
1559
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301560 ENTER();
1561
Sunil Duttc69bccb2014-05-26 21:30:20 +05301562 status = wlan_hdd_validate_context(pHddCtx);
1563 if (0 != status)
1564 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301565 return;
1566 }
1567 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1568
1569 hddLog(VOS_TRACE_LEVEL_INFO,
1570 "LL_STATS_RADIO"
1571 " radio is %d onTime is %u "
1572 " txTime is %u rxTime is %u "
1573 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301574 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301575 " onTimePnoScan is %u onTimeHs20 is %u "
1576 " numChannels is %u",
1577 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1578 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1579 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301580 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301581 pWifiRadioStat->onTimeRoamScan,
1582 pWifiRadioStat->onTimePnoScan,
1583 pWifiRadioStat->onTimeHs20,
1584 pWifiRadioStat->numChannels);
1585 /*
1586 * Allocate a size of 4096 for the Radio stats comprising
1587 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1588 * (tSirWifiChannelStats).Each channel data is put with an
1589 * NL attribute.The size of 4096 is considered assuming that
1590 * number of channels shall not exceed beyond 60 with the
1591 * sizeof (tSirWifiChannelStats) being 24 bytes.
1592 */
1593
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301594 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1595 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301596 if (!vendor_event)
1597 {
1598 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301599 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301600 return;
1601 }
1602
1603 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301604 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1605 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1606 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301607 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1608 pWifiRadioStat->radio) ||
1609 nla_put_u32(vendor_event,
1610 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1611 pWifiRadioStat->onTime) ||
1612 nla_put_u32(vendor_event,
1613 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1614 pWifiRadioStat->txTime) ||
1615 nla_put_u32(vendor_event,
1616 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1617 pWifiRadioStat->rxTime) ||
1618 nla_put_u32(vendor_event,
1619 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1620 pWifiRadioStat->onTimeScan) ||
1621 nla_put_u32(vendor_event,
1622 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1623 pWifiRadioStat->onTimeNbd) ||
1624 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301625 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1626 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301627 nla_put_u32(vendor_event,
1628 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1629 pWifiRadioStat->onTimeRoamScan) ||
1630 nla_put_u32(vendor_event,
1631 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1632 pWifiRadioStat->onTimePnoScan) ||
1633 nla_put_u32(vendor_event,
1634 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1635 pWifiRadioStat->onTimeHs20) ||
1636 nla_put_u32(vendor_event,
1637 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1638 pWifiRadioStat->numChannels))
1639 {
1640 hddLog(VOS_TRACE_LEVEL_ERROR,
1641 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1642 kfree_skb(vendor_event);
1643 return ;
1644 }
1645
1646 chList = nla_nest_start(vendor_event,
1647 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301648 if(!chList)
1649 {
1650 hddLog(VOS_TRACE_LEVEL_ERROR,
1651 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1652 __func__);
1653 kfree_skb(vendor_event);
1654 return;
1655 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301656 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1657 {
1658 struct nlattr *chInfo;
1659
1660 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1661 pWifiRadioStat->channels +
1662 (i * sizeof(tSirWifiChannelStats)));
1663
1664 hddLog(VOS_TRACE_LEVEL_INFO,
1665 " %d) Channel Info"
1666 " width is %u "
1667 " CenterFreq %u "
1668 " CenterFreq0 %u "
1669 " CenterFreq1 %u "
1670 " onTime %u "
1671 " ccaBusyTime %u",
1672 i,
1673 pWifiChannelStats->channel.width,
1674 pWifiChannelStats->channel.centerFreq,
1675 pWifiChannelStats->channel.centerFreq0,
1676 pWifiChannelStats->channel.centerFreq1,
1677 pWifiChannelStats->onTime,
1678 pWifiChannelStats->ccaBusyTime);
1679
1680
1681 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301682 if(!chInfo)
1683 {
1684 hddLog(VOS_TRACE_LEVEL_ERROR,
1685 "%s: failed to put chInfo",
1686 __func__);
1687 kfree_skb(vendor_event);
1688 return;
1689 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301690
1691 if (nla_put_u32(vendor_event,
1692 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1693 pWifiChannelStats->channel.width) ||
1694 nla_put_u32(vendor_event,
1695 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1696 pWifiChannelStats->channel.centerFreq) ||
1697 nla_put_u32(vendor_event,
1698 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1699 pWifiChannelStats->channel.centerFreq0) ||
1700 nla_put_u32(vendor_event,
1701 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1702 pWifiChannelStats->channel.centerFreq1) ||
1703 nla_put_u32(vendor_event,
1704 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1705 pWifiChannelStats->onTime) ||
1706 nla_put_u32(vendor_event,
1707 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1708 pWifiChannelStats->ccaBusyTime))
1709 {
1710 hddLog(VOS_TRACE_LEVEL_ERROR,
1711 FL("cfg80211_vendor_event_alloc failed") );
1712 kfree_skb(vendor_event);
1713 return ;
1714 }
1715 nla_nest_end(vendor_event, chInfo);
1716 }
1717 nla_nest_end(vendor_event, chList);
1718
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301719 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301720
1721 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301722 return;
1723}
1724
1725/*
1726 * hdd_link_layer_stats_ind_callback () - This function is called after
1727 * receiving Link Layer indications from FW.This callback converts the firmware
1728 * data to the NL data and send the same to the kernel/upper layers.
1729 */
1730static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1731 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301732 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301733{
Dino Mycled3d50022014-07-07 12:58:25 +05301734 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1735 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301736 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301737 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301738 int status;
1739
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301740 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301741
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301742 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301743 if (0 != status)
1744 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301745 return;
1746 }
1747
Dino Mycled3d50022014-07-07 12:58:25 +05301748 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1749 if (NULL == pAdapter)
1750 {
1751 hddLog(VOS_TRACE_LEVEL_ERROR,
1752 FL(" MAC address %pM does not exist with host"),
1753 macAddr);
1754 return;
1755 }
1756
Sunil Duttc69bccb2014-05-26 21:30:20 +05301757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301758 "%s: Interface: %s LLStats indType: %d", __func__,
1759 pAdapter->dev->name, indType);
1760
Sunil Duttc69bccb2014-05-26 21:30:20 +05301761 switch (indType)
1762 {
1763 case SIR_HAL_LL_STATS_RESULTS_RSP:
1764 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301765 hddLog(VOS_TRACE_LEVEL_INFO,
1766 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1767 hddLog(VOS_TRACE_LEVEL_INFO,
1768 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1769 linkLayerStatsResults->paramId);
1770 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301771 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1772 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301773 hddLog(VOS_TRACE_LEVEL_INFO,
1774 "LL_STATS RESULTS RESPONSE respId = %u",
1775 linkLayerStatsResults->respId);
1776 hddLog(VOS_TRACE_LEVEL_INFO,
1777 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1778 linkLayerStatsResults->moreResultToFollow);
1779 hddLog(VOS_TRACE_LEVEL_INFO,
1780 "LL_STATS RESULTS RESPONSE result = %p",
1781 linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301782 spin_lock(&hdd_context_lock);
1783 context = &pHddCtx->ll_stats_context;
1784 /* validate response received from target */
1785 if ((context->request_id != linkLayerStatsResults->respId) ||
1786 !(context->request_bitmap & linkLayerStatsResults->paramId))
1787 {
1788 spin_unlock(&hdd_context_lock);
1789 hddLog(LOGE,
1790 FL("Error : Request id %d response id %d request bitmap 0x%x"
1791 "response bitmap 0x%x"),
1792 context->request_id, linkLayerStatsResults->respId,
1793 context->request_bitmap, linkLayerStatsResults->paramId);
1794 return;
1795 }
1796 spin_unlock(&hdd_context_lock);
1797
Sunil Duttc69bccb2014-05-26 21:30:20 +05301798 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1799 {
1800 hdd_link_layer_process_radio_stats(pAdapter,
1801 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301802 spin_lock(&hdd_context_lock);
1803 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1804 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301805 }
1806 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1807 {
1808 hdd_link_layer_process_iface_stats(pAdapter,
1809 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301810 spin_lock(&hdd_context_lock);
1811 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1812 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301813 }
1814 else if ( linkLayerStatsResults->paramId &
1815 WMI_LINK_STATS_ALL_PEER )
1816 {
1817 hdd_link_layer_process_peer_stats(pAdapter,
1818 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301819 spin_lock(&hdd_context_lock);
1820 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1821 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301822 } /* WMI_LINK_STATS_ALL_PEER */
1823 else
1824 {
1825 hddLog(VOS_TRACE_LEVEL_ERROR,
1826 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1827 }
1828
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301829 spin_lock(&hdd_context_lock);
1830 /* complete response event if all requests are completed */
1831 if (0 == context->request_bitmap)
1832 complete(&context->response_event);
1833 spin_unlock(&hdd_context_lock);
1834
Sunil Duttc69bccb2014-05-26 21:30:20 +05301835 break;
1836 }
1837 default:
1838 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1839 break;
1840 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301841
1842 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301843 return;
1844}
1845
1846const struct
1847nla_policy
1848qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1849{
1850 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1851 { .type = NLA_U32 },
1852 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1853 { .type = NLA_U32 },
1854};
1855
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301856static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1857 struct wireless_dev *wdev,
1858 const void *data,
1859 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301860{
1861 int status;
1862 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301863 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301864 struct net_device *dev = wdev->netdev;
1865 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1866 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1867
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301868 ENTER();
1869
Sunil Duttc69bccb2014-05-26 21:30:20 +05301870 status = wlan_hdd_validate_context(pHddCtx);
1871 if (0 != status)
1872 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301873 return -EINVAL;
1874 }
1875
1876 if (NULL == pAdapter)
1877 {
1878 hddLog(VOS_TRACE_LEVEL_ERROR,
1879 FL("HDD adapter is Null"));
1880 return -ENODEV;
1881 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301882 /* check the LLStats Capability */
1883 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1884 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1885 {
1886 hddLog(VOS_TRACE_LEVEL_ERROR,
1887 FL("Link Layer Statistics not supported by Firmware"));
1888 return -EINVAL;
1889 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301890
1891 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1892 (struct nlattr *)data,
1893 data_len, qca_wlan_vendor_ll_set_policy))
1894 {
1895 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1896 return -EINVAL;
1897 }
1898 if (!tb_vendor
1899 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1900 {
1901 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1902 return -EINVAL;
1903 }
1904 if (!tb_vendor[
1905 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1906 {
1907 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1908 return -EINVAL;
1909 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301910 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301911 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301912
Dino Mycledf0a5d92014-07-04 09:41:55 +05301913 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301914 nla_get_u32(
1915 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1916
Dino Mycledf0a5d92014-07-04 09:41:55 +05301917 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301918 nla_get_u32(
1919 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1920
Dino Mycled3d50022014-07-07 12:58:25 +05301921 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1922 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301923
1924
1925 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301926 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301927 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301928 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301929 hddLog(VOS_TRACE_LEVEL_INFO,
1930 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301931 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301932 hddLog(VOS_TRACE_LEVEL_INFO,
1933 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301934 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301935
1936 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1937 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301938 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301939 {
1940 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1941 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301942 return -EINVAL;
1943
1944 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301945
Sunil Duttc69bccb2014-05-26 21:30:20 +05301946 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301947 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301948 {
1949 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1950 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301951 return -EINVAL;
1952 }
1953
1954 pAdapter->isLinkLayerStatsSet = 1;
1955
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301956 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301957 return 0;
1958}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301959static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1960 struct wireless_dev *wdev,
1961 const void *data,
1962 int data_len)
1963{
1964 int ret = 0;
1965
1966 vos_ssr_protect(__func__);
1967 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1968 vos_ssr_unprotect(__func__);
1969
1970 return ret;
1971}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301972
1973const struct
1974nla_policy
1975qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1976{
1977 /* Unsigned 32bit value provided by the caller issuing the GET stats
1978 * command. When reporting
1979 * the stats results, the driver uses the same value to indicate
1980 * which GET request the results
1981 * correspond to.
1982 */
1983 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1984
1985 /* Unsigned 32bit value . bit mask to identify what statistics are
1986 requested for retrieval */
1987 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1988};
1989
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301990static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1991 struct wireless_dev *wdev,
1992 const void *data,
1993 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301994{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301995 unsigned long rc;
1996 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301997 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1998 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301999 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302000 struct net_device *dev = wdev->netdev;
2001 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302002 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302003 int status;
2004
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302005 ENTER();
2006
Sunil Duttc69bccb2014-05-26 21:30:20 +05302007 status = wlan_hdd_validate_context(pHddCtx);
2008 if (0 != status)
2009 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302010 return -EINVAL ;
2011 }
2012
2013 if (NULL == pAdapter)
2014 {
2015 hddLog(VOS_TRACE_LEVEL_FATAL,
2016 "%s: HDD adapter is Null", __func__);
2017 return -ENODEV;
2018 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302019
2020 if (pHddStaCtx == NULL)
2021 {
2022 hddLog(VOS_TRACE_LEVEL_FATAL,
2023 "%s: HddStaCtx is Null", __func__);
2024 return -ENODEV;
2025 }
2026
Dino Mycledf0a5d92014-07-04 09:41:55 +05302027 /* check the LLStats Capability */
2028 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2029 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2030 {
2031 hddLog(VOS_TRACE_LEVEL_ERROR,
2032 FL("Link Layer Statistics not supported by Firmware"));
2033 return -EINVAL;
2034 }
2035
Sunil Duttc69bccb2014-05-26 21:30:20 +05302036
2037 if (!pAdapter->isLinkLayerStatsSet)
2038 {
2039 hddLog(VOS_TRACE_LEVEL_FATAL,
2040 "%s: isLinkLayerStatsSet : %d",
2041 __func__, pAdapter->isLinkLayerStatsSet);
2042 return -EINVAL;
2043 }
2044
Mukul Sharma10313ba2015-07-29 19:14:39 +05302045 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2046 {
2047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2048 "%s: Roaming in progress, so unable to proceed this request", __func__);
2049 return -EBUSY;
2050 }
2051
Sunil Duttc69bccb2014-05-26 21:30:20 +05302052 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2053 (struct nlattr *)data,
2054 data_len, qca_wlan_vendor_ll_get_policy))
2055 {
2056 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2057 return -EINVAL;
2058 }
2059
2060 if (!tb_vendor
2061 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2062 {
2063 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2064 return -EINVAL;
2065 }
2066
2067 if (!tb_vendor
2068 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2069 {
2070 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2071 return -EINVAL;
2072 }
2073
Sunil Duttc69bccb2014-05-26 21:30:20 +05302074
Dino Mycledf0a5d92014-07-04 09:41:55 +05302075 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302076 nla_get_u32( tb_vendor[
2077 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302078 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302079 nla_get_u32( tb_vendor[
2080 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2081
Dino Mycled3d50022014-07-07 12:58:25 +05302082 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2083 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302084
2085 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302086 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302087 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302088 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302089 hddLog(VOS_TRACE_LEVEL_INFO,
2090 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302091 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302092
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302093 spin_lock(&hdd_context_lock);
2094 context = &pHddCtx->ll_stats_context;
2095 context->request_id = linkLayerStatsGetReq.reqId;
2096 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
2097 INIT_COMPLETION(context->response_event);
2098 spin_unlock(&hdd_context_lock);
2099
Sunil Duttc69bccb2014-05-26 21:30:20 +05302100 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302101 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302102 {
2103 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2104 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302105 return -EINVAL;
2106 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302107
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302108 rc = wait_for_completion_timeout(&context->response_event,
2109 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
2110 if (!rc)
2111 {
2112 hddLog(LOGE,
2113 FL("Target response timed out request id %d request bitmap 0x%x"),
2114 context->request_id, context->request_bitmap);
2115 return -ETIMEDOUT;
2116 }
2117
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302118 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302119 return 0;
2120}
2121
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302122static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2123 struct wireless_dev *wdev,
2124 const void *data,
2125 int data_len)
2126{
2127 int ret = 0;
2128
2129 vos_ssr_protect(__func__);
2130 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
2131 vos_ssr_unprotect(__func__);
2132
2133 return ret;
2134}
2135
Sunil Duttc69bccb2014-05-26 21:30:20 +05302136const struct
2137nla_policy
2138qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2139{
2140 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2141 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2142 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2143 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2144};
2145
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302146static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2147 struct wireless_dev *wdev,
2148 const void *data,
2149 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302150{
2151 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2152 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302153 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302154 struct net_device *dev = wdev->netdev;
2155 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2156 u32 statsClearReqMask;
2157 u8 stopReq;
2158 int status;
2159
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302160 ENTER();
2161
Sunil Duttc69bccb2014-05-26 21:30:20 +05302162 status = wlan_hdd_validate_context(pHddCtx);
2163 if (0 != status)
2164 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302165 return -EINVAL;
2166 }
2167
2168 if (NULL == pAdapter)
2169 {
2170 hddLog(VOS_TRACE_LEVEL_FATAL,
2171 "%s: HDD adapter is Null", __func__);
2172 return -ENODEV;
2173 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302174 /* check the LLStats Capability */
2175 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2176 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2177 {
2178 hddLog(VOS_TRACE_LEVEL_ERROR,
2179 FL("Enable LLStats Capability"));
2180 return -EINVAL;
2181 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302182
2183 if (!pAdapter->isLinkLayerStatsSet)
2184 {
2185 hddLog(VOS_TRACE_LEVEL_FATAL,
2186 "%s: isLinkLayerStatsSet : %d",
2187 __func__, pAdapter->isLinkLayerStatsSet);
2188 return -EINVAL;
2189 }
2190
2191 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2192 (struct nlattr *)data,
2193 data_len, qca_wlan_vendor_ll_clr_policy))
2194 {
2195 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2196 return -EINVAL;
2197 }
2198
2199 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2200
2201 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2202 {
2203 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2204 return -EINVAL;
2205
2206 }
2207
Sunil Duttc69bccb2014-05-26 21:30:20 +05302208
Dino Mycledf0a5d92014-07-04 09:41:55 +05302209 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302210 nla_get_u32(
2211 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2212
Dino Mycledf0a5d92014-07-04 09:41:55 +05302213 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302214 nla_get_u8(
2215 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2216
2217 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302218 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302219
Dino Mycled3d50022014-07-07 12:58:25 +05302220 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2221 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302222
2223 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302224 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302225 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302226 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302227 hddLog(VOS_TRACE_LEVEL_INFO,
2228 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302229 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302230 hddLog(VOS_TRACE_LEVEL_INFO,
2231 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302232 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302233
2234 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302235 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302236 {
2237 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302238 hdd_station_ctx_t *pHddStaCtx;
2239
2240 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2241 if (VOS_STATUS_SUCCESS !=
2242 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2243 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2244 {
2245 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2246 "WLANTL_ClearInterfaceStats Failed", __func__);
2247 return -EINVAL;
2248 }
2249 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2250 (statsClearReqMask & WIFI_STATS_IFACE)) {
2251 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2252 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2253 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2254 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2255 }
2256
Sunil Duttc69bccb2014-05-26 21:30:20 +05302257 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2258 2 * sizeof(u32) +
2259 NLMSG_HDRLEN);
2260
2261 if (temp_skbuff != NULL)
2262 {
2263
2264 if (nla_put_u32(temp_skbuff,
2265 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2266 statsClearReqMask) ||
2267 nla_put_u32(temp_skbuff,
2268 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2269 stopReq))
2270 {
2271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2272 kfree_skb(temp_skbuff);
2273 return -EINVAL;
2274 }
2275 /* If the ask is to stop the stats collection as part of clear
2276 * (stopReq = 1) , ensure that no further requests of get
2277 * go to the firmware by having isLinkLayerStatsSet set to 0.
2278 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302279 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302280 * case the firmware is just asked to clear the statistics.
2281 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302282 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302283 pAdapter->isLinkLayerStatsSet = 0;
2284 return cfg80211_vendor_cmd_reply(temp_skbuff);
2285 }
2286 return -ENOMEM;
2287 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302288
2289 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302290 return -EINVAL;
2291}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302292static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2293 struct wireless_dev *wdev,
2294 const void *data,
2295 int data_len)
2296{
2297 int ret = 0;
2298
2299 vos_ssr_protect(__func__);
2300 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2301 vos_ssr_unprotect(__func__);
2302
2303 return ret;
2304
2305
2306}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302307#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2308
Dino Mycle6fb96c12014-06-10 11:52:40 +05302309#ifdef WLAN_FEATURE_EXTSCAN
2310static const struct nla_policy
2311wlan_hdd_extscan_config_policy
2312 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2313{
2314 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2315 { .type = NLA_U32 },
2316 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2317 { .type = NLA_U32 },
2318 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2319 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2320 { .type = NLA_U32 },
2321 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2322 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2323
2324 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2325 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2326 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2327 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2328 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302329 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2330 { .type = NLA_U32 },
2331 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2332 { .type = NLA_U32 },
2333 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2334 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302335 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2336 { .type = NLA_U32 },
2337 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2338 { .type = NLA_U32 },
2339 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2340 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302341 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2342 { .type = NLA_U8 },
2343 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302344 { .type = NLA_U8 },
2345 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2346 { .type = NLA_U8 },
2347 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2348 { .type = NLA_U8 },
2349
2350 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2351 { .type = NLA_U32 },
2352 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2353 { .type = NLA_UNSPEC },
2354 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2355 { .type = NLA_S32 },
2356 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2357 { .type = NLA_S32 },
2358 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2359 { .type = NLA_U32 },
2360 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2361 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302362 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2363 { .type = NLA_U32 },
2364 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2365 { .type = NLA_BINARY,
2366 .len = IEEE80211_MAX_SSID_LEN + 1 },
2367 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302368 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302369 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2370 { .type = NLA_U32 },
2371 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2372 { .type = NLA_U8 },
2373 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2374 { .type = NLA_S32 },
2375 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2376 { .type = NLA_S32 },
2377 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2378 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302379};
2380
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302381/**
2382 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2383 * @ctx: hdd global context
2384 * @data: capabilities data
2385 *
2386 * Return: none
2387 */
2388static void
2389wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302390{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302391 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302392 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302393 tSirEXTScanCapabilitiesEvent *data =
2394 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302395
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302396 ENTER();
2397
2398 if (wlan_hdd_validate_context(pHddCtx))
2399 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302400 return;
2401 }
2402
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302403 if (!pMsg)
2404 {
2405 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2406 return;
2407 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302408
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302409 vos_spin_lock_acquire(&hdd_context_lock);
2410
2411 context = &pHddCtx->ext_scan_context;
2412 /* validate response received from target*/
2413 if (context->request_id != data->requestId)
2414 {
2415 vos_spin_lock_release(&hdd_context_lock);
2416 hddLog(LOGE,
2417 FL("Target response id did not match: request_id %d resposne_id %d"),
2418 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302419 return;
2420 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302421 else
2422 {
2423 context->capability_response = *data;
2424 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302425 }
2426
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302427 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302428
Dino Mycle6fb96c12014-06-10 11:52:40 +05302429 return;
2430}
2431
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302432/*
2433 * define short names for the global vendor params
2434 * used by wlan_hdd_send_ext_scan_capability()
2435 */
2436#define PARAM_REQUEST_ID \
2437 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2438#define PARAM_STATUS \
2439 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2440#define MAX_SCAN_CACHE_SIZE \
2441 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2442#define MAX_SCAN_BUCKETS \
2443 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2444#define MAX_AP_CACHE_PER_SCAN \
2445 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2446#define MAX_RSSI_SAMPLE_SIZE \
2447 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2448#define MAX_SCAN_RPT_THRHOLD \
2449 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2450#define MAX_HOTLIST_BSSIDS \
2451 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2452#define MAX_BSSID_HISTORY_ENTRIES \
2453 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2454#define MAX_HOTLIST_SSIDS \
2455 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302456#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2457 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302458
2459static int wlan_hdd_send_ext_scan_capability(void *ctx)
2460{
2461 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2462 struct sk_buff *skb = NULL;
2463 int ret;
2464 tSirEXTScanCapabilitiesEvent *data;
2465 tANI_U32 nl_buf_len;
2466
2467 ret = wlan_hdd_validate_context(pHddCtx);
2468 if (0 != ret)
2469 {
2470 return ret;
2471 }
2472
2473 data = &(pHddCtx->ext_scan_context.capability_response);
2474
2475 nl_buf_len = NLMSG_HDRLEN;
2476 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2477 (sizeof(data->status) + NLA_HDRLEN) +
2478 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2479 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2480 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2481 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2482 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2483 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2484 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2485 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2486
2487 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2488
2489 if (!skb)
2490 {
2491 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2492 return -ENOMEM;
2493 }
2494
2495 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2496 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2497 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2498 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2499 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2500 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2501 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2502 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2503
2504 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2505 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2506 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2507 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2508 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2509 data->maxApPerScan) ||
2510 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2511 data->maxRssiSampleSize) ||
2512 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2513 data->maxScanReportingThreshold) ||
2514 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2515 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2516 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302517 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2518 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302519 {
2520 hddLog(LOGE, FL("nla put fail"));
2521 goto nla_put_failure;
2522 }
2523
2524 cfg80211_vendor_cmd_reply(skb);
2525 return 0;
2526
2527nla_put_failure:
2528 kfree_skb(skb);
2529 return -EINVAL;;
2530}
2531
2532/*
2533 * done with short names for the global vendor params
2534 * used by wlan_hdd_send_ext_scan_capability()
2535 */
2536#undef PARAM_REQUEST_ID
2537#undef PARAM_STATUS
2538#undef MAX_SCAN_CACHE_SIZE
2539#undef MAX_SCAN_BUCKETS
2540#undef MAX_AP_CACHE_PER_SCAN
2541#undef MAX_RSSI_SAMPLE_SIZE
2542#undef MAX_SCAN_RPT_THRHOLD
2543#undef MAX_HOTLIST_BSSIDS
2544#undef MAX_SIGNIFICANT_WIFI_CHANGE_APS
2545#undef MAX_BSSID_HISTORY_ENTRIES
2546#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302547
2548static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2549{
2550 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2551 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302552 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302553 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302554
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302555 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302556
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302557 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302558 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302559
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302560 if (!pMsg)
2561 {
2562 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302563 return;
2564 }
2565
Dino Mycle6fb96c12014-06-10 11:52:40 +05302566 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2567 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2568
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302569 context = &pHddCtx->ext_scan_context;
2570 spin_lock(&hdd_context_lock);
2571 if (context->request_id == pData->requestId) {
2572 context->response_status = pData->status ? -EINVAL : 0;
2573 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302574 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302575 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302576
2577 /*
2578 * Store the Request ID for comparing with the requestID obtained
2579 * in other requests.HDD shall return a failure is the extscan_stop
2580 * request is issued with a different requestId as that of the
2581 * extscan_start request. Also, This requestId shall be used while
2582 * indicating the full scan results to the upper layers.
2583 * The requestId is stored with the assumption that the firmware
2584 * shall return the ext scan start request's requestId in ext scan
2585 * start response.
2586 */
2587 if (pData->status == 0)
2588 pMac->sme.extScanStartReqId = pData->requestId;
2589
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302590 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302591 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302592}
2593
2594
2595static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2596{
2597 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2598 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302599 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302600
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302601 ENTER();
2602
2603 if (wlan_hdd_validate_context(pHddCtx)){
2604 return;
2605 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302606
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302607 if (!pMsg)
2608 {
2609 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302610 return;
2611 }
2612
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302613 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2614 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302615
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302616 context = &pHddCtx->ext_scan_context;
2617 spin_lock(&hdd_context_lock);
2618 if (context->request_id == pData->requestId) {
2619 context->response_status = pData->status ? -EINVAL : 0;
2620 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302621 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302622 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302623
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302624 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302625 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302626}
2627
Dino Mycle6fb96c12014-06-10 11:52:40 +05302628static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2629 void *pMsg)
2630{
2631 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2632 struct sk_buff *skb = NULL;
2633 tpSirEXTScanSetBssidHotListRspParams pData =
2634 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2635
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302636 ENTER();
2637
2638 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302639 return;
2640 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302641 if (!pMsg)
2642 {
2643 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2644 return;
2645 }
2646
Dino Mycle6fb96c12014-06-10 11:52:40 +05302647 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302648#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2649 NULL,
2650#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302651 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2652 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2653 GFP_KERNEL);
2654
2655 if (!skb) {
2656 hddLog(VOS_TRACE_LEVEL_ERROR,
2657 FL("cfg80211_vendor_event_alloc failed"));
2658 return;
2659 }
2660 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2661 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2662 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2663
2664 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2665 pData->requestId) ||
2666 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2668 goto nla_put_failure;
2669 }
2670
2671 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302672 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302673 return;
2674
2675nla_put_failure:
2676 kfree_skb(skb);
2677 return;
2678}
2679
2680static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2681 void *pMsg)
2682{
2683 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2684 struct sk_buff *skb = NULL;
2685 tpSirEXTScanResetBssidHotlistRspParams pData =
2686 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2687
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302688 ENTER();
2689
2690 if (wlan_hdd_validate_context(pHddCtx)) {
2691 return;
2692 }
2693 if (!pMsg)
2694 {
2695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302696 return;
2697 }
2698
2699 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302700#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2701 NULL,
2702#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302703 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2704 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2705 GFP_KERNEL);
2706
2707 if (!skb) {
2708 hddLog(VOS_TRACE_LEVEL_ERROR,
2709 FL("cfg80211_vendor_event_alloc failed"));
2710 return;
2711 }
2712 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2713 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2714
2715 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2716 pData->requestId) ||
2717 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2718 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2719 goto nla_put_failure;
2720 }
2721
2722 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302723 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302724 return;
2725
2726nla_put_failure:
2727 kfree_skb(skb);
2728 return;
2729}
2730
2731
2732static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2733 void *pMsg)
2734{
2735 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2736 struct sk_buff *skb = NULL;
2737 tpSirEXTScanSetSignificantChangeRspParams pData =
2738 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2739
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302740 ENTER();
2741
2742 if (wlan_hdd_validate_context(pHddCtx)) {
2743 return;
2744 }
2745 if (!pMsg)
2746 {
2747 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302748 return;
2749 }
2750
2751 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302752#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2753 NULL,
2754#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302755 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2756 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2757 GFP_KERNEL);
2758
2759 if (!skb) {
2760 hddLog(VOS_TRACE_LEVEL_ERROR,
2761 FL("cfg80211_vendor_event_alloc failed"));
2762 return;
2763 }
2764 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2765 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2766 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2767
2768 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2769 pData->requestId) ||
2770 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2771 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2772 goto nla_put_failure;
2773 }
2774
2775 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302776 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302777 return;
2778
2779nla_put_failure:
2780 kfree_skb(skb);
2781 return;
2782}
2783
2784
2785static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2786 void *pMsg)
2787{
2788 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2789 struct sk_buff *skb = NULL;
2790 tpSirEXTScanResetSignificantChangeRspParams pData =
2791 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2792
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302793 ENTER();
2794
2795 if (wlan_hdd_validate_context(pHddCtx)) {
2796 return;
2797 }
2798 if (!pMsg)
2799 {
2800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302801 return;
2802 }
2803
2804 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302805#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2806 NULL,
2807#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302808 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2809 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2810 GFP_KERNEL);
2811
2812 if (!skb) {
2813 hddLog(VOS_TRACE_LEVEL_ERROR,
2814 FL("cfg80211_vendor_event_alloc failed"));
2815 return;
2816 }
2817 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2818 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2819 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2820
2821 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2822 pData->requestId) ||
2823 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2824 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2825 goto nla_put_failure;
2826 }
2827
2828 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302829 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302830 return;
2831
2832nla_put_failure:
2833 kfree_skb(skb);
2834 return;
2835}
2836
2837static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2838 void *pMsg)
2839{
2840 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2841 struct sk_buff *skb = NULL;
2842 tANI_U32 i = 0, j, resultsPerEvent;
2843 tANI_S32 totalResults;
2844 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2845 tpSirWifiScanResult pSirWifiScanResult;
2846
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302847 ENTER();
2848
2849 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302850 return;
2851 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302852 if (!pMsg)
2853 {
2854 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2855 return;
2856 }
2857
Dino Mycle6fb96c12014-06-10 11:52:40 +05302858 totalResults = pData->numOfAps;
2859 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2860 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2861 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2862
2863 do{
2864 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2865 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2866 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2867
2868 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302869#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2870 NULL,
2871#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302872 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2873 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2874 GFP_KERNEL);
2875
2876 if (!skb) {
2877 hddLog(VOS_TRACE_LEVEL_ERROR,
2878 FL("cfg80211_vendor_event_alloc failed"));
2879 return;
2880 }
2881
2882 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2883
2884 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2885 pData->requestId) ||
2886 nla_put_u32(skb,
2887 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2888 resultsPerEvent)) {
2889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2890 goto fail;
2891 }
2892 if (nla_put_u8(skb,
2893 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2894 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2895 {
2896 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2897 goto fail;
2898 }
2899
2900 if (resultsPerEvent) {
2901 struct nlattr *aps;
2902
2903 aps = nla_nest_start(skb,
2904 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2905 if (!aps)
2906 {
2907 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2908 goto fail;
2909 }
2910
2911 for (j = 0; j < resultsPerEvent; j++, i++) {
2912 struct nlattr *ap;
2913 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2914 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2915
2916 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2917 "Ssid (%s)"
2918 "Bssid: %pM "
2919 "Channel (%u)"
2920 "Rssi (%d)"
2921 "RTT (%u)"
2922 "RTT_SD (%u)",
2923 i,
2924 pSirWifiScanResult->ts,
2925 pSirWifiScanResult->ssid,
2926 pSirWifiScanResult->bssid,
2927 pSirWifiScanResult->channel,
2928 pSirWifiScanResult->rssi,
2929 pSirWifiScanResult->rtt,
2930 pSirWifiScanResult->rtt_sd);
2931
2932 ap = nla_nest_start(skb, j + 1);
2933 if (!ap)
2934 {
2935 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2936 goto fail;
2937 }
2938
2939 if (nla_put_u64(skb,
2940 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2941 pSirWifiScanResult->ts) )
2942 {
2943 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2944 goto fail;
2945 }
2946 if (nla_put(skb,
2947 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2948 sizeof(pSirWifiScanResult->ssid),
2949 pSirWifiScanResult->ssid) )
2950 {
2951 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2952 goto fail;
2953 }
2954 if (nla_put(skb,
2955 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2956 sizeof(pSirWifiScanResult->bssid),
2957 pSirWifiScanResult->bssid) )
2958 {
2959 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2960 goto fail;
2961 }
2962 if (nla_put_u32(skb,
2963 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2964 pSirWifiScanResult->channel) )
2965 {
2966 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2967 goto fail;
2968 }
Dasari Srinivas90747d72014-10-08 12:16:15 +05302969 if (nla_put_s32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302970 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2971 pSirWifiScanResult->rssi) )
2972 {
2973 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2974 goto fail;
2975 }
2976 if (nla_put_u32(skb,
2977 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2978 pSirWifiScanResult->rtt) )
2979 {
2980 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2981 goto fail;
2982 }
2983 if (nla_put_u32(skb,
2984 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2985 pSirWifiScanResult->rtt_sd))
2986 {
2987 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2988 goto fail;
2989 }
2990
2991 nla_nest_end(skb, ap);
2992 }
2993 nla_nest_end(skb, aps);
2994
2995 }
2996 cfg80211_vendor_event(skb, GFP_KERNEL);
2997 } while (totalResults > 0);
2998
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302999 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303000 return;
3001fail:
3002 kfree_skb(skb);
3003 return;
3004}
3005
3006static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3007 void *pMsg)
3008{
3009 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
3010 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3011 struct sk_buff *skb = NULL;
3012 tANI_U32 i;
3013
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303014 ENTER();
3015
3016 if (wlan_hdd_validate_context(pHddCtx)) {
3017 return;
3018 }
3019 if (!pMsg)
3020 {
3021 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303022 return;
3023 }
3024
3025 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303026#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3027 NULL,
3028#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303029 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3030 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
3031 GFP_KERNEL);
3032
3033 if (!skb) {
3034 hddLog(VOS_TRACE_LEVEL_ERROR,
3035 FL("cfg80211_vendor_event_alloc failed"));
3036 return;
3037 }
3038 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3039 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3040 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
3041 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3042
3043 for (i = 0; i < pData->numOfAps; i++) {
3044 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3045 "Ssid (%s) "
3046 "Bssid (" MAC_ADDRESS_STR ") "
3047 "Channel (%u) "
3048 "Rssi (%d) "
3049 "RTT (%u) "
3050 "RTT_SD (%u) ",
3051 i,
3052 pData->ap[i].ts,
3053 pData->ap[i].ssid,
3054 MAC_ADDR_ARRAY(pData->ap[i].bssid),
3055 pData->ap[i].channel,
3056 pData->ap[i].rssi,
3057 pData->ap[i].rtt,
3058 pData->ap[i].rtt_sd);
3059 }
3060
3061 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3062 pData->requestId) ||
3063 nla_put_u32(skb,
3064 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3065 pData->numOfAps)) {
3066 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3067 goto fail;
3068 }
3069 if (pData->numOfAps) {
3070 struct nlattr *aps;
3071
3072 aps = nla_nest_start(skb,
3073 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3074 if (!aps)
3075 goto fail;
3076
3077 for (i = 0; i < pData->numOfAps; i++) {
3078 struct nlattr *ap;
3079
3080 ap = nla_nest_start(skb, i + 1);
3081 if (!ap)
3082 goto fail;
3083
3084 if (nla_put_u64(skb,
3085 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3086 pData->ap[i].ts) ||
3087 nla_put(skb,
3088 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3089 sizeof(pData->ap[i].ssid),
3090 pData->ap[i].ssid) ||
3091 nla_put(skb,
3092 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3093 sizeof(pData->ap[i].bssid),
3094 pData->ap[i].bssid) ||
3095 nla_put_u32(skb,
3096 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3097 pData->ap[i].channel) ||
3098 nla_put_s32(skb,
3099 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3100 pData->ap[i].rssi) ||
3101 nla_put_u32(skb,
3102 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3103 pData->ap[i].rtt) ||
3104 nla_put_u32(skb,
3105 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3106 pData->ap[i].rtt_sd))
3107 goto fail;
3108
3109 nla_nest_end(skb, ap);
3110 }
3111 nla_nest_end(skb, aps);
3112
3113 if (nla_put_u8(skb,
3114 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3115 pData->moreData))
3116 goto fail;
3117 }
3118
3119 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303120 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303121 return;
3122
3123fail:
3124 kfree_skb(skb);
3125 return;
3126
3127}
3128static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
3129 void *pMsg)
3130{
3131 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3132 struct sk_buff *skb = NULL;
3133 tANI_U32 i, j;
3134 tpSirWifiSignificantChangeEvent pData =
3135 (tpSirWifiSignificantChangeEvent) pMsg;
3136
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303137 ENTER();
3138
3139 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303140 return;
3141 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303142 if (!pMsg)
3143 {
3144 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3145 return;
3146 }
3147
Dino Mycle6fb96c12014-06-10 11:52:40 +05303148 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303149#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3150 NULL,
3151#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303152 EXTSCAN_EVENT_BUF_SIZE,
3153 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
3154 GFP_KERNEL);
3155
3156 if (!skb) {
3157 hddLog(VOS_TRACE_LEVEL_ERROR,
3158 FL("cfg80211_vendor_event_alloc failed"));
3159 return;
3160 }
3161 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3162 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3163 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
3164 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
3165 pData->numSigRssiBss);
3166 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
3167
3168 for (i = 0; i < pData->numSigRssiBss; i++) {
3169 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
3170 " num RSSI %u ",
3171 i, pData->sigRssiResult[i].bssid,
3172 pData->sigRssiResult[i].channel,
3173 pData->sigRssiResult[i].numRssi);
3174
3175 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
3176
3177 hddLog(VOS_TRACE_LEVEL_INFO,
3178 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05303179 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303180
3181 }
3182 }
3183
3184
3185 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3186 pData->requestId) ||
3187 nla_put_u32(skb,
3188 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3189 pData->numSigRssiBss)) {
3190 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3191 goto fail;
3192 }
3193
3194 if (pData->numSigRssiBss) {
3195 struct nlattr *aps;
3196 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3197 if (!aps)
3198 goto fail;
3199 for (i = 0; i < pData->numSigRssiBss; i++) {
3200 struct nlattr *ap;
3201
3202 ap = nla_nest_start(skb, i);
3203 if (!ap)
3204 goto fail;
3205 if (nla_put(skb,
3206 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
3207 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
3208 nla_put_u32(skb,
3209 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
3210 pData->sigRssiResult[i].channel) ||
3211 nla_put_u32(skb,
3212 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
3213 pData->sigRssiResult[i].numRssi) ||
3214 nla_put(skb,
3215 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
3216 sizeof(s32) * pData->sigRssiResult[i].numRssi,
3217 pData->sigRssiResult[i].rssi))
3218 goto fail;
3219 nla_nest_end(skb, ap);
3220 }
3221 nla_nest_end(skb, aps);
3222 if (nla_put_u8(skb,
3223 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3224 pData->moreData))
3225 goto fail;
3226 }
3227 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303228 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303229 return;
3230fail:
3231 kfree_skb(skb);
3232 return;
3233}
3234
3235static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3236 void *pMsg)
3237{
3238 struct sk_buff *skb;
3239 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3240 tpSirWifiFullScanResultEvent pData =
3241 (tpSirWifiFullScanResultEvent) (pMsg);
3242
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303243 ENTER();
3244
3245 if (wlan_hdd_validate_context(pHddCtx)) {
3246 return;
3247 }
3248 if (!pMsg)
3249 {
3250 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303251 return;
3252 }
3253
3254 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303255#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3256 NULL,
3257#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303258 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3259 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3260 GFP_KERNEL);
3261
3262 if (!skb) {
3263 hddLog(VOS_TRACE_LEVEL_ERROR,
3264 FL("cfg80211_vendor_event_alloc failed"));
3265 return;
3266 }
3267
3268 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3269 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3270 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3271 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3272 "Ssid (%s)"
3273 "Bssid (" MAC_ADDRESS_STR ")"
3274 "Channel (%u)"
3275 "Rssi (%d)"
3276 "RTT (%u)"
3277 "RTT_SD (%u)"),
3278 pData->ap.ts,
3279 pData->ap.ssid,
3280 MAC_ADDR_ARRAY(pData->ap.bssid),
3281 pData->ap.channel,
3282 pData->ap.rssi,
3283 pData->ap.rtt,
3284 pData->ap.rtt_sd);
3285 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3286 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3287 pData->requestId) ||
3288 nla_put_u64(skb,
3289 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3290 pData->ap.ts) ||
3291 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3292 sizeof(pData->ap.ssid),
3293 pData->ap.ssid) ||
3294 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3295 WNI_CFG_BSSID_LEN,
3296 pData->ap.bssid) ||
3297 nla_put_u32(skb,
3298 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3299 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303300 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303301 pData->ap.rssi) ||
3302 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3303 pData->ap.rtt) ||
3304 nla_put_u32(skb,
3305 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3306 pData->ap.rtt_sd) ||
3307 nla_put_u16(skb,
3308 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3309 pData->ap.beaconPeriod) ||
3310 nla_put_u16(skb,
3311 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3312 pData->ap.capability) ||
3313 nla_put_u32(skb,
3314 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3315 pData->ieLength))
3316 {
3317 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3318 goto nla_put_failure;
3319 }
3320 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3321 pData->ieLength,
3322 pData->ie))
3323 {
3324 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3325 goto nla_put_failure;
3326 }
3327
3328 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303329 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303330 return;
3331
3332nla_put_failure:
3333 kfree_skb(skb);
3334 return;
3335}
3336
3337static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3338 void *pMsg)
3339{
3340 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3341 struct sk_buff *skb = NULL;
3342 tpSirEXTScanResultsAvailableIndParams pData =
3343 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3344
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303345 ENTER();
3346
3347 if (wlan_hdd_validate_context(pHddCtx)){
3348 return;
3349 }
3350 if (!pMsg)
3351 {
3352 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303353 return;
3354 }
3355
3356 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303357#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3358 NULL,
3359#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303360 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3361 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3362 GFP_KERNEL);
3363
3364 if (!skb) {
3365 hddLog(VOS_TRACE_LEVEL_ERROR,
3366 FL("cfg80211_vendor_event_alloc failed"));
3367 return;
3368 }
3369
3370 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3371 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3372 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3373 pData->numResultsAvailable);
3374 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3375 pData->requestId) ||
3376 nla_put_u32(skb,
3377 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3378 pData->numResultsAvailable)) {
3379 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3380 goto nla_put_failure;
3381 }
3382
3383 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303384 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303385 return;
3386
3387nla_put_failure:
3388 kfree_skb(skb);
3389 return;
3390}
3391
3392static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3393{
3394 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3395 struct sk_buff *skb = NULL;
3396 tpSirEXTScanProgressIndParams pData =
3397 (tpSirEXTScanProgressIndParams) pMsg;
3398
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303399 ENTER();
3400
3401 if (wlan_hdd_validate_context(pHddCtx)){
3402 return;
3403 }
3404 if (!pMsg)
3405 {
3406 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303407 return;
3408 }
3409
3410 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303411#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3412 NULL,
3413#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303414 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3415 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3416 GFP_KERNEL);
3417
3418 if (!skb) {
3419 hddLog(VOS_TRACE_LEVEL_ERROR,
3420 FL("cfg80211_vendor_event_alloc failed"));
3421 return;
3422 }
3423 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3424 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3425 pData->extScanEventType);
3426 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3427 pData->status);
3428
3429 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3430 pData->extScanEventType) ||
3431 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303432 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3433 pData->requestId) ||
3434 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303435 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3436 pData->status)) {
3437 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3438 goto nla_put_failure;
3439 }
3440
3441 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303442 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303443 return;
3444
3445nla_put_failure:
3446 kfree_skb(skb);
3447 return;
3448}
3449
3450void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3451 void *pMsg)
3452{
3453 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3454
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303455 ENTER();
3456
Dino Mycle6fb96c12014-06-10 11:52:40 +05303457 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303458 return;
3459 }
3460
3461 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3462
3463
3464 switch(evType) {
3465 case SIR_HAL_EXTSCAN_START_RSP:
3466 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3467 break;
3468
3469 case SIR_HAL_EXTSCAN_STOP_RSP:
3470 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3471 break;
3472 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3473 /* There is no need to send this response to upper layer
3474 Just log the message */
3475 hddLog(VOS_TRACE_LEVEL_INFO,
3476 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3477 break;
3478 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3479 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3480 break;
3481
3482 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3483 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3484 break;
3485
3486 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
3487 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
3488 break;
3489
3490 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
3491 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
3492 break;
3493 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303494 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303495 break;
3496 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3497 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3498 break;
3499 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3500 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3501 break;
3502 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3503 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3504 break;
3505 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3506 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3507 break;
3508 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
3509 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
3510 break;
3511 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3512 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3513 break;
3514 default:
3515 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3516 break;
3517 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303518 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303519}
3520
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303521static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3522 struct wireless_dev *wdev,
3523 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303524{
Dino Myclee8843b32014-07-04 14:21:45 +05303525 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303526 struct net_device *dev = wdev->netdev;
3527 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3528 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3529 struct nlattr
3530 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3531 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303532 struct hdd_ext_scan_context *context;
3533 unsigned long rc;
3534 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303535
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303536 ENTER();
3537
Dino Mycle6fb96c12014-06-10 11:52:40 +05303538 status = wlan_hdd_validate_context(pHddCtx);
3539 if (0 != status)
3540 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303541 return -EINVAL;
3542 }
Dino Myclee8843b32014-07-04 14:21:45 +05303543 /* check the EXTScan Capability */
3544 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3545 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3546 {
3547 hddLog(VOS_TRACE_LEVEL_ERROR,
3548 FL("EXTScan not enabled/supported by Firmware"));
3549 return -EINVAL;
3550 }
3551
Dino Mycle6fb96c12014-06-10 11:52:40 +05303552 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3553 data, dataLen,
3554 wlan_hdd_extscan_config_policy)) {
3555 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3556 return -EINVAL;
3557 }
3558
3559 /* Parse and fetch request Id */
3560 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3561 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3562 return -EINVAL;
3563 }
3564
Dino Myclee8843b32014-07-04 14:21:45 +05303565 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303566 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303567 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303568
Dino Myclee8843b32014-07-04 14:21:45 +05303569 reqMsg.sessionId = pAdapter->sessionId;
3570 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303571
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303572 vos_spin_lock_acquire(&hdd_context_lock);
3573 context = &pHddCtx->ext_scan_context;
3574 context->request_id = reqMsg.requestId;
3575 INIT_COMPLETION(context->response_event);
3576 vos_spin_lock_release(&hdd_context_lock);
3577
Dino Myclee8843b32014-07-04 14:21:45 +05303578 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303579 if (!HAL_STATUS_SUCCESS(status)) {
3580 hddLog(VOS_TRACE_LEVEL_ERROR,
3581 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303582 return -EINVAL;
3583 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303584
3585 rc = wait_for_completion_timeout(&context->response_event,
3586 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3587 if (!rc) {
3588 hddLog(LOGE, FL("Target response timed out"));
3589 return -ETIMEDOUT;
3590 }
3591
3592 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3593 if (ret)
3594 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3595
3596 return ret;
3597
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303598 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303599 return 0;
3600}
3601
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303602static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3603 struct wireless_dev *wdev,
3604 const void *data, int dataLen)
3605{
3606 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303607
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303608 vos_ssr_protect(__func__);
3609 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3610 vos_ssr_unprotect(__func__);
3611
3612 return ret;
3613}
3614
3615static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3616 struct wireless_dev *wdev,
3617 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303618{
Dino Myclee8843b32014-07-04 14:21:45 +05303619 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303620 struct net_device *dev = wdev->netdev;
3621 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3622 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3623 struct nlattr
3624 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3625 eHalStatus status;
3626
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303627 ENTER();
3628
Dino Mycle6fb96c12014-06-10 11:52:40 +05303629 status = wlan_hdd_validate_context(pHddCtx);
3630 if (0 != status)
3631 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303632 return -EINVAL;
3633 }
Dino Myclee8843b32014-07-04 14:21:45 +05303634 /* check the EXTScan Capability */
3635 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3636 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3637 {
3638 hddLog(VOS_TRACE_LEVEL_ERROR,
3639 FL("EXTScan not enabled/supported by Firmware"));
3640 return -EINVAL;
3641 }
3642
Dino Mycle6fb96c12014-06-10 11:52:40 +05303643 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3644 data, dataLen,
3645 wlan_hdd_extscan_config_policy)) {
3646 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3647 return -EINVAL;
3648 }
3649 /* Parse and fetch request Id */
3650 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3651 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3652 return -EINVAL;
3653 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303654
Dino Myclee8843b32014-07-04 14:21:45 +05303655 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303656 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3657
Dino Myclee8843b32014-07-04 14:21:45 +05303658 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303659
Dino Myclee8843b32014-07-04 14:21:45 +05303660 reqMsg.sessionId = pAdapter->sessionId;
3661 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303662
3663 /* Parse and fetch flush parameter */
3664 if (!tb
3665 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3666 {
3667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3668 goto failed;
3669 }
Dino Myclee8843b32014-07-04 14:21:45 +05303670 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303671 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3672
Dino Myclee8843b32014-07-04 14:21:45 +05303673 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303674
Dino Myclee8843b32014-07-04 14:21:45 +05303675 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303676 if (!HAL_STATUS_SUCCESS(status)) {
3677 hddLog(VOS_TRACE_LEVEL_ERROR,
3678 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303679 return -EINVAL;
3680 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303681 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303682 return 0;
3683
3684failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303685 return -EINVAL;
3686}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303687static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3688 struct wireless_dev *wdev,
3689 const void *data, int dataLen)
3690{
3691 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303692
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303693 vos_ssr_protect(__func__);
3694 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3695 vos_ssr_unprotect(__func__);
3696
3697 return ret;
3698}
3699
3700static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303701 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303702 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303703{
3704 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3705 struct net_device *dev = wdev->netdev;
3706 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3707 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3708 struct nlattr
3709 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3710 struct nlattr
3711 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3712 struct nlattr *apTh;
3713 eHalStatus status;
3714 tANI_U8 i = 0;
3715 int rem;
3716
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303717 ENTER();
3718
Dino Mycle6fb96c12014-06-10 11:52:40 +05303719 status = wlan_hdd_validate_context(pHddCtx);
3720 if (0 != status)
3721 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303722 return -EINVAL;
3723 }
Dino Myclee8843b32014-07-04 14:21:45 +05303724 /* check the EXTScan Capability */
3725 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3726 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3727 {
3728 hddLog(VOS_TRACE_LEVEL_ERROR,
3729 FL("EXTScan not enabled/supported by Firmware"));
3730 return -EINVAL;
3731 }
3732
Dino Mycle6fb96c12014-06-10 11:52:40 +05303733 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3734 data, dataLen,
3735 wlan_hdd_extscan_config_policy)) {
3736 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3737 return -EINVAL;
3738 }
3739
3740 /* Parse and fetch request Id */
3741 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3742 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3743 return -EINVAL;
3744 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303745 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3746 vos_mem_malloc(sizeof(*pReqMsg));
3747 if (!pReqMsg) {
3748 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3749 return -ENOMEM;
3750 }
3751
Dino Myclee8843b32014-07-04 14:21:45 +05303752
Dino Mycle6fb96c12014-06-10 11:52:40 +05303753 pReqMsg->requestId = nla_get_u32(
3754 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3755 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3756
3757 /* Parse and fetch number of APs */
3758 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3759 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3760 goto fail;
3761 }
3762
3763 pReqMsg->sessionId = pAdapter->sessionId;
3764 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3765
3766 pReqMsg->numAp = nla_get_u32(
3767 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3768 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3769
3770 nla_for_each_nested(apTh,
3771 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3772 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3773 nla_data(apTh), nla_len(apTh),
3774 NULL)) {
3775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3776 goto fail;
3777 }
3778
3779 /* Parse and fetch MAC address */
3780 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3781 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3782 goto fail;
3783 }
3784 memcpy(pReqMsg->ap[i].bssid, nla_data(
3785 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3786 sizeof(tSirMacAddr));
3787 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3788
3789 /* Parse and fetch low RSSI */
3790 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3791 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3792 goto fail;
3793 }
3794 pReqMsg->ap[i].low = nla_get_s32(
3795 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3796 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3797
3798 /* Parse and fetch high RSSI */
3799 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3801 goto fail;
3802 }
3803 pReqMsg->ap[i].high = nla_get_s32(
3804 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3805 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3806 pReqMsg->ap[i].high);
3807
3808 /* Parse and fetch channel */
3809 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3810 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3811 goto fail;
3812 }
3813 pReqMsg->ap[i].channel = nla_get_u32(
3814 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3815 hddLog(VOS_TRACE_LEVEL_INFO,
3816 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3817 i++;
3818 }
3819 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3820 if (!HAL_STATUS_SUCCESS(status)) {
3821 hddLog(VOS_TRACE_LEVEL_ERROR,
3822 FL("sme_SetBssHotlist failed(err=%d)"), status);
3823 vos_mem_free(pReqMsg);
3824 return -EINVAL;
3825 }
3826
Dino Myclee8843b32014-07-04 14:21:45 +05303827 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303828 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303829 return 0;
3830
3831fail:
3832 vos_mem_free(pReqMsg);
3833 return -EINVAL;
3834}
3835
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303836static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3837 struct wireless_dev *wdev,
3838 const void *data, int dataLen)
3839{
3840 int ret = 0;
3841
3842 vos_ssr_protect(__func__);
3843 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3844 dataLen);
3845 vos_ssr_unprotect(__func__);
3846
3847 return ret;
3848}
3849
3850static int __wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303851 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303852 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303853{
3854 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3855 struct net_device *dev = wdev->netdev;
3856 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3857 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3858 struct nlattr
3859 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3860 struct nlattr
3861 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3862 struct nlattr *apTh;
3863 eHalStatus status;
3864 int i = 0;
3865 int rem;
3866
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303867 ENTER();
3868
Dino Mycle6fb96c12014-06-10 11:52:40 +05303869 status = wlan_hdd_validate_context(pHddCtx);
3870 if (0 != status)
3871 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303872 return -EINVAL;
3873 }
Dino Myclee8843b32014-07-04 14:21:45 +05303874 /* check the EXTScan Capability */
3875 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3876 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3877 {
3878 hddLog(VOS_TRACE_LEVEL_ERROR,
3879 FL("EXTScan not enabled/supported by Firmware"));
3880 return -EINVAL;
3881 }
3882
Dino Mycle6fb96c12014-06-10 11:52:40 +05303883 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3884 data, dataLen,
3885 wlan_hdd_extscan_config_policy)) {
3886 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3887 return -EINVAL;
3888 }
3889
3890 /* Parse and fetch request Id */
3891 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3892 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3893 return -EINVAL;
3894 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303895 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303896 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303897 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303898 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3899 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303900 }
3901
Dino Myclee8843b32014-07-04 14:21:45 +05303902
3903
Dino Mycle6fb96c12014-06-10 11:52:40 +05303904 pReqMsg->requestId = nla_get_u32(
3905 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3906 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3907
3908 /* Parse and fetch RSSI sample size */
3909 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3910 {
3911 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3912 goto fail;
3913 }
3914 pReqMsg->rssiSampleSize = nla_get_u32(
3915 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3916 hddLog(VOS_TRACE_LEVEL_INFO,
3917 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3918
3919 /* Parse and fetch lost AP sample size */
3920 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3921 {
3922 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3923 goto fail;
3924 }
3925 pReqMsg->lostApSampleSize = nla_get_u32(
3926 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3927 hddLog(VOS_TRACE_LEVEL_INFO,
3928 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3929 /* Parse and fetch minimum Breaching */
3930 if (!tb
3931 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3932 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3933 goto fail;
3934 }
3935 pReqMsg->minBreaching = nla_get_u32(
3936 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3937 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3938
3939 /* Parse and fetch number of APs */
3940 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3941 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3942 goto fail;
3943 }
3944 pReqMsg->numAp = nla_get_u32(
3945 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3946 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3947
3948 pReqMsg->sessionId = pAdapter->sessionId;
3949 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3950
3951 nla_for_each_nested(apTh,
3952 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3953 if(nla_parse(tb2,
3954 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3955 nla_data(apTh), nla_len(apTh),
3956 NULL)) {
3957 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3958 goto fail;
3959 }
3960
3961 /* Parse and fetch MAC address */
3962 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3963 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3964 goto fail;
3965 }
3966 memcpy(pReqMsg->ap[i].bssid, nla_data(
3967 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3968 sizeof(tSirMacAddr));
3969
3970 /* Parse and fetch low RSSI */
3971 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3972 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3973 goto fail;
3974 }
3975 pReqMsg->ap[i].low = nla_get_s32(
3976 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3977 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3978
3979 /* Parse and fetch high RSSI */
3980 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3981 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3982 goto fail;
3983 }
3984 pReqMsg->ap[i].high = nla_get_s32(
3985 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3986 hddLog(VOS_TRACE_LEVEL_INFO,
3987 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3988
3989 /* Parse and fetch channel */
3990 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3991 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3992 goto fail;
3993 }
3994 pReqMsg->ap[i].channel = nla_get_u32(
3995 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3996 hddLog(VOS_TRACE_LEVEL_INFO,
3997 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3998 i++;
3999 }
4000
4001 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
4002 if (!HAL_STATUS_SUCCESS(status)) {
4003 hddLog(VOS_TRACE_LEVEL_ERROR,
4004 FL("sme_SetSignificantChange failed(err=%d)"), status);
4005 vos_mem_free(pReqMsg);
4006 return -EINVAL;
4007 }
Dino Myclee8843b32014-07-04 14:21:45 +05304008 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304009 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304010 return 0;
4011
4012fail:
4013 vos_mem_free(pReqMsg);
4014 return -EINVAL;
4015}
4016
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304017static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
4018 struct wireless_dev *wdev,
4019 const void *data, int dataLen)
4020{
4021 int ret = 0;
4022
4023 vos_ssr_protect(__func__);
4024 ret = __wlan_hdd_cfg80211_extscan_set_significant_change(wiphy, wdev, data,
4025 dataLen);
4026 vos_ssr_unprotect(__func__);
4027
4028 return ret;
4029}
4030
4031static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304032 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304033 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304034{
4035 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4036 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4037 tANI_U8 numChannels = 0;
4038 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304039 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304040 tWifiBand wifiBand;
4041 eHalStatus status;
4042 struct sk_buff *replySkb;
4043 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304044 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304045
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304046 ENTER();
4047
Dino Mycle6fb96c12014-06-10 11:52:40 +05304048 status = wlan_hdd_validate_context(pHddCtx);
4049 if (0 != status)
4050 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304051 return -EINVAL;
4052 }
Dino Myclee8843b32014-07-04 14:21:45 +05304053
Dino Mycle6fb96c12014-06-10 11:52:40 +05304054 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4055 data, dataLen,
4056 wlan_hdd_extscan_config_policy)) {
4057 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4058 return -EINVAL;
4059 }
4060
4061 /* Parse and fetch request Id */
4062 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4063 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4064 return -EINVAL;
4065 }
4066 requestId = nla_get_u32(
4067 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4068 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4069
4070 /* Parse and fetch wifi band */
4071 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4072 {
4073 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4074 return -EINVAL;
4075 }
4076 wifiBand = nla_get_u32(
4077 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4078 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4079
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304080 /* Parse and fetch max channels */
4081 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4082 {
4083 hddLog(LOGE, FL("attr max channels failed"));
4084 return -EINVAL;
4085 }
4086 maxChannels = nla_get_u32(
4087 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4088 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4089
Dino Mycle6fb96c12014-06-10 11:52:40 +05304090 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
4091 wifiBand, ChannelList,
4092 &numChannels);
4093 if (eHAL_STATUS_SUCCESS != status) {
4094 hddLog(VOS_TRACE_LEVEL_ERROR,
4095 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4096 return -EINVAL;
4097 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304098
4099 numChannels = VOS_MIN(numChannels, maxChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304100 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304101
Dino Mycle6fb96c12014-06-10 11:52:40 +05304102 for (i = 0; i < numChannels; i++)
4103 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
4104
4105 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4106 sizeof(u32) * numChannels +
4107 NLMSG_HDRLEN);
4108
4109 if (!replySkb) {
4110 hddLog(VOS_TRACE_LEVEL_ERROR,
4111 FL("valid channels: buffer alloc fail"));
4112 return -EINVAL;
4113 }
4114 if (nla_put_u32(replySkb,
4115 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
4116 numChannels) ||
4117 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
4118 sizeof(u32) * numChannels, ChannelList)) {
4119
4120 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4121 kfree_skb(replySkb);
4122 return -EINVAL;
4123 }
4124
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304125 ret = cfg80211_vendor_cmd_reply(replySkb);
4126
4127 EXIT();
4128 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304129}
4130
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304131static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4132 struct wireless_dev *wdev,
4133 const void *data, int dataLen)
4134{
4135 int ret = 0;
4136
4137 vos_ssr_protect(__func__);
4138 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4139 dataLen);
4140 vos_ssr_unprotect(__func__);
4141
4142 return ret;
4143}
4144
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304145static int hdd_extscan_start_fill_bucket_channel_spec(
4146 hdd_context_t *pHddCtx,
4147 tpSirEXTScanStartReqParams pReqMsg,
4148 struct nlattr **tb)
4149{
4150 struct nlattr *bucket[
4151 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4152 struct nlattr *channel[
4153 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4154 struct nlattr *buckets;
4155 struct nlattr *channels;
4156 int rem1, rem2;
4157 eHalStatus status;
4158 tANI_U8 bktIndex, j, numChannels;
4159 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4160 tANI_U32 passive_max_chn_time, active_max_chn_time;
4161
4162 bktIndex = 0;
4163
4164 nla_for_each_nested(buckets,
4165 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4166 if (nla_parse(bucket,
4167 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4168 nla_data(buckets), nla_len(buckets), NULL)) {
4169 hddLog(LOGE, FL("nla_parse failed"));
4170 return -EINVAL;
4171 }
4172
4173 /* Parse and fetch bucket spec */
4174 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4175 hddLog(LOGE, FL("attr bucket index failed"));
4176 return -EINVAL;
4177 }
4178 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4179 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4180 hddLog(LOG1, FL("Bucket spec Index %d"),
4181 pReqMsg->buckets[bktIndex].bucket);
4182
4183 /* Parse and fetch wifi band */
4184 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4185 hddLog(LOGE, FL("attr wifi band failed"));
4186 return -EINVAL;
4187 }
4188 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4189 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4190 hddLog(LOG1, FL("Wifi band %d"),
4191 pReqMsg->buckets[bktIndex].band);
4192
4193 /* Parse and fetch period */
4194 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4195 hddLog(LOGE, FL("attr period failed"));
4196 return -EINVAL;
4197 }
4198 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4199 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4200 hddLog(LOG1, FL("period %d"),
4201 pReqMsg->buckets[bktIndex].period);
4202
4203 /* Parse and fetch report events */
4204 if (!bucket[
4205 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4206 hddLog(LOGE, FL("attr report events failed"));
4207 return -EINVAL;
4208 }
4209 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4210 bucket[
4211 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4212 hddLog(LOG1, FL("report events %d"),
4213 pReqMsg->buckets[bktIndex].reportEvents);
4214
4215 /* Parse and fetch max period */
4216 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4217 hddLog(LOGE, FL("attr max period failed"));
4218 return -EINVAL;
4219 }
4220 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4221 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4222 hddLog(LOG1, FL("max period %u"),
4223 pReqMsg->buckets[bktIndex].max_period);
4224
4225 /* Parse and fetch exponent */
4226 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4227 hddLog(LOGE, FL("attr exponent failed"));
4228 return -EINVAL;
4229 }
4230 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4231 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4232 hddLog(LOG1, FL("exponent %u"),
4233 pReqMsg->buckets[bktIndex].exponent);
4234
4235 /* Parse and fetch step count */
4236 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4237 hddLog(LOGE, FL("attr step count failed"));
4238 return -EINVAL;
4239 }
4240 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4241 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4242 hddLog(LOG1, FL("Step count %u"),
4243 pReqMsg->buckets[bktIndex].step_count);
4244
4245 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4246 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4247
4248 /* Framework shall pass the channel list if the input WiFi band is
4249 * WIFI_BAND_UNSPECIFIED.
4250 * If the input WiFi band is specified (any value other than
4251 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4252 */
4253 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4254 numChannels = 0;
4255 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4256 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4257 pReqMsg->buckets[bktIndex].band,
4258 chanList, &numChannels);
4259 if (!HAL_STATUS_SUCCESS(status)) {
4260 hddLog(LOGE,
4261 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4262 status);
4263 return -EINVAL;
4264 }
4265
4266 pReqMsg->buckets[bktIndex].numChannels =
4267 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4268 hddLog(LOG1, FL("Num channels %d"),
4269 pReqMsg->buckets[bktIndex].numChannels);
4270
4271 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4272 j++) {
4273 pReqMsg->buckets[bktIndex].channels[j].channel =
4274 chanList[j];
4275 pReqMsg->buckets[bktIndex].channels[j].
4276 chnlClass = 0;
4277 if (CSR_IS_CHANNEL_DFS(
4278 vos_freq_to_chan(chanList[j]))) {
4279 pReqMsg->buckets[bktIndex].channels[j].
4280 passive = 1;
4281 pReqMsg->buckets[bktIndex].channels[j].
4282 dwellTimeMs = passive_max_chn_time;
4283 } else {
4284 pReqMsg->buckets[bktIndex].channels[j].
4285 passive = 0;
4286 pReqMsg->buckets[bktIndex].channels[j].
4287 dwellTimeMs = active_max_chn_time;
4288 }
4289
4290 hddLog(LOG1,
4291 "Channel %u Passive %u Dwell time %u ms",
4292 pReqMsg->buckets[bktIndex].channels[j].channel,
4293 pReqMsg->buckets[bktIndex].channels[j].passive,
4294 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4295 }
4296
4297 bktIndex++;
4298 continue;
4299 }
4300
4301 /* Parse and fetch number of channels */
4302 if (!bucket[
4303 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4304 hddLog(LOGE, FL("attr num channels failed"));
4305 return -EINVAL;
4306 }
4307
4308 pReqMsg->buckets[bktIndex].numChannels =
4309 nla_get_u32(bucket[
4310 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4311 hddLog(LOG1, FL("num channels %d"),
4312 pReqMsg->buckets[bktIndex].numChannels);
4313
4314 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4315 hddLog(LOGE, FL("attr channel spec failed"));
4316 return -EINVAL;
4317 }
4318
4319 j = 0;
4320 nla_for_each_nested(channels,
4321 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4322 if (nla_parse(channel,
4323 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4324 nla_data(channels), nla_len(channels),
4325 wlan_hdd_extscan_config_policy)) {
4326 hddLog(LOGE, FL("nla_parse failed"));
4327 return -EINVAL;
4328 }
4329
4330 /* Parse and fetch channel */
4331 if (!channel[
4332 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4333 hddLog(LOGE, FL("attr channel failed"));
4334 return -EINVAL;
4335 }
4336 pReqMsg->buckets[bktIndex].channels[j].channel =
4337 nla_get_u32(channel[
4338 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4339 hddLog(LOG1, FL("channel %u"),
4340 pReqMsg->buckets[bktIndex].channels[j].channel);
4341
4342 /* Parse and fetch dwell time */
4343 if (!channel[
4344 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4345 hddLog(LOGE, FL("attr dwelltime failed"));
4346 return -EINVAL;
4347 }
4348 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4349 nla_get_u32(channel[
4350 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4351
4352 hddLog(LOG1, FL("Dwell time (%u ms)"),
4353 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4354
4355
4356 /* Parse and fetch channel spec passive */
4357 if (!channel[
4358 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4359 hddLog(LOGE,
4360 FL("attr channel spec passive failed"));
4361 return -EINVAL;
4362 }
4363 pReqMsg->buckets[bktIndex].channels[j].passive =
4364 nla_get_u8(channel[
4365 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4366 hddLog(LOG1, FL("Chnl spec passive %u"),
4367 pReqMsg->buckets[bktIndex].channels[j].passive);
4368
4369 j++;
4370 }
4371
4372 bktIndex++;
4373 }
4374
4375 return 0;
4376}
4377
4378
4379/*
4380 * define short names for the global vendor params
4381 * used by wlan_hdd_cfg80211_extscan_start()
4382 */
4383#define PARAM_MAX \
4384QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4385#define PARAM_REQUEST_ID \
4386QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4387#define PARAM_BASE_PERIOD \
4388QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4389#define PARAM_MAX_AP_PER_SCAN \
4390QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4391#define PARAM_RPT_THRHLD_PERCENT \
4392QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4393#define PARAM_RPT_THRHLD_NUM_SCANS \
4394QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4395#define PARAM_NUM_BUCKETS \
4396QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4397
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304398static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304399 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304400 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304401{
Dino Myclee8843b32014-07-04 14:21:45 +05304402 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304403 struct net_device *dev = wdev->netdev;
4404 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4405 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4406 struct nlattr *tb[PARAM_MAX + 1];
4407 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304408 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304409 tANI_U32 request_id;
4410 struct hdd_ext_scan_context *context;
4411 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304412
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304413 ENTER();
4414
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304415 if (VOS_FTM_MODE == hdd_get_conparam()) {
4416 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4417 return -EINVAL;
4418 }
4419
Dino Mycle6fb96c12014-06-10 11:52:40 +05304420 status = wlan_hdd_validate_context(pHddCtx);
4421 if (0 != status)
4422 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304423 return -EINVAL;
4424 }
Dino Myclee8843b32014-07-04 14:21:45 +05304425 /* check the EXTScan Capability */
4426 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4427 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4428 {
4429 hddLog(VOS_TRACE_LEVEL_ERROR,
4430 FL("EXTScan not enabled/supported by Firmware"));
4431 return -EINVAL;
4432 }
4433
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304434 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304435 data, dataLen,
4436 wlan_hdd_extscan_config_policy)) {
4437 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4438 return -EINVAL;
4439 }
4440
4441 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304442 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304443 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4444 return -EINVAL;
4445 }
4446
Dino Myclee8843b32014-07-04 14:21:45 +05304447 pReqMsg = (tpSirEXTScanStartReqParams)
4448 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304449 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304450 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4451 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304452 }
4453
4454 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304455 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304456 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4457
4458 pReqMsg->sessionId = pAdapter->sessionId;
4459 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4460
4461 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304462 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304463 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4464 goto fail;
4465 }
4466 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304467 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304468 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4469 pReqMsg->basePeriod);
4470
4471 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304472 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304473 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4474 goto fail;
4475 }
4476 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304477 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304478 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4479 pReqMsg->maxAPperScan);
4480
4481 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304482 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304483 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4484 goto fail;
4485 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304486 pReqMsg->reportThresholdPercent = nla_get_u8(
4487 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304488 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304489 pReqMsg->reportThresholdPercent);
4490
4491 /* Parse and fetch report threshold num scans */
4492 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4493 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4494 goto fail;
4495 }
4496 pReqMsg->reportThresholdNumScans = nla_get_u8(
4497 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4498 hddLog(LOG1, FL("Report Threshold num scans %d"),
4499 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304500
4501 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304502 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304503 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4504 goto fail;
4505 }
4506 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304507 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304508 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4509 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4510 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4511 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4512 }
4513 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4514 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304515
Dino Mycle6fb96c12014-06-10 11:52:40 +05304516 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4517 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4518 goto fail;
4519 }
4520
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304521 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304522
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304523 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4524 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304525
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304526 context = &pHddCtx->ext_scan_context;
4527 spin_lock(&hdd_context_lock);
4528 INIT_COMPLETION(context->response_event);
4529 context->request_id = request_id = pReqMsg->requestId;
4530 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304531
Dino Mycle6fb96c12014-06-10 11:52:40 +05304532 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4533 if (!HAL_STATUS_SUCCESS(status)) {
4534 hddLog(VOS_TRACE_LEVEL_ERROR,
4535 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304536 goto fail;
4537 }
4538
4539 /* request was sent -- wait for the response */
4540 rc = wait_for_completion_timeout(&context->response_event,
4541 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4542
4543 if (!rc) {
4544 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4545 retval = -ETIMEDOUT;
4546 } else {
4547 spin_lock(&hdd_context_lock);
4548 if (context->request_id == request_id)
4549 retval = context->response_status;
4550 else
4551 retval = -EINVAL;
4552 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304553 }
4554
Dino Myclee8843b32014-07-04 14:21:45 +05304555 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304556 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304557 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304558
4559fail:
4560 vos_mem_free(pReqMsg);
4561 return -EINVAL;
4562}
4563
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304564/*
4565 * done with short names for the global vendor params
4566 * used by wlan_hdd_cfg80211_extscan_start()
4567 */
4568#undef PARAM_MAX
4569#undef PARAM_REQUEST_ID
4570#undef PARAM_BASE_PERIOD
4571#undef PARAMS_MAX_AP_PER_SCAN
4572#undef PARAMS_RPT_THRHLD_PERCENT
4573#undef PARAMS_RPT_THRHLD_NUM_SCANS
4574#undef PARAMS_NUM_BUCKETS
4575
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304576static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4577 struct wireless_dev *wdev,
4578 const void *data, int dataLen)
4579{
4580 int ret = 0;
4581
4582 vos_ssr_protect(__func__);
4583 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4584 vos_ssr_unprotect(__func__);
4585
4586 return ret;
4587}
4588
4589static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304590 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304591 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304592{
Dino Myclee8843b32014-07-04 14:21:45 +05304593 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304594 struct net_device *dev = wdev->netdev;
4595 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4596 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4597 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4598 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304599 int retval;
4600 unsigned long rc;
4601 struct hdd_ext_scan_context *context;
4602 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304603
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304604 ENTER();
4605
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304606 if (VOS_FTM_MODE == hdd_get_conparam()) {
4607 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4608 return -EINVAL;
4609 }
4610
Dino Mycle6fb96c12014-06-10 11:52:40 +05304611 status = wlan_hdd_validate_context(pHddCtx);
4612 if (0 != status)
4613 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304614 return -EINVAL;
4615 }
Dino Myclee8843b32014-07-04 14:21:45 +05304616 /* check the EXTScan Capability */
4617 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4618 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4619 {
4620 hddLog(VOS_TRACE_LEVEL_ERROR,
4621 FL("EXTScan not enabled/supported by Firmware"));
4622 return -EINVAL;
4623 }
4624
Dino Mycle6fb96c12014-06-10 11:52:40 +05304625 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4626 data, dataLen,
4627 wlan_hdd_extscan_config_policy)) {
4628 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4629 return -EINVAL;
4630 }
4631
4632 /* Parse and fetch request Id */
4633 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4634 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4635 return -EINVAL;
4636 }
4637
Dino Myclee8843b32014-07-04 14:21:45 +05304638 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304639 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304640 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304641
Dino Myclee8843b32014-07-04 14:21:45 +05304642 reqMsg.sessionId = pAdapter->sessionId;
4643 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304644
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304645 context = &pHddCtx->ext_scan_context;
4646 spin_lock(&hdd_context_lock);
4647 INIT_COMPLETION(context->response_event);
4648 context->request_id = request_id = reqMsg.sessionId;
4649 spin_unlock(&hdd_context_lock);
4650
Dino Myclee8843b32014-07-04 14:21:45 +05304651 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304652 if (!HAL_STATUS_SUCCESS(status)) {
4653 hddLog(VOS_TRACE_LEVEL_ERROR,
4654 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304655 return -EINVAL;
4656 }
4657
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304658 /* request was sent -- wait for the response */
4659 rc = wait_for_completion_timeout(&context->response_event,
4660 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4661
4662 if (!rc) {
4663 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4664 retval = -ETIMEDOUT;
4665 } else {
4666 spin_lock(&hdd_context_lock);
4667 if (context->request_id == request_id)
4668 retval = context->response_status;
4669 else
4670 retval = -EINVAL;
4671 spin_unlock(&hdd_context_lock);
4672 }
4673
4674 return retval;
4675
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304676 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304677 return 0;
4678}
4679
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304680static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4681 struct wireless_dev *wdev,
4682 const void *data, int dataLen)
4683{
4684 int ret = 0;
4685
4686 vos_ssr_protect(__func__);
4687 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4688 vos_ssr_unprotect(__func__);
4689
4690 return ret;
4691}
4692
4693static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304694 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304695 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304696{
Dino Myclee8843b32014-07-04 14:21:45 +05304697 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304698 struct net_device *dev = wdev->netdev;
4699 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4700 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4701 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4702 eHalStatus status;
4703
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304704 ENTER();
4705
Dino Mycle6fb96c12014-06-10 11:52:40 +05304706 status = wlan_hdd_validate_context(pHddCtx);
4707 if (0 != status)
4708 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304709 return -EINVAL;
4710 }
Dino Myclee8843b32014-07-04 14:21:45 +05304711 /* check the EXTScan Capability */
4712 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4713 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4714 {
4715 hddLog(VOS_TRACE_LEVEL_ERROR,
4716 FL("EXTScan not enabled/supported by Firmware"));
4717 return -EINVAL;
4718 }
4719
Dino Mycle6fb96c12014-06-10 11:52:40 +05304720 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4721 data, dataLen,
4722 wlan_hdd_extscan_config_policy)) {
4723 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4724 return -EINVAL;
4725 }
4726
4727 /* Parse and fetch request Id */
4728 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4729 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4730 return -EINVAL;
4731 }
4732
Dino Myclee8843b32014-07-04 14:21:45 +05304733 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304734 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304735 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304736
Dino Myclee8843b32014-07-04 14:21:45 +05304737 reqMsg.sessionId = pAdapter->sessionId;
4738 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304739
Dino Myclee8843b32014-07-04 14:21:45 +05304740 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304741 if (!HAL_STATUS_SUCCESS(status)) {
4742 hddLog(VOS_TRACE_LEVEL_ERROR,
4743 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304744 return -EINVAL;
4745 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304746 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304747 return 0;
4748}
4749
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304750static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4751 struct wireless_dev *wdev,
4752 const void *data, int dataLen)
4753{
4754 int ret = 0;
4755
4756 vos_ssr_protect(__func__);
4757 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4758 vos_ssr_unprotect(__func__);
4759
4760 return ret;
4761}
4762
4763static int __wlan_hdd_cfg80211_extscan_reset_significant_change(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304764 struct wiphy *wiphy,
4765 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304766 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304767{
Dino Myclee8843b32014-07-04 14:21:45 +05304768 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304769 struct net_device *dev = wdev->netdev;
4770 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4771 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4772 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4773 eHalStatus status;
4774
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304775 ENTER();
4776
Dino Mycle6fb96c12014-06-10 11:52:40 +05304777 status = wlan_hdd_validate_context(pHddCtx);
4778 if (0 != status)
4779 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304780 return -EINVAL;
4781 }
Dino Myclee8843b32014-07-04 14:21:45 +05304782 /* check the EXTScan Capability */
4783 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4784 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4785 {
4786 hddLog(VOS_TRACE_LEVEL_ERROR,
4787 FL("EXTScan not enabled/supported by Firmware"));
4788 return -EINVAL;
4789 }
4790
Dino Mycle6fb96c12014-06-10 11:52:40 +05304791 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4792 data, dataLen,
4793 wlan_hdd_extscan_config_policy)) {
4794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4795 return -EINVAL;
4796 }
4797
4798 /* Parse and fetch request Id */
4799 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4801 return -EINVAL;
4802 }
4803
Dino Mycle6fb96c12014-06-10 11:52:40 +05304804
Dino Myclee8843b32014-07-04 14:21:45 +05304805 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304806 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304807 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304808
Dino Myclee8843b32014-07-04 14:21:45 +05304809 reqMsg.sessionId = pAdapter->sessionId;
4810 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304811
Dino Myclee8843b32014-07-04 14:21:45 +05304812 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304813 if (!HAL_STATUS_SUCCESS(status)) {
4814 hddLog(VOS_TRACE_LEVEL_ERROR,
4815 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304816 return -EINVAL;
4817 }
4818
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304819 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304820 return 0;
4821}
4822
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304823static int wlan_hdd_cfg80211_extscan_reset_significant_change(
4824 struct wiphy *wiphy,
4825 struct wireless_dev *wdev,
4826 const void *data, int dataLen)
4827{
4828 int ret = 0;
4829
4830 vos_ssr_protect(__func__);
4831 ret = __wlan_hdd_cfg80211_extscan_reset_significant_change(wiphy,
4832 wdev, data,
4833 dataLen);
4834 vos_ssr_unprotect(__func__);
4835
4836 return ret;
4837}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304838#endif /* WLAN_FEATURE_EXTSCAN */
4839
Atul Mittal115287b2014-07-08 13:26:33 +05304840/*EXT TDLS*/
4841static const struct nla_policy
4842wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4843{
4844 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4845 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4846 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4847 {.type = NLA_S32 },
4848 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4849 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4850
4851};
4852
4853static const struct nla_policy
4854wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4855{
4856 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4857
4858};
4859
4860static const struct nla_policy
4861wlan_hdd_tdls_config_state_change_policy[
4862 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4863{
4864 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4865 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4866 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304867 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4868 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4869 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304870
4871};
4872
4873static const struct nla_policy
4874wlan_hdd_tdls_config_get_status_policy[
4875 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4876{
4877 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4878 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4879 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304880 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4881 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4882 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304883
4884};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304885
4886static const struct nla_policy
4887wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4888{
4889 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4890};
4891
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304892static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304893 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304894 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304895 int data_len)
4896{
4897
4898 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4899 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4900
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304901 ENTER();
4902
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304903 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304904 return -EINVAL;
4905 }
4906 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05304907 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304908 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304909 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304910 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05304911 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304912 return -ENOTSUPP;
4913 }
4914
4915 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4916 data, data_len, wlan_hdd_mac_config)) {
4917 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4918 return -EINVAL;
4919 }
4920
4921 /* Parse and fetch mac address */
4922 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4923 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4924 return -EINVAL;
4925 }
4926
4927 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4928 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4929 VOS_MAC_ADDR_LAST_3_BYTES);
4930
Siddharth Bhal76972212014-10-15 16:22:51 +05304931 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4932
4933 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304934 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4935 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304936 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4937 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4938 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4939 {
4940 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4941 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4942 VOS_MAC_ADDRESS_LEN);
4943 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304944 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304945
Siddharth Bhal76972212014-10-15 16:22:51 +05304946 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
4947 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304948 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4949 }
4950
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304951 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304952 return 0;
4953}
4954
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304955static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
4956 struct wireless_dev *wdev,
4957 const void *data,
4958 int data_len)
4959{
4960 int ret = 0;
4961
4962 vos_ssr_protect(__func__);
4963 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
4964 vos_ssr_unprotect(__func__);
4965
4966 return ret;
4967}
4968
4969static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304970 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304971 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304972 int data_len)
4973{
4974 u8 peer[6] = {0};
4975 struct net_device *dev = wdev->netdev;
4976 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4977 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4978 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4979 eHalStatus ret;
4980 tANI_S32 state;
4981 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304982 tANI_S32 global_operating_class = 0;
4983 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304984 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304985 int retVal;
4986
4987 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304988
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304989 if (!pAdapter) {
4990 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4991 return -EINVAL;
4992 }
4993
Atul Mittal115287b2014-07-08 13:26:33 +05304994 ret = wlan_hdd_validate_context(pHddCtx);
4995 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304996 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304997 return -EINVAL;
4998 }
4999 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305000 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305001 return -ENOTSUPP;
5002 }
5003 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5004 data, data_len,
5005 wlan_hdd_tdls_config_get_status_policy)) {
5006 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5007 return -EINVAL;
5008 }
5009
5010 /* Parse and fetch mac address */
5011 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5012 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5013 return -EINVAL;
5014 }
5015
5016 memcpy(peer, nla_data(
5017 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5018 sizeof(peer));
5019 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5020
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305021 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305022
Atul Mittal115287b2014-07-08 13:26:33 +05305023 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305024 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305025 NLMSG_HDRLEN);
5026
5027 if (!skb) {
5028 hddLog(VOS_TRACE_LEVEL_ERROR,
5029 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5030 return -EINVAL;
5031 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305032 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 +05305033 reason,
5034 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305035 global_operating_class,
5036 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305037 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305038 if (nla_put_s32(skb,
5039 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5040 state) ||
5041 nla_put_s32(skb,
5042 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5043 reason) ||
5044 nla_put_s32(skb,
5045 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5046 global_operating_class) ||
5047 nla_put_s32(skb,
5048 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5049 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305050
5051 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5052 goto nla_put_failure;
5053 }
5054
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305055 retVal = cfg80211_vendor_cmd_reply(skb);
5056 EXIT();
5057 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305058
5059nla_put_failure:
5060 kfree_skb(skb);
5061 return -EINVAL;
5062}
5063
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305064static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5065 struct wireless_dev *wdev,
5066 const void *data,
5067 int data_len)
5068{
5069 int ret = 0;
5070
5071 vos_ssr_protect(__func__);
5072 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5073 vos_ssr_unprotect(__func__);
5074
5075 return ret;
5076}
5077
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305078static int wlan_hdd_cfg80211_exttdls_callback(
5079#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5080 const tANI_U8* mac,
5081#else
5082 tANI_U8* mac,
5083#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305084 tANI_S32 state,
5085 tANI_S32 reason,
5086 void *ctx)
5087{
5088 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305089 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305090 tANI_S32 global_operating_class = 0;
5091 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305092 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305093
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305094 ENTER();
5095
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305096 if (!pAdapter) {
5097 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5098 return -EINVAL;
5099 }
5100
5101 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305102 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305103 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305104 return -EINVAL;
5105 }
5106
5107 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305108 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305109 return -ENOTSUPP;
5110 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305111 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5112#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5113 NULL,
5114#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305115 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5116 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5117 GFP_KERNEL);
5118
5119 if (!skb) {
5120 hddLog(VOS_TRACE_LEVEL_ERROR,
5121 FL("cfg80211_vendor_event_alloc failed"));
5122 return -EINVAL;
5123 }
5124 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305125 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5126 reason,
5127 state,
5128 global_operating_class,
5129 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305130 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5131 MAC_ADDR_ARRAY(mac));
5132
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305133 if (nla_put(skb,
5134 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5135 VOS_MAC_ADDR_SIZE, mac) ||
5136 nla_put_s32(skb,
5137 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5138 state) ||
5139 nla_put_s32(skb,
5140 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5141 reason) ||
5142 nla_put_s32(skb,
5143 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5144 channel) ||
5145 nla_put_s32(skb,
5146 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5147 global_operating_class)
5148 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305149 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5150 goto nla_put_failure;
5151 }
5152
5153 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305154 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305155 return (0);
5156
5157nla_put_failure:
5158 kfree_skb(skb);
5159 return -EINVAL;
5160}
5161
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305162static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305163 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305164 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305165 int data_len)
5166{
5167 u8 peer[6] = {0};
5168 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305169 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5170 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5171 eHalStatus status;
5172 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305173 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305174 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305175
5176 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305177
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305178 if (!dev) {
5179 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5180 return -EINVAL;
5181 }
5182
5183 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5184 if (!pAdapter) {
5185 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5186 return -EINVAL;
5187 }
5188
Atul Mittal115287b2014-07-08 13:26:33 +05305189 status = wlan_hdd_validate_context(pHddCtx);
5190 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305191 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305192 return -EINVAL;
5193 }
5194 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305195 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305196 return -ENOTSUPP;
5197 }
5198 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5199 data, data_len,
5200 wlan_hdd_tdls_config_enable_policy)) {
5201 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5202 return -EINVAL;
5203 }
5204
5205 /* Parse and fetch mac address */
5206 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5207 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5208 return -EINVAL;
5209 }
5210
5211 memcpy(peer, nla_data(
5212 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5213 sizeof(peer));
5214 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5215
5216 /* Parse and fetch channel */
5217 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5218 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5219 return -EINVAL;
5220 }
5221 pReqMsg.channel = nla_get_s32(
5222 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5223 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5224
5225 /* Parse and fetch global operating class */
5226 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5227 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5228 return -EINVAL;
5229 }
5230 pReqMsg.global_operating_class = nla_get_s32(
5231 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5232 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5233 pReqMsg.global_operating_class);
5234
5235 /* Parse and fetch latency ms */
5236 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5237 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5238 return -EINVAL;
5239 }
5240 pReqMsg.max_latency_ms = nla_get_s32(
5241 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5242 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5243 pReqMsg.max_latency_ms);
5244
5245 /* Parse and fetch required bandwidth kbps */
5246 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5247 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5248 return -EINVAL;
5249 }
5250
5251 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5252 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5253 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5254 pReqMsg.min_bandwidth_kbps);
5255
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305256 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305257 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305258 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305259 wlan_hdd_cfg80211_exttdls_callback);
5260
5261 EXIT();
5262 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305263}
5264
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305265static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5266 struct wireless_dev *wdev,
5267 const void *data,
5268 int data_len)
5269{
5270 int ret = 0;
5271
5272 vos_ssr_protect(__func__);
5273 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5274 vos_ssr_unprotect(__func__);
5275
5276 return ret;
5277}
5278
5279static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305280 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305281 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305282 int data_len)
5283{
5284 u8 peer[6] = {0};
5285 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305286 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5287 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5288 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305289 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305290 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305291
5292 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305293
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305294 if (!dev) {
5295 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5296 return -EINVAL;
5297 }
5298
5299 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5300 if (!pAdapter) {
5301 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5302 return -EINVAL;
5303 }
5304
Atul Mittal115287b2014-07-08 13:26:33 +05305305 status = wlan_hdd_validate_context(pHddCtx);
5306 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305307 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305308 return -EINVAL;
5309 }
5310 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305311 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305312 return -ENOTSUPP;
5313 }
5314 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5315 data, data_len,
5316 wlan_hdd_tdls_config_disable_policy)) {
5317 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5318 return -EINVAL;
5319 }
5320 /* Parse and fetch mac address */
5321 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5322 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5323 return -EINVAL;
5324 }
5325
5326 memcpy(peer, nla_data(
5327 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5328 sizeof(peer));
5329 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5330
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305331 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5332
5333 EXIT();
5334 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305335}
5336
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305337static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5338 struct wireless_dev *wdev,
5339 const void *data,
5340 int data_len)
5341{
5342 int ret = 0;
5343
5344 vos_ssr_protect(__func__);
5345 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5346 vos_ssr_unprotect(__func__);
5347
5348 return ret;
5349}
5350
Dasari Srinivas7875a302014-09-26 17:50:57 +05305351static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305352__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305353 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305354 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305355{
5356 struct net_device *dev = wdev->netdev;
5357 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5358 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5359 struct sk_buff *skb = NULL;
5360 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305361 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305362
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305363 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305364
5365 ret = wlan_hdd_validate_context(pHddCtx);
5366 if (0 != ret)
5367 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305368 return ret;
5369 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305370 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5371 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5372 fset |= WIFI_FEATURE_INFRA;
5373 }
5374
5375 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5376 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5377 fset |= WIFI_FEATURE_INFRA_5G;
5378 }
5379
5380#ifdef WLAN_FEATURE_P2P
5381 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5382 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5383 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5384 fset |= WIFI_FEATURE_P2P;
5385 }
5386#endif
5387
5388 /* Soft-AP is supported currently by default */
5389 fset |= WIFI_FEATURE_SOFT_AP;
5390
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305391 /* HOTSPOT is a supplicant feature, enable it by default */
5392 fset |= WIFI_FEATURE_HOTSPOT;
5393
Dasari Srinivas7875a302014-09-26 17:50:57 +05305394#ifdef WLAN_FEATURE_EXTSCAN
5395 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
5396 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
5397 hddLog(LOG1, FL("EXTScan is supported by firmware"));
5398 fset |= WIFI_FEATURE_EXTSCAN;
5399 }
5400#endif
5401
Dasari Srinivas7875a302014-09-26 17:50:57 +05305402 if (sme_IsFeatureSupportedByFW(NAN)) {
5403 hddLog(LOG1, FL("NAN is supported by firmware"));
5404 fset |= WIFI_FEATURE_NAN;
5405 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305406
5407 /* D2D RTT is not supported currently by default */
5408 if (sme_IsFeatureSupportedByFW(RTT)) {
5409 hddLog(LOG1, FL("RTT is supported by firmware"));
5410 fset |= WIFI_FEATURE_D2AP_RTT;
5411 }
5412
5413#ifdef FEATURE_WLAN_BATCH_SCAN
5414 if (fset & WIFI_FEATURE_EXTSCAN) {
5415 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5416 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5417 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5418 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5419 fset |= WIFI_FEATURE_BATCH_SCAN;
5420 }
5421#endif
5422
5423#ifdef FEATURE_WLAN_SCAN_PNO
5424 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5425 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5426 hddLog(LOG1, FL("PNO is supported by firmware"));
5427 fset |= WIFI_FEATURE_PNO;
5428 }
5429#endif
5430
5431 /* STA+STA is supported currently by default */
5432 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5433
5434#ifdef FEATURE_WLAN_TDLS
5435 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5436 sme_IsFeatureSupportedByFW(TDLS)) {
5437 hddLog(LOG1, FL("TDLS is supported by firmware"));
5438 fset |= WIFI_FEATURE_TDLS;
5439 }
5440
5441 /* TDLS_OFFCHANNEL is not supported currently by default */
5442#endif
5443
5444#ifdef WLAN_AP_STA_CONCURRENCY
5445 /* AP+STA concurrency is supported currently by default */
5446 fset |= WIFI_FEATURE_AP_STA;
5447#endif
5448
Mukul Sharma5add0532015-08-17 15:57:47 +05305449#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5450 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5451 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5452#endif
5453
Dasari Srinivas7875a302014-09-26 17:50:57 +05305454 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5455 NLMSG_HDRLEN);
5456
5457 if (!skb) {
5458 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5459 return -EINVAL;
5460 }
5461 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5462
5463 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5464 hddLog(LOGE, FL("nla put fail"));
5465 goto nla_put_failure;
5466 }
5467
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305468 ret = cfg80211_vendor_cmd_reply(skb);
5469 EXIT();
5470 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305471
5472nla_put_failure:
5473 kfree_skb(skb);
5474 return -EINVAL;
5475}
5476
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305477static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305478wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5479 struct wireless_dev *wdev,
5480 const void *data, int data_len)
5481{
5482 int ret = 0;
5483
5484 vos_ssr_protect(__func__);
5485 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5486 vos_ssr_unprotect(__func__);
5487
5488 return ret;
5489}
5490
5491static int
5492__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305493 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305494 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305495{
5496 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5497 uint8_t i, feature_sets, max_feature_sets;
5498 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5499 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305500 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5501 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305502
5503 ENTER();
5504
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305505 ret = wlan_hdd_validate_context(pHddCtx);
5506 if (0 != ret)
5507 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305508 return ret;
5509 }
5510
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305511 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5512 data, data_len, NULL)) {
5513 hddLog(LOGE, FL("Invalid ATTR"));
5514 return -EINVAL;
5515 }
5516
5517 /* Parse and fetch max feature set */
5518 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5519 hddLog(LOGE, FL("Attr max feature set size failed"));
5520 return -EINVAL;
5521 }
5522 max_feature_sets = nla_get_u32(
5523 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5524 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5525
5526 /* Fill feature combination matrix */
5527 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305528 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5529 WIFI_FEATURE_P2P;
5530
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305531 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5532 WIFI_FEATURE_SOFT_AP;
5533
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305534 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5535 WIFI_FEATURE_SOFT_AP;
5536
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305537 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5538 WIFI_FEATURE_SOFT_AP |
5539 WIFI_FEATURE_P2P;
5540
5541 /* Add more feature combinations here */
5542
5543 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5544 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5545 hddLog(LOG1, "Feature set matrix");
5546 for (i = 0; i < feature_sets; i++)
5547 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5548
5549 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5550 sizeof(u32) * feature_sets +
5551 NLMSG_HDRLEN);
5552
5553 if (reply_skb) {
5554 if (nla_put_u32(reply_skb,
5555 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5556 feature_sets) ||
5557 nla_put(reply_skb,
5558 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5559 sizeof(u32) * feature_sets, feature_set_matrix)) {
5560 hddLog(LOGE, FL("nla put fail"));
5561 kfree_skb(reply_skb);
5562 return -EINVAL;
5563 }
5564
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305565 ret = cfg80211_vendor_cmd_reply(reply_skb);
5566 EXIT();
5567 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305568 }
5569 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5570 return -ENOMEM;
5571
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305572}
5573
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305574static int
5575wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5576 struct wireless_dev *wdev,
5577 const void *data, int data_len)
5578{
5579 int ret = 0;
5580
5581 vos_ssr_protect(__func__);
5582 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5583 data_len);
5584 vos_ssr_unprotect(__func__);
5585
5586 return ret;
5587}
5588
Agarwal Ashish738843c2014-09-25 12:27:56 +05305589static const struct nla_policy
5590wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5591 +1] =
5592{
5593 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5594};
5595
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305596static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305597 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305598 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305599 int data_len)
5600{
5601 struct net_device *dev = wdev->netdev;
5602 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5603 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5604 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5605 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5606 eHalStatus status;
5607 u32 dfsFlag = 0;
5608
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305609 ENTER();
5610
Agarwal Ashish738843c2014-09-25 12:27:56 +05305611 status = wlan_hdd_validate_context(pHddCtx);
5612 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305613 return -EINVAL;
5614 }
5615 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5616 data, data_len,
5617 wlan_hdd_set_no_dfs_flag_config_policy)) {
5618 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5619 return -EINVAL;
5620 }
5621
5622 /* Parse and fetch required bandwidth kbps */
5623 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5624 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5625 return -EINVAL;
5626 }
5627
5628 dfsFlag = nla_get_u32(
5629 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5630 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5631 dfsFlag);
5632
5633 pHddCtx->disable_dfs_flag = dfsFlag;
5634
5635 sme_disable_dfs_channel(hHal, dfsFlag);
5636 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305637
5638 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305639 return 0;
5640}
Atul Mittal115287b2014-07-08 13:26:33 +05305641
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305642static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5643 struct wireless_dev *wdev,
5644 const void *data,
5645 int data_len)
5646{
5647 int ret = 0;
5648
5649 vos_ssr_protect(__func__);
5650 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5651 vos_ssr_unprotect(__func__);
5652
5653 return ret;
5654
5655}
5656
Mukul Sharma2a271632014-10-13 14:59:01 +05305657const struct
5658nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5659{
5660 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5661 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5662};
5663
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305664static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305665 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305666{
5667
5668 u8 bssid[6] = {0};
5669 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5670 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5671 eHalStatus status = eHAL_STATUS_SUCCESS;
5672 v_U32_t isFwrRoamEnabled = FALSE;
5673 int ret;
5674
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305675 ENTER();
5676
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305677 ret = wlan_hdd_validate_context(pHddCtx);
5678 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305679 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305680 }
5681
5682 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5683 data, data_len,
5684 qca_wlan_vendor_attr);
5685 if (ret){
5686 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5687 return -EINVAL;
5688 }
5689
5690 /* Parse and fetch Enable flag */
5691 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5692 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5693 return -EINVAL;
5694 }
5695
5696 isFwrRoamEnabled = nla_get_u32(
5697 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5698
5699 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5700
5701 /* Parse and fetch bssid */
5702 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5703 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5704 return -EINVAL;
5705 }
5706
5707 memcpy(bssid, nla_data(
5708 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5709 sizeof(bssid));
5710 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5711
5712 //Update roaming
5713 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305714 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305715 return status;
5716}
5717
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305718static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5719 struct wireless_dev *wdev, const void *data, int data_len)
5720{
5721 int ret = 0;
5722
5723 vos_ssr_protect(__func__);
5724 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5725 vos_ssr_unprotect(__func__);
5726
5727 return ret;
5728}
5729
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305730/**
5731 * __wlan_hdd_cfg80211_setband() - set band
5732 * @wiphy: Pointer to wireless phy
5733 * @wdev: Pointer to wireless device
5734 * @data: Pointer to data
5735 * @data_len: Data length
5736 *
5737 * Return: 0 on success, negative errno on failure
5738 */
5739static int
5740__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5741 struct wireless_dev *wdev,
5742 const void *data,
5743 int data_len)
5744{
5745 struct net_device *dev = wdev->netdev;
5746 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5747 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5748 int ret;
5749 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
5750 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
5751
5752 ENTER();
5753
5754 ret = wlan_hdd_validate_context(hdd_ctx);
5755 if (0 != ret) {
5756 hddLog(LOGE, FL("HDD context is not valid"));
5757 return ret;
5758 }
5759
5760 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
5761 policy)) {
5762 hddLog(LOGE, FL("Invalid ATTR"));
5763 return -EINVAL;
5764 }
5765
5766 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
5767 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
5768 return -EINVAL;
5769 }
5770
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305771 hdd_ctx->isSetBandByNL = TRUE;
5772 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305773 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305774 hdd_ctx->isSetBandByNL = FALSE;
5775
5776 EXIT();
5777 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305778}
5779
5780/**
5781 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
5782 * @wiphy: wiphy structure pointer
5783 * @wdev: Wireless device structure pointer
5784 * @data: Pointer to the data received
5785 * @data_len: Length of @data
5786 *
5787 * Return: 0 on success; errno on failure
5788 */
5789static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5790 struct wireless_dev *wdev,
5791 const void *data,
5792 int data_len)
5793{
5794 int ret = 0;
5795
5796 vos_ssr_protect(__func__);
5797 ret = __wlan_hdd_cfg80211_setband(wiphy,
5798 wdev, data, data_len);
5799 vos_ssr_unprotect(__func__);
5800
5801 return ret;
5802}
5803
Sunil Duttc69bccb2014-05-26 21:30:20 +05305804const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
5805{
Mukul Sharma2a271632014-10-13 14:59:01 +05305806 {
5807 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5808 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
5809 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5810 WIPHY_VENDOR_CMD_NEED_NETDEV |
5811 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305812 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05305813 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305814
5815 {
5816 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5817 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
5818 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5819 WIPHY_VENDOR_CMD_NEED_NETDEV |
5820 WIPHY_VENDOR_CMD_NEED_RUNNING,
5821 .doit = wlan_hdd_cfg80211_nan_request
5822 },
5823
Sunil Duttc69bccb2014-05-26 21:30:20 +05305824#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5825 {
5826 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5827 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
5828 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5829 WIPHY_VENDOR_CMD_NEED_NETDEV |
5830 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305831 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05305832 },
5833
5834 {
5835 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5836 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
5837 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5838 WIPHY_VENDOR_CMD_NEED_NETDEV |
5839 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305840 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05305841 },
5842
5843 {
5844 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5845 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
5846 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5847 WIPHY_VENDOR_CMD_NEED_NETDEV |
5848 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305849 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05305850 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305851#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305852#ifdef WLAN_FEATURE_EXTSCAN
5853 {
5854 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5855 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
5856 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5857 WIPHY_VENDOR_CMD_NEED_NETDEV |
5858 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305859 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05305860 },
5861 {
5862 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5863 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
5864 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5865 WIPHY_VENDOR_CMD_NEED_NETDEV |
5866 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305867 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05305868 },
5869 {
5870 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5871 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
5872 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5873 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305874 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05305875 },
5876 {
5877 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5878 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
5879 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5880 WIPHY_VENDOR_CMD_NEED_NETDEV |
5881 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305882 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05305883 },
5884 {
5885 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5886 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
5887 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5888 WIPHY_VENDOR_CMD_NEED_NETDEV |
5889 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305890 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05305891 },
5892 {
5893 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5894 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
5895 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5896 WIPHY_VENDOR_CMD_NEED_NETDEV |
5897 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305898 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305899 },
5900 {
5901 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5902 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
5903 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5904 WIPHY_VENDOR_CMD_NEED_NETDEV |
5905 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305906 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305907 },
5908 {
5909 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5910 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
5911 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5912 WIPHY_VENDOR_CMD_NEED_NETDEV |
5913 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305914 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305915 },
5916 {
5917 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5918 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
5919 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5920 WIPHY_VENDOR_CMD_NEED_NETDEV |
5921 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305922 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305923 },
5924#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305925/*EXT TDLS*/
5926 {
5927 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5928 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
5929 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5930 WIPHY_VENDOR_CMD_NEED_NETDEV |
5931 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305932 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05305933 },
5934 {
5935 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5936 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
5937 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5938 WIPHY_VENDOR_CMD_NEED_NETDEV |
5939 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305940 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05305941 },
5942 {
5943 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5944 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
5945 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5946 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305947 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05305948 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05305949 {
5950 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5951 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
5952 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5953 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305954 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05305955 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05305956 {
5957 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5958 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
5959 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5960 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305961 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05305962 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305963 {
5964 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5965 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
5966 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5967 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305968 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305969 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305970 {
5971 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5972 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
5973 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5974 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305975 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305976 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305977 {
5978 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5979 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
5980 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5981 WIPHY_VENDOR_CMD_NEED_NETDEV |
5982 WIPHY_VENDOR_CMD_NEED_RUNNING,
5983 .doit = wlan_hdd_cfg80211_setband
5984 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05305985};
5986
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005987/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05305988static const
5989struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005990{
5991#ifdef FEATURE_WLAN_CH_AVOID
5992 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05305993 .vendor_id = QCA_NL80211_VENDOR_ID,
5994 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005995 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305996#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
5997#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5998 {
5999 /* Index = 1*/
6000 .vendor_id = QCA_NL80211_VENDOR_ID,
6001 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
6002 },
6003 {
6004 /* Index = 2*/
6005 .vendor_id = QCA_NL80211_VENDOR_ID,
6006 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
6007 },
6008 {
6009 /* Index = 3*/
6010 .vendor_id = QCA_NL80211_VENDOR_ID,
6011 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
6012 },
6013 {
6014 /* Index = 4*/
6015 .vendor_id = QCA_NL80211_VENDOR_ID,
6016 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
6017 },
6018 {
6019 /* Index = 5*/
6020 .vendor_id = QCA_NL80211_VENDOR_ID,
6021 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
6022 },
6023 {
6024 /* Index = 6*/
6025 .vendor_id = QCA_NL80211_VENDOR_ID,
6026 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
6027 },
6028#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05306029#ifdef WLAN_FEATURE_EXTSCAN
6030 {
6031 .vendor_id = QCA_NL80211_VENDOR_ID,
6032 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
6033 },
6034 {
6035 .vendor_id = QCA_NL80211_VENDOR_ID,
6036 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
6037 },
6038 {
6039 .vendor_id = QCA_NL80211_VENDOR_ID,
6040 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
6041 },
6042 {
6043 .vendor_id = QCA_NL80211_VENDOR_ID,
6044 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
6045 },
6046 {
6047 .vendor_id = QCA_NL80211_VENDOR_ID,
6048 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
6049 },
6050 {
6051 .vendor_id = QCA_NL80211_VENDOR_ID,
6052 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
6053 },
6054 {
6055 .vendor_id = QCA_NL80211_VENDOR_ID,
6056 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
6057 },
6058 {
6059 .vendor_id = QCA_NL80211_VENDOR_ID,
6060 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
6061 },
6062 {
6063 .vendor_id = QCA_NL80211_VENDOR_ID,
6064 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
6065 },
6066 {
6067 .vendor_id = QCA_NL80211_VENDOR_ID,
6068 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
6069 },
6070 {
6071 .vendor_id = QCA_NL80211_VENDOR_ID,
6072 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
6073 },
6074 {
6075 .vendor_id = QCA_NL80211_VENDOR_ID,
6076 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
6077 },
6078 {
6079 .vendor_id = QCA_NL80211_VENDOR_ID,
6080 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
6081 },
6082#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05306083/*EXT TDLS*/
6084 {
6085 .vendor_id = QCA_NL80211_VENDOR_ID,
6086 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
6087 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05306088
6089 {
6090 .vendor_id = QCA_NL80211_VENDOR_ID,
6091 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
6092 },
6093
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006094};
6095
Jeff Johnson295189b2012-06-20 16:38:30 -07006096/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306097 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306098 * This function is called by hdd_wlan_startup()
6099 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306100 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07006101 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306102struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07006103{
6104 struct wiphy *wiphy;
6105 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306106 /*
6107 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07006108 */
6109 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
6110
6111 if (!wiphy)
6112 {
6113 /* Print error and jump into err label and free the memory */
6114 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
6115 return NULL;
6116 }
6117
Sunil Duttc69bccb2014-05-26 21:30:20 +05306118
Jeff Johnson295189b2012-06-20 16:38:30 -07006119 return wiphy;
6120}
6121
6122/*
6123 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306124 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07006125 * private ioctl to change the band value
6126 */
6127int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
6128{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306129 int i, j;
6130 eNVChannelEnabledType channelEnabledState;
6131
Jeff Johnsone7245742012-09-05 17:12:55 -07006132 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306133
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306134 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006135 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306136
6137 if (NULL == wiphy->bands[i])
6138 {
6139 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
6140 __func__, i);
6141 continue;
6142 }
6143
6144 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
6145 {
6146 struct ieee80211_supported_band *band = wiphy->bands[i];
6147
6148 channelEnabledState = vos_nv_getChannelEnabledState(
6149 band->channels[j].hw_value);
6150
6151 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
6152 {
Abhishek Singh678227a2014-11-04 10:52:38 +05306153 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306154 continue;
6155 }
6156 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
6157 {
6158 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6159 continue;
6160 }
6161
6162 if (NV_CHANNEL_DISABLE == channelEnabledState ||
6163 NV_CHANNEL_INVALID == channelEnabledState)
6164 {
6165 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6166 }
6167 else if (NV_CHANNEL_DFS == channelEnabledState)
6168 {
6169 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
6170 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
6171 }
6172 else
6173 {
6174 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
6175 |IEEE80211_CHAN_RADAR);
6176 }
6177 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006178 }
6179 return 0;
6180}
6181/*
6182 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306183 * This function is called by hdd_wlan_startup()
6184 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07006185 * This function is used to initialize and register wiphy structure.
6186 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306187int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006188 struct wiphy *wiphy,
6189 hdd_config_t *pCfg
6190 )
6191{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306192 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05306193 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6194
Jeff Johnsone7245742012-09-05 17:12:55 -07006195 ENTER();
6196
Jeff Johnson295189b2012-06-20 16:38:30 -07006197 /* Now bind the underlying wlan device with wiphy */
6198 set_wiphy_dev(wiphy, dev);
6199
6200 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07006201
Kiet Lam6c583332013-10-14 05:37:09 +05306202#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07006203 /* the flag for the other case would be initialzed in
6204 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07006205 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05306206#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07006207
Amar Singhalfddc28c2013-09-05 13:03:40 -07006208 /* This will disable updating of NL channels from passive to
6209 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306210#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
6211 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
6212#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07006213 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306214#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07006215
Amar Singhala49cbc52013-10-08 18:37:44 -07006216
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006217#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07006218 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
6219 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
6220 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07006221 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306222#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
6223 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
6224#else
6225 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
6226#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006227#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07006228
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006229#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006230 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08006231#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006232 || pCfg->isFastRoamIniFeatureEnabled
6233#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006234#ifdef FEATURE_WLAN_ESE
6235 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006236#endif
6237 )
6238 {
6239 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
6240 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08006241#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006242#ifdef FEATURE_WLAN_TDLS
6243 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
6244 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
6245#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306246#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05306247 if (pCfg->configPNOScanSupport)
6248 {
6249 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
6250 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
6251 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
6252 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
6253 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306254#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006255
Abhishek Singh10d85972015-04-17 10:27:23 +05306256#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6257 wiphy->features |= NL80211_FEATURE_HT_IBSS;
6258#endif
6259
Amar Singhalfddc28c2013-09-05 13:03:40 -07006260#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07006261 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
6262 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07006263 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07006264 driver need to determine what to do with both
6265 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07006266
6267 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07006268#else
6269 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07006270#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006271
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306272 wiphy->max_scan_ssids = MAX_SCAN_SSID;
6273
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05306274 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07006275
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306276 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
6277
Jeff Johnson295189b2012-06-20 16:38:30 -07006278 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05306279 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
6280 | BIT(NL80211_IFTYPE_ADHOC)
6281 | BIT(NL80211_IFTYPE_P2P_CLIENT)
6282 | BIT(NL80211_IFTYPE_P2P_GO)
6283 | BIT(NL80211_IFTYPE_AP);
6284
6285 if (VOS_MONITOR_MODE == hdd_get_conparam())
6286 {
6287 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
6288 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006289
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306290 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006291 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306292#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6293 if( pCfg->enableMCC )
6294 {
6295 /* Currently, supports up to two channels */
6296 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006297
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306298 if( !pCfg->allowMCCGODiffBI )
6299 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006300
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306301 }
6302 wiphy->iface_combinations = &wlan_hdd_iface_combination;
6303 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006304#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306305 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006306
Jeff Johnson295189b2012-06-20 16:38:30 -07006307 /* Before registering we need to update the ht capabilitied based
6308 * on ini values*/
6309 if( !pCfg->ShortGI20MhzEnable )
6310 {
6311 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6312 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6313 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6314 }
6315
6316 if( !pCfg->ShortGI40MhzEnable )
6317 {
6318 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
6319 }
6320
6321 if( !pCfg->nChannelBondingMode5GHz )
6322 {
6323 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6324 }
6325
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306326 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05306327 if (true == hdd_is_5g_supported(pHddCtx))
6328 {
6329 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
6330 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306331
6332 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
6333 {
6334
6335 if (NULL == wiphy->bands[i])
6336 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05306337 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306338 __func__, i);
6339 continue;
6340 }
6341
6342 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
6343 {
6344 struct ieee80211_supported_band *band = wiphy->bands[i];
6345
6346 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
6347 {
6348 // Enable social channels for P2P
6349 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
6350 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
6351 else
6352 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6353 continue;
6354 }
6355 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
6356 {
6357 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6358 continue;
6359 }
6360 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006361 }
6362 /*Initialise the supported cipher suite details*/
6363 wiphy->cipher_suites = hdd_cipher_suites;
6364 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
6365
6366 /*signal strength in mBm (100*dBm) */
6367 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
6368
6369#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05306370 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07006371#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006372
Sunil Duttc69bccb2014-05-26 21:30:20 +05306373 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
6374 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006375 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
6376 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
6377
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306378 EXIT();
6379 return 0;
6380}
6381
6382/* In this function we are registering wiphy. */
6383int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
6384{
6385 ENTER();
6386 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006387 if (0 > wiphy_register(wiphy))
6388 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306389 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07006390 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
6391 return -EIO;
6392 }
6393
6394 EXIT();
6395 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306396}
Jeff Johnson295189b2012-06-20 16:38:30 -07006397
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306398/* In this function we are updating channel list when,
6399 regulatory domain is FCC and country code is US.
6400 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
6401 As per FCC smart phone is not a indoor device.
6402 GO should not opeate on indoor channels */
6403void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
6404{
6405 int j;
6406 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6407 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
6408 //Default counrtycode from NV at the time of wiphy initialization.
6409 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
6410 &defaultCountryCode[0]))
6411 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006412 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306413 }
6414 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
6415 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306416 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
6417 {
6418 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
6419 return;
6420 }
6421 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
6422 {
6423 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
6424 // Mark UNII -1 band channel as passive
6425 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
6426 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
6427 }
6428 }
6429}
6430
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306431/* This function registers for all frame which supplicant is interested in */
6432void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006433{
Jeff Johnson295189b2012-06-20 16:38:30 -07006434 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6435 /* Register for all P2P action, public action etc frames */
6436 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6437
Jeff Johnsone7245742012-09-05 17:12:55 -07006438 ENTER();
6439
Jeff Johnson295189b2012-06-20 16:38:30 -07006440 /* Right now we are registering these frame when driver is getting
6441 initialized. Once we will move to 2.6.37 kernel, in which we have
6442 frame register ops, we will move this code as a part of that */
6443 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306444 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006445 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6446
6447 /* GAS Initial Response */
6448 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6449 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306450
Jeff Johnson295189b2012-06-20 16:38:30 -07006451 /* GAS Comeback Request */
6452 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6453 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6454
6455 /* GAS Comeback Response */
6456 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6457 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6458
6459 /* P2P Public Action */
6460 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306461 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006462 P2P_PUBLIC_ACTION_FRAME_SIZE );
6463
6464 /* P2P Action */
6465 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6466 (v_U8_t*)P2P_ACTION_FRAME,
6467 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07006468
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05306469 /* WNM BSS Transition Request frame */
6470 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6471 (v_U8_t*)WNM_BSS_ACTION_FRAME,
6472 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006473
6474 /* WNM-Notification */
6475 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6476 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6477 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006478}
6479
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306480void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006481{
Jeff Johnson295189b2012-06-20 16:38:30 -07006482 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6483 /* Register for all P2P action, public action etc frames */
6484 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6485
Jeff Johnsone7245742012-09-05 17:12:55 -07006486 ENTER();
6487
Jeff Johnson295189b2012-06-20 16:38:30 -07006488 /* Right now we are registering these frame when driver is getting
6489 initialized. Once we will move to 2.6.37 kernel, in which we have
6490 frame register ops, we will move this code as a part of that */
6491 /* GAS Initial Request */
6492
6493 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6494 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6495
6496 /* GAS Initial Response */
6497 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6498 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306499
Jeff Johnson295189b2012-06-20 16:38:30 -07006500 /* GAS Comeback Request */
6501 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6502 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6503
6504 /* GAS Comeback Response */
6505 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6506 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6507
6508 /* P2P Public Action */
6509 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306510 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006511 P2P_PUBLIC_ACTION_FRAME_SIZE );
6512
6513 /* P2P Action */
6514 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6515 (v_U8_t*)P2P_ACTION_FRAME,
6516 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006517 /* WNM-Notification */
6518 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6519 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6520 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006521}
6522
6523#ifdef FEATURE_WLAN_WAPI
6524void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05306525 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006526{
6527 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6528 tCsrRoamSetKey setKey;
6529 v_BOOL_t isConnected = TRUE;
6530 int status = 0;
6531 v_U32_t roamId= 0xFF;
6532 tANI_U8 *pKeyPtr = NULL;
6533 int n = 0;
6534
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306535 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6536 __func__, hdd_device_modetoString(pAdapter->device_mode),
6537 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006538
Gopichand Nakkalae7480202013-02-11 15:24:22 +05306539 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006540 setKey.keyId = key_index; // Store Key ID
6541 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
6542 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
6543 setKey.paeRole = 0 ; // the PAE role
6544 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
6545 {
6546 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
6547 }
6548 else
6549 {
6550 isConnected = hdd_connIsConnected(pHddStaCtx);
6551 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
6552 }
6553 setKey.keyLength = key_Len;
6554 pKeyPtr = setKey.Key;
6555 memcpy( pKeyPtr, key, key_Len);
6556
Arif Hussain6d2a3322013-11-17 19:50:10 -08006557 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07006558 __func__, key_Len);
6559 for (n = 0 ; n < key_Len; n++)
6560 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
6561 __func__,n,setKey.Key[n]);
6562
6563 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
6564 if ( isConnected )
6565 {
6566 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
6567 pAdapter->sessionId, &setKey, &roamId );
6568 }
6569 if ( status != 0 )
6570 {
6571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6572 "[%4d] sme_RoamSetKey returned ERROR status= %d",
6573 __LINE__, status );
6574 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
6575 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05306576 /* Need to clear any trace of key value in the memory.
6577 * Thus zero out the memory even though it is local
6578 * variable.
6579 */
6580 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006581}
6582#endif /* FEATURE_WLAN_WAPI*/
6583
6584#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306585int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006586 beacon_data_t **ppBeacon,
6587 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006588#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306589int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006590 beacon_data_t **ppBeacon,
6591 struct cfg80211_beacon_data *params,
6592 int dtim_period)
6593#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306594{
Jeff Johnson295189b2012-06-20 16:38:30 -07006595 int size;
6596 beacon_data_t *beacon = NULL;
6597 beacon_data_t *old = NULL;
6598 int head_len,tail_len;
6599
Jeff Johnsone7245742012-09-05 17:12:55 -07006600 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006601 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306602 {
6603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6604 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006605 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306606 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006607
6608 old = pAdapter->sessionCtx.ap.beacon;
6609
6610 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306611 {
6612 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6613 FL("session(%d) old and new heads points to NULL"),
6614 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006615 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306616 }
6617
6618 if (params->tail && !params->tail_len)
6619 {
6620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6621 FL("tail_len is zero but tail is not NULL"));
6622 return -EINVAL;
6623 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006624
Jeff Johnson295189b2012-06-20 16:38:30 -07006625#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
6626 /* Kernel 3.0 is not updating dtim_period for set beacon */
6627 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306628 {
6629 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6630 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006631 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306632 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006633#endif
6634
6635 if(params->head)
6636 head_len = params->head_len;
6637 else
6638 head_len = old->head_len;
6639
6640 if(params->tail || !old)
6641 tail_len = params->tail_len;
6642 else
6643 tail_len = old->tail_len;
6644
6645 size = sizeof(beacon_data_t) + head_len + tail_len;
6646
6647 beacon = kzalloc(size, GFP_KERNEL);
6648
6649 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306650 {
6651 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6652 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006653 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306654 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006655
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006656#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006657 if(params->dtim_period || !old )
6658 beacon->dtim_period = params->dtim_period;
6659 else
6660 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006661#else
6662 if(dtim_period || !old )
6663 beacon->dtim_period = dtim_period;
6664 else
6665 beacon->dtim_period = old->dtim_period;
6666#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306667
Jeff Johnson295189b2012-06-20 16:38:30 -07006668 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6669 beacon->tail = beacon->head + head_len;
6670 beacon->head_len = head_len;
6671 beacon->tail_len = tail_len;
6672
6673 if(params->head) {
6674 memcpy (beacon->head,params->head,beacon->head_len);
6675 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306676 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07006677 if(old)
6678 memcpy (beacon->head,old->head,beacon->head_len);
6679 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306680
Jeff Johnson295189b2012-06-20 16:38:30 -07006681 if(params->tail) {
6682 memcpy (beacon->tail,params->tail,beacon->tail_len);
6683 }
6684 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306685 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07006686 memcpy (beacon->tail,old->tail,beacon->tail_len);
6687 }
6688
6689 *ppBeacon = beacon;
6690
6691 kfree(old);
6692
6693 return 0;
6694
6695}
Jeff Johnson295189b2012-06-20 16:38:30 -07006696
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306697v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
6698#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6699 const v_U8_t *pIes,
6700#else
6701 v_U8_t *pIes,
6702#endif
6703 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006704{
6705 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306706 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07006707 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306708
Jeff Johnson295189b2012-06-20 16:38:30 -07006709 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306710 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006711 elem_id = ptr[0];
6712 elem_len = ptr[1];
6713 left -= 2;
6714 if(elem_len > left)
6715 {
6716 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006717 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006718 eid,elem_len,left);
6719 return NULL;
6720 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306721 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006722 {
6723 return ptr;
6724 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306725
Jeff Johnson295189b2012-06-20 16:38:30 -07006726 left -= elem_len;
6727 ptr += (elem_len + 2);
6728 }
6729 return NULL;
6730}
6731
Jeff Johnson295189b2012-06-20 16:38:30 -07006732/* Check if rate is 11g rate or not */
6733static int wlan_hdd_rate_is_11g(u8 rate)
6734{
Sanjay Devnani28322e22013-06-21 16:13:40 -07006735 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006736 u8 i;
6737 for (i = 0; i < 8; i++)
6738 {
6739 if(rate == gRateArray[i])
6740 return TRUE;
6741 }
6742 return FALSE;
6743}
6744
6745/* Check for 11g rate and set proper 11g only mode */
6746static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
6747 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
6748{
6749 u8 i, num_rates = pIe[0];
6750
6751 pIe += 1;
6752 for ( i = 0; i < num_rates; i++)
6753 {
6754 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
6755 {
6756 /* If rate set have 11g rate than change the mode to 11G */
6757 *pSapHw_mode = eSAP_DOT11_MODE_11g;
6758 if (pIe[i] & BASIC_RATE_MASK)
6759 {
6760 /* If we have 11g rate as basic rate, it means mode
6761 is 11g only mode.
6762 */
6763 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
6764 *pCheckRatesfor11g = FALSE;
6765 }
6766 }
6767 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6768 {
6769 *require_ht = TRUE;
6770 }
6771 }
6772 return;
6773}
6774
6775static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
6776{
6777 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6778 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6779 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6780 u8 checkRatesfor11g = TRUE;
6781 u8 require_ht = FALSE;
6782 u8 *pIe=NULL;
6783
6784 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
6785
6786 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6787 pBeacon->head_len, WLAN_EID_SUPP_RATES);
6788 if (pIe != NULL)
6789 {
6790 pIe += 1;
6791 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6792 &pConfig->SapHw_mode);
6793 }
6794
6795 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6796 WLAN_EID_EXT_SUPP_RATES);
6797 if (pIe != NULL)
6798 {
6799
6800 pIe += 1;
6801 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6802 &pConfig->SapHw_mode);
6803 }
6804
6805 if( pConfig->channel > 14 )
6806 {
6807 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
6808 }
6809
6810 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6811 WLAN_EID_HT_CAPABILITY);
6812
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306813 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006814 {
6815 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
6816 if(require_ht)
6817 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
6818 }
6819}
6820
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306821static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
6822 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
6823{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006824 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306825 v_U8_t *pIe = NULL;
6826 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6827
6828 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6829 pBeacon->tail, pBeacon->tail_len);
6830
6831 if (pIe)
6832 {
6833 ielen = pIe[1] + 2;
6834 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6835 {
6836 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
6837 }
6838 else
6839 {
6840 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
6841 return -EINVAL;
6842 }
6843 *total_ielen += ielen;
6844 }
6845 return 0;
6846}
6847
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006848static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
6849 v_U8_t *genie, v_U8_t *total_ielen)
6850{
6851 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6852 int left = pBeacon->tail_len;
6853 v_U8_t *ptr = pBeacon->tail;
6854 v_U8_t elem_id, elem_len;
6855 v_U16_t ielen = 0;
6856
6857 if ( NULL == ptr || 0 == left )
6858 return;
6859
6860 while (left >= 2)
6861 {
6862 elem_id = ptr[0];
6863 elem_len = ptr[1];
6864 left -= 2;
6865 if (elem_len > left)
6866 {
6867 hddLog( VOS_TRACE_LEVEL_ERROR,
6868 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
6869 elem_id, elem_len, left);
6870 return;
6871 }
6872 if (IE_EID_VENDOR == elem_id)
6873 {
6874 /* skipping the VSIE's which we don't want to include or
6875 * it will be included by existing code
6876 */
6877 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
6878#ifdef WLAN_FEATURE_WFD
6879 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
6880#endif
6881 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6882 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6883 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
6884 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6885 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
6886 {
6887 ielen = ptr[1] + 2;
6888 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6889 {
6890 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
6891 *total_ielen += ielen;
6892 }
6893 else
6894 {
6895 hddLog( VOS_TRACE_LEVEL_ERROR,
6896 "IE Length is too big "
6897 "IEs eid=%d elem_len=%d total_ie_lent=%d",
6898 elem_id, elem_len, *total_ielen);
6899 }
6900 }
6901 }
6902
6903 left -= elem_len;
6904 ptr += (elem_len + 2);
6905 }
6906 return;
6907}
6908
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006909#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006910static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6911 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006912#else
6913static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6914 struct cfg80211_beacon_data *params)
6915#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006916{
6917 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306918 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006919 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07006920 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006921
6922 genie = vos_mem_malloc(MAX_GENIE_LEN);
6923
6924 if(genie == NULL) {
6925
6926 return -ENOMEM;
6927 }
6928
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306929 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6930 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006931 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306932 hddLog(LOGE,
6933 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306934 ret = -EINVAL;
6935 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006936 }
6937
6938#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306939 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6940 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
6941 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306942 hddLog(LOGE,
6943 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306944 ret = -EINVAL;
6945 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006946 }
6947#endif
6948
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306949 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6950 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006951 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306952 hddLog(LOGE,
6953 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306954 ret = -EINVAL;
6955 goto done;
6956 }
6957
6958 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
6959 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006960 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07006961 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006962
6963 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6964 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
6965 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6966 {
6967 hddLog(LOGE,
6968 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006969 ret = -EINVAL;
6970 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006971 }
6972
6973 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6974 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6975 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6976 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6977 ==eHAL_STATUS_FAILURE)
6978 {
6979 hddLog(LOGE,
6980 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006981 ret = -EINVAL;
6982 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006983 }
6984
6985 // Added for ProResp IE
6986 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
6987 {
6988 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
6989 u8 probe_rsp_ie_len[3] = {0};
6990 u8 counter = 0;
6991 /* Check Probe Resp Length if it is greater then 255 then Store
6992 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
6993 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
6994 Store More then 255 bytes into One Variable.
6995 */
6996 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6997 {
6998 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6999 {
7000 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
7001 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
7002 }
7003 else
7004 {
7005 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
7006 rem_probe_resp_ie_len = 0;
7007 }
7008 }
7009
7010 rem_probe_resp_ie_len = 0;
7011
7012 if (probe_rsp_ie_len[0] > 0)
7013 {
7014 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7015 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
7016 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7017 probe_rsp_ie_len[0], NULL,
7018 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7019 {
7020 hddLog(LOGE,
7021 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007022 ret = -EINVAL;
7023 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007024 }
7025 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
7026 }
7027
7028 if (probe_rsp_ie_len[1] > 0)
7029 {
7030 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7031 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
7032 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7033 probe_rsp_ie_len[1], NULL,
7034 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7035 {
7036 hddLog(LOGE,
7037 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007038 ret = -EINVAL;
7039 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007040 }
7041 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
7042 }
7043
7044 if (probe_rsp_ie_len[2] > 0)
7045 {
7046 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7047 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
7048 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7049 probe_rsp_ie_len[2], NULL,
7050 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7051 {
7052 hddLog(LOGE,
7053 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007054 ret = -EINVAL;
7055 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007056 }
7057 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
7058 }
7059
7060 if (probe_rsp_ie_len[1] == 0 )
7061 {
7062 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7063 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7064 eANI_BOOLEAN_FALSE) )
7065 {
7066 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007067 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007068 }
7069 }
7070
7071 if (probe_rsp_ie_len[2] == 0 )
7072 {
7073 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7074 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7075 eANI_BOOLEAN_FALSE) )
7076 {
7077 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007078 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007079 }
7080 }
7081
7082 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7083 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
7084 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7085 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7086 == eHAL_STATUS_FAILURE)
7087 {
7088 hddLog(LOGE,
7089 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007090 ret = -EINVAL;
7091 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007092 }
7093 }
7094 else
7095 {
7096 // Reset WNI_CFG_PROBE_RSP Flags
7097 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
7098
7099 hddLog(VOS_TRACE_LEVEL_INFO,
7100 "%s: No Probe Response IE received in set beacon",
7101 __func__);
7102 }
7103
7104 // Added for AssocResp IE
7105 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
7106 {
7107 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7108 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
7109 params->assocresp_ies_len, NULL,
7110 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7111 {
7112 hddLog(LOGE,
7113 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007114 ret = -EINVAL;
7115 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007116 }
7117
7118 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7119 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
7120 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7121 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7122 == eHAL_STATUS_FAILURE)
7123 {
7124 hddLog(LOGE,
7125 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007126 ret = -EINVAL;
7127 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007128 }
7129 }
7130 else
7131 {
7132 hddLog(VOS_TRACE_LEVEL_INFO,
7133 "%s: No Assoc Response IE received in set beacon",
7134 __func__);
7135
7136 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7137 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7138 eANI_BOOLEAN_FALSE) )
7139 {
7140 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007141 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007142 }
7143 }
7144
Jeff Johnsone7245742012-09-05 17:12:55 -07007145done:
Jeff Johnson295189b2012-06-20 16:38:30 -07007146 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307147 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007148}
Jeff Johnson295189b2012-06-20 16:38:30 -07007149
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307150/*
Jeff Johnson295189b2012-06-20 16:38:30 -07007151 * FUNCTION: wlan_hdd_validate_operation_channel
7152 * called by wlan_hdd_cfg80211_start_bss() and
7153 * wlan_hdd_cfg80211_set_channel()
7154 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307155 * channel list.
7156 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007157VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07007158{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307159
Jeff Johnson295189b2012-06-20 16:38:30 -07007160 v_U32_t num_ch = 0;
7161 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7162 u32 indx = 0;
7163 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307164 v_U8_t fValidChannel = FALSE, count = 0;
7165 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307166
Jeff Johnson295189b2012-06-20 16:38:30 -07007167 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7168
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307169 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07007170 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307171 /* Validate the channel */
7172 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007173 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307174 if ( channel == rfChannels[count].channelNum )
7175 {
7176 fValidChannel = TRUE;
7177 break;
7178 }
7179 }
7180 if (fValidChannel != TRUE)
7181 {
7182 hddLog(VOS_TRACE_LEVEL_ERROR,
7183 "%s: Invalid Channel [%d]", __func__, channel);
7184 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007185 }
7186 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307187 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007188 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307189 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7190 valid_ch, &num_ch))
7191 {
7192 hddLog(VOS_TRACE_LEVEL_ERROR,
7193 "%s: failed to get valid channel list", __func__);
7194 return VOS_STATUS_E_FAILURE;
7195 }
7196 for (indx = 0; indx < num_ch; indx++)
7197 {
7198 if (channel == valid_ch[indx])
7199 {
7200 break;
7201 }
7202 }
7203
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05307204 if (indx >= num_ch)
7205 {
7206 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
7207 {
7208 eCsrBand band;
7209 unsigned int freq;
7210
7211 sme_GetFreqBand(hHal, &band);
7212
7213 if (eCSR_BAND_5G == band)
7214 {
7215#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
7216 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
7217 {
7218 freq = ieee80211_channel_to_frequency(channel,
7219 IEEE80211_BAND_2GHZ);
7220 }
7221 else
7222 {
7223 freq = ieee80211_channel_to_frequency(channel,
7224 IEEE80211_BAND_5GHZ);
7225 }
7226#else
7227 freq = ieee80211_channel_to_frequency(channel);
7228#endif
7229 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
7230 return VOS_STATUS_SUCCESS;
7231 }
7232 }
7233
7234 hddLog(VOS_TRACE_LEVEL_ERROR,
7235 "%s: Invalid Channel [%d]", __func__, channel);
7236 return VOS_STATUS_E_FAILURE;
7237 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007238 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05307239
Jeff Johnson295189b2012-06-20 16:38:30 -07007240 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307241
Jeff Johnson295189b2012-06-20 16:38:30 -07007242}
7243
Viral Modi3a32cc52013-02-08 11:14:52 -08007244/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307245 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08007246 * This function is used to set the channel number
7247 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307248static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08007249 struct ieee80211_channel *chan,
7250 enum nl80211_channel_type channel_type
7251 )
7252{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307253 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08007254 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07007255 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08007256 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307257 hdd_context_t *pHddCtx;
7258 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007259
7260 ENTER();
7261
7262 if( NULL == dev )
7263 {
7264 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007265 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08007266 return -ENODEV;
7267 }
7268 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307269
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307270 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7271 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
7272 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08007273 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307274 "%s: device_mode = %s (%d) freq = %d", __func__,
7275 hdd_device_modetoString(pAdapter->device_mode),
7276 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307277
7278 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7279 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307280 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08007281 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307282 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007283 }
7284
7285 /*
7286 * Do freq to chan conversion
7287 * TODO: for 11a
7288 */
7289
7290 channel = ieee80211_frequency_to_channel(freq);
7291
7292 /* Check freq range */
7293 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
7294 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
7295 {
7296 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007297 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08007298 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
7299 WNI_CFG_CURRENT_CHANNEL_STAMAX);
7300 return -EINVAL;
7301 }
7302
7303 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7304
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05307305 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
7306 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08007307 {
7308 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
7309 {
7310 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007311 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08007312 return -EINVAL;
7313 }
7314 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7315 "%s: set channel to [%d] for device mode =%d",
7316 __func__, channel,pAdapter->device_mode);
7317 }
7318 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08007319 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08007320 )
7321 {
7322 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7323 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
7324 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7325
7326 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
7327 {
7328 /* Link is up then return cant set channel*/
7329 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007330 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08007331 return -EINVAL;
7332 }
7333
7334 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
7335 pHddStaCtx->conn_info.operationChannel = channel;
7336 pRoamProfile->ChannelInfo.ChannelList =
7337 &pHddStaCtx->conn_info.operationChannel;
7338 }
7339 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08007340 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08007341 )
7342 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307343 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
7344 {
7345 if(VOS_STATUS_SUCCESS !=
7346 wlan_hdd_validate_operation_channel(pAdapter,channel))
7347 {
7348 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007349 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307350 return -EINVAL;
7351 }
7352 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7353 }
7354 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08007355 {
7356 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
7357
7358 /* If auto channel selection is configured as enable/ 1 then ignore
7359 channel set by supplicant
7360 */
7361 if ( cfg_param->apAutoChannelSelection )
7362 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307363 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
7364 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08007365 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307366 "%s: set channel to auto channel (0) for device mode =%s (%d)",
7367 __func__, hdd_device_modetoString(pAdapter->device_mode),
7368 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08007369 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307370 else
7371 {
7372 if(VOS_STATUS_SUCCESS !=
7373 wlan_hdd_validate_operation_channel(pAdapter,channel))
7374 {
7375 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007376 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307377 return -EINVAL;
7378 }
7379 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7380 }
Viral Modi3a32cc52013-02-08 11:14:52 -08007381 }
7382 }
7383 else
7384 {
7385 hddLog(VOS_TRACE_LEVEL_FATAL,
7386 "%s: Invalid device mode failed to set valid channel", __func__);
7387 return -EINVAL;
7388 }
7389 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307390 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007391}
7392
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307393static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
7394 struct net_device *dev,
7395 struct ieee80211_channel *chan,
7396 enum nl80211_channel_type channel_type
7397 )
7398{
7399 int ret;
7400
7401 vos_ssr_protect(__func__);
7402 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
7403 vos_ssr_unprotect(__func__);
7404
7405 return ret;
7406}
7407
Jeff Johnson295189b2012-06-20 16:38:30 -07007408#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7409static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7410 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007411#else
7412static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7413 struct cfg80211_beacon_data *params,
7414 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307415 enum nl80211_hidden_ssid hidden_ssid,
7416 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007417#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007418{
7419 tsap_Config_t *pConfig;
7420 beacon_data_t *pBeacon = NULL;
7421 struct ieee80211_mgmt *pMgmt_frame;
7422 v_U8_t *pIe=NULL;
7423 v_U16_t capab_info;
7424 eCsrAuthType RSNAuthType;
7425 eCsrEncryptionType RSNEncryptType;
7426 eCsrEncryptionType mcRSNEncryptType;
7427 int status = VOS_STATUS_SUCCESS;
7428 tpWLAN_SAPEventCB pSapEventCallback;
7429 hdd_hostapd_state_t *pHostapdState;
7430 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
7431 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307432 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007433 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307434 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07007435 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08007436 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05307437 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07007438 v_BOOL_t MFPCapable = VOS_FALSE;
7439 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307440 v_BOOL_t sapEnable11AC =
7441 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07007442 ENTER();
7443
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307444 iniConfig = pHddCtx->cfg_ini;
7445
Jeff Johnson295189b2012-06-20 16:38:30 -07007446 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7447
7448 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7449
7450 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7451
7452 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7453
7454 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7455
7456 //channel is already set in the set_channel Call back
7457 //pConfig->channel = pCommitConfig->channel;
7458
7459 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307460 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07007461 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
7462
7463 pConfig->dtim_period = pBeacon->dtim_period;
7464
Arif Hussain6d2a3322013-11-17 19:50:10 -08007465 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07007466 pConfig->dtim_period);
7467
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08007468 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07007469 {
7470 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007471 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05307472 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
7473 {
7474 tANI_BOOLEAN restartNeeded;
7475 pConfig->ieee80211d = 1;
7476 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
7477 sme_setRegInfo(hHal, pConfig->countryCode);
7478 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
7479 }
7480 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007481 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07007482 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07007483 pConfig->ieee80211d = 1;
7484 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
7485 sme_setRegInfo(hHal, pConfig->countryCode);
7486 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07007487 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007488 else
7489 {
7490 pConfig->ieee80211d = 0;
7491 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307492 /*
7493 * If auto channel is configured i.e. channel is 0,
7494 * so skip channel validation.
7495 */
7496 if( AUTO_CHANNEL_SELECT != pConfig->channel )
7497 {
7498 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
7499 {
7500 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007501 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307502 return -EINVAL;
7503 }
7504 }
7505 else
7506 {
7507 if(1 != pHddCtx->is_dynamic_channel_range_set)
7508 {
7509 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
7510 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
7511 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
7512 }
7513 pHddCtx->is_dynamic_channel_range_set = 0;
7514 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007515 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007516 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007517 {
7518 pConfig->ieee80211d = 0;
7519 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307520
7521#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7522 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7523 pConfig->authType = eSAP_OPEN_SYSTEM;
7524 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7525 pConfig->authType = eSAP_SHARED_KEY;
7526 else
7527 pConfig->authType = eSAP_AUTO_SWITCH;
7528#else
7529 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7530 pConfig->authType = eSAP_OPEN_SYSTEM;
7531 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7532 pConfig->authType = eSAP_SHARED_KEY;
7533 else
7534 pConfig->authType = eSAP_AUTO_SWITCH;
7535#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007536
7537 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307538
7539 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07007540 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
7541
7542 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7543
7544 /*Set wps station to configured*/
7545 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7546
7547 if(pIe)
7548 {
7549 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
7550 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007551 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07007552 return -EINVAL;
7553 }
7554 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
7555 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007556 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07007557 /* Check 15 bit of WPS IE as it contain information for wps state
7558 * WPS state
7559 */
7560 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
7561 {
7562 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
7563 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
7564 {
7565 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7566 }
7567 }
7568 }
7569 else
7570 {
7571 pConfig->wps_state = SAP_WPS_DISABLED;
7572 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307573 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07007574
c_hpothufe599e92014-06-16 11:38:55 +05307575 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7576 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7577 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7578 eCSR_ENCRYPT_TYPE_NONE;
7579
Jeff Johnson295189b2012-06-20 16:38:30 -07007580 pConfig->RSNWPAReqIELength = 0;
7581 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307582 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007583 WLAN_EID_RSN);
7584 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307585 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007586 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7587 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7588 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307589 /* The actual processing may eventually be more extensive than
7590 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07007591 * by the app.
7592 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307593 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007594 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7595 &RSNEncryptType,
7596 &mcRSNEncryptType,
7597 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007598 &MFPCapable,
7599 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007600 pConfig->pRSNWPAReqIE[1]+2,
7601 pConfig->pRSNWPAReqIE );
7602
7603 if( VOS_STATUS_SUCCESS == status )
7604 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307605 /* Now copy over all the security attributes you have
7606 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007607 * */
7608 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7609 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7610 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7611 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307612 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007613 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007614 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7615 }
7616 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307617
Jeff Johnson295189b2012-06-20 16:38:30 -07007618 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7619 pBeacon->tail, pBeacon->tail_len);
7620
7621 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
7622 {
7623 if (pConfig->pRSNWPAReqIE)
7624 {
7625 /*Mixed mode WPA/WPA2*/
7626 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
7627 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7628 }
7629 else
7630 {
7631 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7632 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7633 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307634 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007635 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7636 &RSNEncryptType,
7637 &mcRSNEncryptType,
7638 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007639 &MFPCapable,
7640 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007641 pConfig->pRSNWPAReqIE[1]+2,
7642 pConfig->pRSNWPAReqIE );
7643
7644 if( VOS_STATUS_SUCCESS == status )
7645 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307646 /* Now copy over all the security attributes you have
7647 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007648 * */
7649 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7650 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7651 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7652 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307653 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007654 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007655 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7656 }
7657 }
7658 }
7659
Jeff Johnson4416a782013-03-25 14:17:50 -07007660 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
7661 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
7662 return -EINVAL;
7663 }
7664
Jeff Johnson295189b2012-06-20 16:38:30 -07007665 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
7666
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007667#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007668 if (params->ssid != NULL)
7669 {
7670 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
7671 pConfig->SSIDinfo.ssid.length = params->ssid_len;
7672 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7673 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7674 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007675#else
7676 if (ssid != NULL)
7677 {
7678 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
7679 pConfig->SSIDinfo.ssid.length = ssid_len;
7680 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7681 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7682 }
7683#endif
7684
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307685 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07007686 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307687
Jeff Johnson295189b2012-06-20 16:38:30 -07007688 /* default value */
7689 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7690 pConfig->num_accept_mac = 0;
7691 pConfig->num_deny_mac = 0;
7692
7693 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7694 pBeacon->tail, pBeacon->tail_len);
7695
7696 /* pIe for black list is following form:
7697 type : 1 byte
7698 length : 1 byte
7699 OUI : 4 bytes
7700 acl type : 1 byte
7701 no of mac addr in black list: 1 byte
7702 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307703 */
7704 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007705 {
7706 pConfig->SapMacaddr_acl = pIe[6];
7707 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007708 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007709 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307710 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7711 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007712 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7713 for (i = 0; i < pConfig->num_deny_mac; i++)
7714 {
7715 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7716 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307717 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007718 }
7719 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7720 pBeacon->tail, pBeacon->tail_len);
7721
7722 /* pIe for white list is following form:
7723 type : 1 byte
7724 length : 1 byte
7725 OUI : 4 bytes
7726 acl type : 1 byte
7727 no of mac addr in white list: 1 byte
7728 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307729 */
7730 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007731 {
7732 pConfig->SapMacaddr_acl = pIe[6];
7733 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007734 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007735 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307736 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7737 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007738 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7739 for (i = 0; i < pConfig->num_accept_mac; i++)
7740 {
7741 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7742 acl_entry++;
7743 }
7744 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307745
Jeff Johnson295189b2012-06-20 16:38:30 -07007746 wlan_hdd_set_sapHwmode(pHostapdAdapter);
7747
Jeff Johnsone7245742012-09-05 17:12:55 -07007748#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007749 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307750 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
7751 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05307752 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
7753 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007754 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
7755 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307756 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
7757 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07007758 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307759 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07007760 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307761 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007762
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307763 /* If ACS disable and selected channel <= 14
7764 * OR
7765 * ACS enabled and ACS operating band is choosen as 2.4
7766 * AND
7767 * VHT in 2.4G Disabled
7768 * THEN
7769 * Fallback to 11N mode
7770 */
7771 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
7772 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05307773 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307774 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007775 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307776 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
7777 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007778 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
7779 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007780 }
7781#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307782
Jeff Johnson295189b2012-06-20 16:38:30 -07007783 // ht_capab is not what the name conveys,this is used for protection bitmap
7784 pConfig->ht_capab =
7785 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
7786
7787 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
7788 {
7789 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7790 return -EINVAL;
7791 }
7792
7793 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307794 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07007795 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
7796 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307797 pConfig->obssProtEnabled =
7798 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07007799
Chet Lanctot8cecea22014-02-11 19:09:36 -08007800#ifdef WLAN_FEATURE_11W
7801 pConfig->mfpCapable = MFPCapable;
7802 pConfig->mfpRequired = MFPRequired;
7803 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
7804 pConfig->mfpCapable, pConfig->mfpRequired);
7805#endif
7806
Arif Hussain6d2a3322013-11-17 19:50:10 -08007807 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07007808 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007809 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
7810 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7811 (int)pConfig->channel);
7812 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
7813 pConfig->SapHw_mode, pConfig->privacy,
7814 pConfig->authType);
7815 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
7816 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7817 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7818 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07007819
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307820 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007821 {
7822 //Bss already started. just return.
7823 //TODO Probably it should update some beacon params.
7824 hddLog( LOGE, "Bss Already started...Ignore the request");
7825 EXIT();
7826 return 0;
7827 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307828
Agarwal Ashish51325b52014-06-16 16:50:49 +05307829 if (vos_max_concurrent_connections_reached()) {
7830 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7831 return -EINVAL;
7832 }
7833
Jeff Johnson295189b2012-06-20 16:38:30 -07007834 pConfig->persona = pHostapdAdapter->device_mode;
7835
Peng Xu2446a892014-09-05 17:21:18 +05307836 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
7837 if ( NULL != psmeConfig)
7838 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307839 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05307840 sme_GetConfigParam(hHal, psmeConfig);
7841 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307842#ifdef WLAN_FEATURE_AP_HT40_24G
7843 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7844 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
7845 && pHddCtx->cfg_ini->apHT40_24GEnabled)
7846 {
7847 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
7848 sme_UpdateConfig (hHal, psmeConfig);
7849 }
7850#endif
Peng Xu2446a892014-09-05 17:21:18 +05307851 vos_mem_free(psmeConfig);
7852 }
Peng Xuafc34e32014-09-25 13:23:55 +05307853 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05307854
Jeff Johnson295189b2012-06-20 16:38:30 -07007855 pSapEventCallback = hdd_hostapd_SAPEventCB;
7856 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
7857 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
7858 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007859 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007860 return -EINVAL;
7861 }
7862
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307863 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07007864 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7865
7866 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307867
Jeff Johnson295189b2012-06-20 16:38:30 -07007868 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307869 {
7870 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007871 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07007872 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07007873 VOS_ASSERT(0);
7874 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307875
Jeff Johnson295189b2012-06-20 16:38:30 -07007876 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05307877 /* Initialize WMM configuation */
7878 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307879 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007880
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007881#ifdef WLAN_FEATURE_P2P_DEBUG
7882 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
7883 {
7884 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
7885 {
7886 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7887 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007888 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007889 }
7890 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
7891 {
7892 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7893 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007894 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007895 }
7896 }
7897#endif
7898
Jeff Johnson295189b2012-06-20 16:38:30 -07007899 pHostapdState->bCommit = TRUE;
7900 EXIT();
7901
7902 return 0;
7903}
7904
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007905#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307906static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307907 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007908 struct beacon_parameters *params)
7909{
7910 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307911 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307912 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007913
7914 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307915
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307916 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7917 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
7918 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307919 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
7920 hdd_device_modetoString(pAdapter->device_mode),
7921 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007922
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307923 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7924 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307925 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007926 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307927 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007928 }
7929
Agarwal Ashish51325b52014-06-16 16:50:49 +05307930 if (vos_max_concurrent_connections_reached()) {
7931 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7932 return -EINVAL;
7933 }
7934
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307935 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007936 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007937 )
7938 {
7939 beacon_data_t *old,*new;
7940
7941 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307942
Jeff Johnson295189b2012-06-20 16:38:30 -07007943 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307944 {
7945 hddLog(VOS_TRACE_LEVEL_WARN,
7946 FL("already beacon info added to session(%d)"),
7947 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007948 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307949 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007950
7951 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7952
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307953 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07007954 {
7955 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007956 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007957 return -EINVAL;
7958 }
7959
7960 pAdapter->sessionCtx.ap.beacon = new;
7961
7962 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7963 }
7964
7965 EXIT();
7966 return status;
7967}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307968
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307969static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
7970 struct net_device *dev,
7971 struct beacon_parameters *params)
7972{
7973 int ret;
7974
7975 vos_ssr_protect(__func__);
7976 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
7977 vos_ssr_unprotect(__func__);
7978
7979 return ret;
7980}
7981
7982static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007983 struct net_device *dev,
7984 struct beacon_parameters *params)
7985{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307986 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307987 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7988 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307989 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007990
7991 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307992
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307993 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7994 TRACE_CODE_HDD_CFG80211_SET_BEACON,
7995 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
7996 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7997 __func__, hdd_device_modetoString(pAdapter->device_mode),
7998 pAdapter->device_mode);
7999
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308000 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8001 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308002 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008003 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308004 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008005 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308006
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308007 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008008 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308009 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008010 {
8011 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308012
Jeff Johnson295189b2012-06-20 16:38:30 -07008013 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308014
Jeff Johnson295189b2012-06-20 16:38:30 -07008015 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308016 {
8017 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8018 FL("session(%d) old and new heads points to NULL"),
8019 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008020 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308021 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008022
8023 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
8024
8025 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308026 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008027 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008028 return -EINVAL;
8029 }
8030
8031 pAdapter->sessionCtx.ap.beacon = new;
8032
8033 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
8034 }
8035
8036 EXIT();
8037 return status;
8038}
8039
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308040static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
8041 struct net_device *dev,
8042 struct beacon_parameters *params)
8043{
8044 int ret;
8045
8046 vos_ssr_protect(__func__);
8047 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
8048 vos_ssr_unprotect(__func__);
8049
8050 return ret;
8051}
8052
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008053#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8054
8055#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308056static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008057 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008058#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308059static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008060 struct net_device *dev)
8061#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008062{
8063 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07008064 hdd_context_t *pHddCtx = NULL;
8065 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308066 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308067 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008068
8069 ENTER();
8070
8071 if (NULL == pAdapter)
8072 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008074 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008075 return -ENODEV;
8076 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008077
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308078 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8079 TRACE_CODE_HDD_CFG80211_STOP_AP,
8080 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308081 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8082 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308083 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008084 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308085 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07008086 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008087
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008088 pScanInfo = &pHddCtx->scan_info;
8089
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308090 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8091 __func__, hdd_device_modetoString(pAdapter->device_mode),
8092 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008093
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308094 ret = wlan_hdd_scan_abort(pAdapter);
8095
Girish Gowli4bf7a632014-06-12 13:42:11 +05308096 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07008097 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8099 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308100
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308101 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07008102 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8104 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08008105
Jeff Johnsone7245742012-09-05 17:12:55 -07008106 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308107 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07008108 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308109 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008110 }
8111
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05308112 /* Delete all associated STAs before stopping AP/P2P GO */
8113 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05308114 hdd_hostapd_stop(dev);
8115
Jeff Johnson295189b2012-06-20 16:38:30 -07008116 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008117 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008118 )
8119 {
8120 beacon_data_t *old;
8121
8122 old = pAdapter->sessionCtx.ap.beacon;
8123
8124 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308125 {
8126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8127 FL("session(%d) beacon data points to NULL"),
8128 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008129 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308130 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008131
Jeff Johnson295189b2012-06-20 16:38:30 -07008132 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008133
8134 mutex_lock(&pHddCtx->sap_lock);
8135 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8136 {
Jeff Johnson4416a782013-03-25 14:17:50 -07008137 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008138 {
8139 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8140
8141 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
8142
8143 if (!VOS_IS_STATUS_SUCCESS(status))
8144 {
8145 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008146 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008147 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308148 }
8149 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008150 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05308151 /* BSS stopped, clear the active sessions for this device mode */
8152 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008153 }
8154 mutex_unlock(&pHddCtx->sap_lock);
8155
8156 if(status != VOS_STATUS_SUCCESS)
8157 {
8158 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008159 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008160 return -EINVAL;
8161 }
8162
Jeff Johnson4416a782013-03-25 14:17:50 -07008163 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07008164 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
8165 ==eHAL_STATUS_FAILURE)
8166 {
8167 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008168 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008169 }
8170
Jeff Johnson4416a782013-03-25 14:17:50 -07008171 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07008172 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8173 eANI_BOOLEAN_FALSE) )
8174 {
8175 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008176 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008177 }
8178
8179 // Reset WNI_CFG_PROBE_RSP Flags
8180 wlan_hdd_reset_prob_rspies(pAdapter);
8181
8182 pAdapter->sessionCtx.ap.beacon = NULL;
8183 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008184#ifdef WLAN_FEATURE_P2P_DEBUG
8185 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
8186 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
8187 {
8188 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
8189 "GO got removed");
8190 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
8191 }
8192#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008193 }
8194 EXIT();
8195 return status;
8196}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008197
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308198#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8199static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
8200 struct net_device *dev)
8201{
8202 int ret;
8203
8204 vos_ssr_protect(__func__);
8205 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
8206 vos_ssr_unprotect(__func__);
8207
8208 return ret;
8209}
8210#else
8211static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
8212 struct net_device *dev)
8213{
8214 int ret;
8215
8216 vos_ssr_protect(__func__);
8217 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
8218 vos_ssr_unprotect(__func__);
8219
8220 return ret;
8221}
8222#endif
8223
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008224#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
8225
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308226static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308227 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008228 struct cfg80211_ap_settings *params)
8229{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308230 hdd_adapter_t *pAdapter;
8231 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308232 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008233
8234 ENTER();
8235
Girish Gowlib143d7a2015-02-18 19:39:55 +05308236 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008237 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05308239 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308240 return -ENODEV;
8241 }
8242
8243 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8244 if (NULL == pAdapter)
8245 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308246 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308247 "%s: HDD adapter is Null", __func__);
8248 return -ENODEV;
8249 }
8250
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308251 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8252 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
8253 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308254 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8255 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308257 "%s: HDD adapter magic is invalid", __func__);
8258 return -ENODEV;
8259 }
8260
8261 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308262 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308263 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308264 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308265 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308266 }
8267
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308268 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
8269 __func__, hdd_device_modetoString(pAdapter->device_mode),
8270 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308271
8272 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008273 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008274 )
8275 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308276 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008277
8278 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308279
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008280 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308281 {
8282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8283 FL("already beacon info added to session(%d)"),
8284 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008285 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308286 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008287
Girish Gowlib143d7a2015-02-18 19:39:55 +05308288#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8289 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
8290 &new,
8291 &params->beacon);
8292#else
8293 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
8294 &new,
8295 &params->beacon,
8296 params->dtim_period);
8297#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008298
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308299 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008300 {
8301 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308302 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008303 return -EINVAL;
8304 }
8305 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08008306#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07008307 wlan_hdd_cfg80211_set_channel(wiphy, dev,
8308#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
8309 params->channel, params->channel_type);
8310#else
8311 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
8312#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08008313#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008314 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308315 params->ssid_len, params->hidden_ssid,
8316 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008317 }
8318
8319 EXIT();
8320 return status;
8321}
8322
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308323static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
8324 struct net_device *dev,
8325 struct cfg80211_ap_settings *params)
8326{
8327 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008328
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308329 vos_ssr_protect(__func__);
8330 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
8331 vos_ssr_unprotect(__func__);
8332
8333 return ret;
8334}
8335
8336static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008337 struct net_device *dev,
8338 struct cfg80211_beacon_data *params)
8339{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308340 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308341 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308342 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008343
8344 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308345
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308346 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8347 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
8348 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08008349 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008350 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308351
8352 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8353 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308354 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008355 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308356 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008357 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008358
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308359 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008360 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308361 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008362 {
8363 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308364
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008365 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308366
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008367 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308368 {
8369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8370 FL("session(%d) beacon data points to NULL"),
8371 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008372 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308373 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008374
8375 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
8376
8377 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308378 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008379 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008380 return -EINVAL;
8381 }
8382
8383 pAdapter->sessionCtx.ap.beacon = new;
8384
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308385 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
8386 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008387 }
8388
8389 EXIT();
8390 return status;
8391}
8392
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308393static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8394 struct net_device *dev,
8395 struct cfg80211_beacon_data *params)
8396{
8397 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008398
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308399 vos_ssr_protect(__func__);
8400 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8401 vos_ssr_unprotect(__func__);
8402
8403 return ret;
8404}
8405
8406#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008407
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308408static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008409 struct net_device *dev,
8410 struct bss_parameters *params)
8411{
8412 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308413 hdd_context_t *pHddCtx;
8414 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008415
8416 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308417
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308418 if (NULL == pAdapter)
8419 {
8420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8421 "%s: HDD adapter is Null", __func__);
8422 return -ENODEV;
8423 }
8424 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308425 ret = wlan_hdd_validate_context(pHddCtx);
8426 if (0 != ret)
8427 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308428 return ret;
8429 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308430 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8431 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
8432 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308433 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8434 __func__, hdd_device_modetoString(pAdapter->device_mode),
8435 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008436
8437 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008438 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308439 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008440 {
8441 /* ap_isolate == -1 means that in change bss, upper layer doesn't
8442 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308443 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07008444 {
8445 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308446 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008447 }
8448
8449 EXIT();
8450 return 0;
8451}
8452
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308453static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
8454 struct net_device *dev,
8455 struct bss_parameters *params)
8456{
8457 int ret;
8458
8459 vos_ssr_protect(__func__);
8460 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
8461 vos_ssr_unprotect(__func__);
8462
8463 return ret;
8464}
Kiet Lam10841362013-11-01 11:36:50 +05308465/* FUNCTION: wlan_hdd_change_country_code_cd
8466* to wait for contry code completion
8467*/
8468void* wlan_hdd_change_country_code_cb(void *pAdapter)
8469{
8470 hdd_adapter_t *call_back_pAdapter = pAdapter;
8471 complete(&call_back_pAdapter->change_country_code);
8472 return NULL;
8473}
8474
Jeff Johnson295189b2012-06-20 16:38:30 -07008475/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308476 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07008477 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
8478 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308479int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008480 struct net_device *ndev,
8481 enum nl80211_iftype type,
8482 u32 *flags,
8483 struct vif_params *params
8484 )
8485{
8486 struct wireless_dev *wdev;
8487 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008488 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07008489 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008490 tCsrRoamProfile *pRoamProfile = NULL;
8491 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308492 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008493 eMib_dot11DesiredBssType connectedBssType;
8494 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308495 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008496
8497 ENTER();
8498
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308499 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008500 {
8501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8502 "%s: Adapter context is null", __func__);
8503 return VOS_STATUS_E_FAILURE;
8504 }
8505
8506 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8507 if (!pHddCtx)
8508 {
8509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8510 "%s: HDD context is null", __func__);
8511 return VOS_STATUS_E_FAILURE;
8512 }
8513
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308514 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8515 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
8516 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308517 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308518 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07008519 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308520 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008521 }
8522
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308523 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8524 __func__, hdd_device_modetoString(pAdapter->device_mode),
8525 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008526
Agarwal Ashish51325b52014-06-16 16:50:49 +05308527 if (vos_max_concurrent_connections_reached()) {
8528 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8529 return -EINVAL;
8530 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308531 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07008532 wdev = ndev->ieee80211_ptr;
8533
8534#ifdef WLAN_BTAMP_FEATURE
8535 if((NL80211_IFTYPE_P2P_CLIENT == type)||
8536 (NL80211_IFTYPE_ADHOC == type)||
8537 (NL80211_IFTYPE_AP == type)||
8538 (NL80211_IFTYPE_P2P_GO == type))
8539 {
8540 pHddCtx->isAmpAllowed = VOS_FALSE;
8541 // stop AMP traffic
8542 status = WLANBAP_StopAmp();
8543 if(VOS_STATUS_SUCCESS != status )
8544 {
8545 pHddCtx->isAmpAllowed = VOS_TRUE;
8546 hddLog(VOS_TRACE_LEVEL_FATAL,
8547 "%s: Failed to stop AMP", __func__);
8548 return -EINVAL;
8549 }
8550 }
8551#endif //WLAN_BTAMP_FEATURE
8552 /* Reset the current device mode bit mask*/
8553 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8554
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +05308555 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
8556 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
8557 (type == NL80211_IFTYPE_P2P_GO)))
8558 {
8559 /* Notify Mode change in case of concurrency.
8560 * Below function invokes TDLS teardown Functionality Since TDLS is
8561 * not Supported in case of concurrency i.e Once P2P session
8562 * is detected disable offchannel and teardown TDLS links
8563 */
8564 hddLog(LOG1,
8565 FL("Device mode = %d Interface type = %d"),
8566 pAdapter->device_mode, type);
8567 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
8568 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +05308569
Jeff Johnson295189b2012-06-20 16:38:30 -07008570 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008571 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07008572 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008573 )
8574 {
8575 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008576 if (!pWextState)
8577 {
8578 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8579 "%s: pWextState is null", __func__);
8580 return VOS_STATUS_E_FAILURE;
8581 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008582 pRoamProfile = &pWextState->roamProfile;
8583 LastBSSType = pRoamProfile->BSSType;
8584
8585 switch (type)
8586 {
8587 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008588 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008589 hddLog(VOS_TRACE_LEVEL_INFO,
8590 "%s: setting interface Type to INFRASTRUCTURE", __func__);
8591 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008592#ifdef WLAN_FEATURE_11AC
8593 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
8594 {
8595 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
8596 }
8597#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308598 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07008599 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008600 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008601 //Check for sub-string p2p to confirm its a p2p interface
8602 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308603 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +05308604#ifdef FEATURE_WLAN_TDLS
8605 mutex_lock(&pHddCtx->tdls_lock);
8606 wlan_hdd_tdls_exit(pAdapter, TRUE);
8607 mutex_unlock(&pHddCtx->tdls_lock);
8608#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008609 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8610 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8611 }
8612 else
8613 {
8614 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008615 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008616 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008617 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05308618
Jeff Johnson295189b2012-06-20 16:38:30 -07008619 case NL80211_IFTYPE_ADHOC:
8620 hddLog(VOS_TRACE_LEVEL_INFO,
8621 "%s: setting interface Type to ADHOC", __func__);
8622 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
8623 pRoamProfile->phyMode =
8624 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07008625 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008626 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05308627 hdd_set_ibss_ops( pAdapter );
8628 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +05308629
8630 status = hdd_sta_id_hash_attach(pAdapter);
8631 if (VOS_STATUS_SUCCESS != status) {
8632 hddLog(VOS_TRACE_LEVEL_ERROR,
8633 FL("Failed to initialize hash for IBSS"));
8634 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008635 break;
8636
8637 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008638 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008639 {
8640 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8641 "%s: setting interface Type to %s", __func__,
8642 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
8643
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008644 //Cancel any remain on channel for GO mode
8645 if (NL80211_IFTYPE_P2P_GO == type)
8646 {
8647 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
8648 }
Mohit Khanna0f232092012-09-11 14:46:08 -07008649 if (NL80211_IFTYPE_AP == type)
8650 {
8651 /* As Loading WLAN Driver one interface being created for p2p device
8652 * address. This will take one HW STA and the max number of clients
8653 * that can connect to softAP will be reduced by one. so while changing
8654 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
8655 * interface as it is not required in SoftAP mode.
8656 */
8657
8658 // Get P2P Adapter
8659 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
8660
8661 if (pP2pAdapter)
8662 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308663 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05308664 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07008665 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
8666 }
8667 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05308668 //Disable IMPS & BMPS for SAP/GO
8669 if(VOS_STATUS_E_FAILURE ==
8670 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
8671 {
8672 //Fail to Exit BMPS
8673 VOS_ASSERT(0);
8674 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05308675
8676 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
8677
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308678#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07008679
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308680 /* A Mutex Lock is introduced while changing the mode to
8681 * protect the concurrent access for the Adapters by TDLS
8682 * module.
8683 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308684 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308685#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008686 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05308687 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008688 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07008689 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8690 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308691#ifdef FEATURE_WLAN_TDLS
8692 mutex_unlock(&pHddCtx->tdls_lock);
8693#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008694 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
8695 (pConfig->apRandomBssidEnabled))
8696 {
8697 /* To meet Android requirements create a randomized
8698 MAC address of the form 02:1A:11:Fx:xx:xx */
8699 get_random_bytes(&ndev->dev_addr[3], 3);
8700 ndev->dev_addr[0] = 0x02;
8701 ndev->dev_addr[1] = 0x1A;
8702 ndev->dev_addr[2] = 0x11;
8703 ndev->dev_addr[3] |= 0xF0;
8704 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
8705 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08008706 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
8707 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008708 }
8709
Jeff Johnson295189b2012-06-20 16:38:30 -07008710 hdd_set_ap_ops( pAdapter->dev );
8711
Kiet Lam10841362013-11-01 11:36:50 +05308712 /* This is for only SAP mode where users can
8713 * control country through ini.
8714 * P2P GO follows station country code
8715 * acquired during the STA scanning. */
8716 if((NL80211_IFTYPE_AP == type) &&
8717 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
8718 {
8719 int status = 0;
8720 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
8721 "%s: setting country code from INI ", __func__);
8722 init_completion(&pAdapter->change_country_code);
8723 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
8724 (void *)(tSmeChangeCountryCallback)
8725 wlan_hdd_change_country_code_cb,
8726 pConfig->apCntryCode, pAdapter,
8727 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308728 eSIR_FALSE,
8729 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05308730 if (eHAL_STATUS_SUCCESS == status)
8731 {
8732 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308733 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05308734 &pAdapter->change_country_code,
8735 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308736 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05308737 {
8738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308739 FL("SME Timed out while setting country code %ld"),
8740 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08008741
8742 if (pHddCtx->isLogpInProgress)
8743 {
8744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8745 "%s: LOGP in Progress. Ignore!!!", __func__);
8746 return -EAGAIN;
8747 }
Kiet Lam10841362013-11-01 11:36:50 +05308748 }
8749 }
8750 else
8751 {
8752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008753 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05308754 return -EINVAL;
8755 }
8756 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008757 status = hdd_init_ap_mode(pAdapter);
8758 if(status != VOS_STATUS_SUCCESS)
8759 {
8760 hddLog(VOS_TRACE_LEVEL_FATAL,
8761 "%s: Error initializing the ap mode", __func__);
8762 return -EINVAL;
8763 }
8764 hdd_set_conparam(1);
8765
Nirav Shah7e3c8132015-06-22 23:51:42 +05308766 status = hdd_sta_id_hash_attach(pAdapter);
8767 if (VOS_STATUS_SUCCESS != status)
8768 {
8769 hddLog(VOS_TRACE_LEVEL_ERROR,
8770 FL("Failed to initialize hash for AP"));
8771 return -EINVAL;
8772 }
8773
Jeff Johnson295189b2012-06-20 16:38:30 -07008774 /*interface type changed update in wiphy structure*/
8775 if(wdev)
8776 {
8777 wdev->iftype = type;
8778 pHddCtx->change_iface = type;
8779 }
8780 else
8781 {
8782 hddLog(VOS_TRACE_LEVEL_ERROR,
8783 "%s: ERROR !!!! Wireless dev is NULL", __func__);
8784 return -EINVAL;
8785 }
8786 goto done;
8787 }
8788
8789 default:
8790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8791 __func__);
8792 return -EOPNOTSUPP;
8793 }
8794 }
8795 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008796 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008797 )
8798 {
8799 switch(type)
8800 {
8801 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008802 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008803 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05308804
8805 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308806#ifdef FEATURE_WLAN_TDLS
8807
8808 /* A Mutex Lock is introduced while changing the mode to
8809 * protect the concurrent access for the Adapters by TDLS
8810 * module.
8811 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308812 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308813#endif
c_hpothu002231a2015-02-05 14:58:51 +05308814 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008815 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008816 //Check for sub-string p2p to confirm its a p2p interface
8817 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008818 {
8819 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8820 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8821 }
8822 else
8823 {
8824 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008825 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008826 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008827 hdd_set_conparam(0);
8828 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008829 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
8830 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308831#ifdef FEATURE_WLAN_TDLS
8832 mutex_unlock(&pHddCtx->tdls_lock);
8833#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308834 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008835 if( VOS_STATUS_SUCCESS != status )
8836 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07008837 /* In case of JB, for P2P-GO, only change interface will be called,
8838 * This is the right place to enable back bmps_imps()
8839 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308840 if (pHddCtx->hdd_wlan_suspended)
8841 {
8842 hdd_set_pwrparams(pHddCtx);
8843 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008844 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008845 goto done;
8846 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008847 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008848 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008849 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8850 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008851 goto done;
8852 default:
8853 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8854 __func__);
8855 return -EOPNOTSUPP;
8856
8857 }
8858
8859 }
8860 else
8861 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308862 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
8863 __func__, hdd_device_modetoString(pAdapter->device_mode),
8864 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008865 return -EOPNOTSUPP;
8866 }
8867
8868
8869 if(pRoamProfile)
8870 {
8871 if ( LastBSSType != pRoamProfile->BSSType )
8872 {
8873 /*interface type changed update in wiphy structure*/
8874 wdev->iftype = type;
8875
8876 /*the BSS mode changed, We need to issue disconnect
8877 if connected or in IBSS disconnect state*/
8878 if ( hdd_connGetConnectedBssType(
8879 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
8880 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
8881 {
8882 /*need to issue a disconnect to CSR.*/
8883 INIT_COMPLETION(pAdapter->disconnect_comp_var);
8884 if( eHAL_STATUS_SUCCESS ==
8885 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
8886 pAdapter->sessionId,
8887 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
8888 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308889 ret = wait_for_completion_interruptible_timeout(
8890 &pAdapter->disconnect_comp_var,
8891 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
8892 if (ret <= 0)
8893 {
8894 hddLog(VOS_TRACE_LEVEL_ERROR,
8895 FL("wait on disconnect_comp_var failed %ld"), ret);
8896 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008897 }
8898 }
8899 }
8900 }
8901
8902done:
8903 /*set bitmask based on updated value*/
8904 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07008905
8906 /* Only STA mode support TM now
8907 * all other mode, TM feature should be disabled */
8908 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
8909 (~VOS_STA & pHddCtx->concurrency_mode) )
8910 {
8911 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
8912 }
8913
Jeff Johnson295189b2012-06-20 16:38:30 -07008914#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308915 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05308916 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07008917 {
8918 //we are ok to do AMP
8919 pHddCtx->isAmpAllowed = VOS_TRUE;
8920 }
8921#endif //WLAN_BTAMP_FEATURE
8922 EXIT();
8923 return 0;
8924}
8925
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308926/*
8927 * FUNCTION: wlan_hdd_cfg80211_change_iface
8928 * wrapper function to protect the actual implementation from SSR.
8929 */
8930int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
8931 struct net_device *ndev,
8932 enum nl80211_iftype type,
8933 u32 *flags,
8934 struct vif_params *params
8935 )
8936{
8937 int ret;
8938
8939 vos_ssr_protect(__func__);
8940 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
8941 vos_ssr_unprotect(__func__);
8942
8943 return ret;
8944}
8945
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008946#ifdef FEATURE_WLAN_TDLS
8947static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308948 struct net_device *dev,
8949#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
8950 const u8 *mac,
8951#else
8952 u8 *mac,
8953#endif
8954 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008955{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008956 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008957 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308958 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308959 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308960 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05308961 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008962
8963 ENTER();
8964
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308965 if (!dev) {
8966 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
8967 return -EINVAL;
8968 }
8969
8970 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8971 if (!pAdapter) {
8972 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
8973 return -EINVAL;
8974 }
8975
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308976 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008977 {
8978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8979 "Invalid arguments");
8980 return -EINVAL;
8981 }
Hoonki Lee27511902013-03-14 18:19:06 -07008982
8983 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
8984 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
8985 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308986 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07008987 "%s: TDLS mode is disabled OR not enabled in FW."
8988 MAC_ADDRESS_STR " Request declined.",
8989 __func__, MAC_ADDR_ARRAY(mac));
8990 return -ENOTSUPP;
8991 }
8992
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008993 if (pHddCtx->isLogpInProgress)
8994 {
8995 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8996 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05308997 wlan_hdd_tdls_set_link_status(pAdapter,
8998 mac,
8999 eTDLS_LINK_IDLE,
9000 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009001 return -EBUSY;
9002 }
9003
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309004 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05309005 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009006
9007 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309008 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009009 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
9010 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309011 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009012 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009013 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309014 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009015
9016 /* in add station, we accept existing valid staId if there is */
9017 if ((0 == update) &&
9018 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
9019 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009020 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309021 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009022 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009023 " link_status %d. staId %d. add station ignored.",
9024 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
9025 return 0;
9026 }
9027 /* in change station, we accept only when staId is valid */
9028 if ((1 == update) &&
9029 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
9030 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
9031 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309032 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009033 "%s: " MAC_ADDRESS_STR
9034 " link status %d. staId %d. change station %s.",
9035 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
9036 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
9037 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009038 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009039
9040 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05309041 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009042 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9044 "%s: " MAC_ADDRESS_STR
9045 " TDLS setup is ongoing. Request declined.",
9046 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07009047 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009048 }
9049
9050 /* first to check if we reached to maximum supported TDLS peer.
9051 TODO: for now, return -EPERM looks working fine,
9052 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309053 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
9054 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009055 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9057 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309058 " TDLS Max peer already connected. Request declined."
9059 " Num of peers (%d), Max allowed (%d).",
9060 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
9061 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009062 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009063 }
9064 else
9065 {
9066 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309067 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009068 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009069 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9071 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
9072 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009073 return -EPERM;
9074 }
9075 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009076 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05309077 wlan_hdd_tdls_set_link_status(pAdapter,
9078 mac,
9079 eTDLS_LINK_CONNECTING,
9080 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009081
Jeff Johnsond75fe012013-04-06 10:53:06 -07009082 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309083 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009084 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009086 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07009087 if(StaParams->htcap_present)
9088 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009090 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309091 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009092 "ht_capa->extended_capabilities: %0x",
9093 StaParams->HTCap.extendedHtCapInfo);
9094 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009096 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009098 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07009099 if(StaParams->vhtcap_present)
9100 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309101 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009102 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
9103 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
9104 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
9105 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009106 {
9107 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009109 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009111 "[%d]: %x ", i, StaParams->supported_rates[i]);
9112 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07009113 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309114 else if ((1 == update) && (NULL == StaParams))
9115 {
9116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9117 "%s : update is true, but staParams is NULL. Error!", __func__);
9118 return -EPERM;
9119 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009120
9121 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
9122
9123 if (!update)
9124 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309125 /*Before adding sta make sure that device exited from BMPS*/
9126 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
9127 {
9128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9129 "%s: Adding tdls peer sta. Disable BMPS", __func__);
9130 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
9131 if (status != VOS_STATUS_SUCCESS) {
9132 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
9133 }
9134 }
9135
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309136 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009137 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309138 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309139 hddLog(VOS_TRACE_LEVEL_ERROR,
9140 FL("Failed to add TDLS peer STA. Enable Bmps"));
9141 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309142 return -EPERM;
9143 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009144 }
9145 else
9146 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309147 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009148 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309149 if (ret != eHAL_STATUS_SUCCESS) {
9150 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
9151 return -EPERM;
9152 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009153 }
9154
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309155 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009156 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
9157
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309158 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009159 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009160 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309161 "%s: timeout waiting for tdls add station indication %ld",
9162 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009163 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009164 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309165
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009166 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
9167 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009169 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009170 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009171 }
9172
9173 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07009174
9175error:
Atul Mittal115287b2014-07-08 13:26:33 +05309176 wlan_hdd_tdls_set_link_status(pAdapter,
9177 mac,
9178 eTDLS_LINK_IDLE,
9179 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009180 return -EPERM;
9181
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009182}
9183#endif
9184
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309185static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009186 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309187#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9188 const u8 *mac,
9189#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009190 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309191#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009192 struct station_parameters *params)
9193{
9194 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309195 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309196 hdd_context_t *pHddCtx;
9197 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009198 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309199 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009200#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009201 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009202 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309203 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009204#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009205
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309206 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309207
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309208 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05309209 if ((NULL == pAdapter))
9210 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309212 "invalid adapter ");
9213 return -EINVAL;
9214 }
9215
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309216 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9217 TRACE_CODE_HDD_CHANGE_STATION,
9218 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05309219 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05309220
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309221 ret = wlan_hdd_validate_context(pHddCtx);
9222 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05309223 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309224 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309225 }
9226
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309227 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9228
9229 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009230 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9232 "invalid HDD station context");
9233 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009234 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009235 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
9236
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009237 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
9238 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07009239 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009240 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07009241 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309242 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07009243 WLANTL_STA_AUTHENTICATED);
9244
Gopichand Nakkala29149562013-05-10 21:43:41 +05309245 if (status != VOS_STATUS_SUCCESS)
9246 {
9247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9248 "%s: Not able to change TL state to AUTHENTICATED", __func__);
9249 return -EINVAL;
9250 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009251 }
9252 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07009253 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
9254 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309255#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009256 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
9257 StaParams.capability = params->capability;
9258 StaParams.uapsd_queues = params->uapsd_queues;
9259 StaParams.max_sp = params->max_sp;
9260
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309261 /* Convert (first channel , number of channels) tuple to
9262 * the total list of channels. This goes with the assumption
9263 * that if the first channel is < 14, then the next channels
9264 * are an incremental of 1 else an incremental of 4 till the number
9265 * of channels.
9266 */
9267 if (0 != params->supported_channels_len) {
9268 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
9269 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
9270 {
9271 int wifi_chan_index;
9272 StaParams.supported_channels[j] = params->supported_channels[i];
9273 wifi_chan_index =
9274 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
9275 no_of_channels = params->supported_channels[i+1];
9276 for(k=1; k <= no_of_channels; k++)
9277 {
9278 StaParams.supported_channels[j+1] =
9279 StaParams.supported_channels[j] + wifi_chan_index;
9280 j+=1;
9281 }
9282 }
9283 StaParams.supported_channels_len = j;
9284 }
9285 vos_mem_copy(StaParams.supported_oper_classes,
9286 params->supported_oper_classes,
9287 params->supported_oper_classes_len);
9288 StaParams.supported_oper_classes_len =
9289 params->supported_oper_classes_len;
9290
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009291 if (0 != params->ext_capab_len)
9292 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
9293 sizeof(StaParams.extn_capability));
9294
9295 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07009296 {
9297 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009298 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07009299 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009300
9301 StaParams.supported_rates_len = params->supported_rates_len;
9302
9303 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
9304 * The supported_rates array , for all the structures propogating till Add Sta
9305 * to the firmware has to be modified , if the supplicant (ieee80211) is
9306 * modified to send more rates.
9307 */
9308
9309 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
9310 */
9311 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
9312 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
9313
9314 if (0 != StaParams.supported_rates_len) {
9315 int i = 0;
9316 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
9317 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009319 "Supported Rates with Length %d", StaParams.supported_rates_len);
9320 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009322 "[%d]: %0x", i, StaParams.supported_rates[i]);
9323 }
9324
9325 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07009326 {
9327 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009328 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07009329 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009330
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009331 if (0 != params->ext_capab_len ) {
9332 /*Define A Macro : TODO Sunil*/
9333 if ((1<<4) & StaParams.extn_capability[3]) {
9334 isBufSta = 1;
9335 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309336 /* TDLS Channel Switching Support */
9337 if ((1<<6) & StaParams.extn_capability[3]) {
9338 isOffChannelSupported = 1;
9339 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009340 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309341 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
9342 &StaParams, isBufSta,
9343 isOffChannelSupported);
9344
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309345 if (VOS_STATUS_SUCCESS != status) {
9346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9347 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
9348 return -EINVAL;
9349 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009350 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
9351
9352 if (VOS_STATUS_SUCCESS != status) {
9353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9354 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
9355 return -EINVAL;
9356 }
9357 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009358#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05309359 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009360 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009361 return status;
9362}
9363
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309364#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
9365static int wlan_hdd_change_station(struct wiphy *wiphy,
9366 struct net_device *dev,
9367 const u8 *mac,
9368 struct station_parameters *params)
9369#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309370static int wlan_hdd_change_station(struct wiphy *wiphy,
9371 struct net_device *dev,
9372 u8 *mac,
9373 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309374#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309375{
9376 int ret;
9377
9378 vos_ssr_protect(__func__);
9379 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
9380 vos_ssr_unprotect(__func__);
9381
9382 return ret;
9383}
9384
Jeff Johnson295189b2012-06-20 16:38:30 -07009385/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309386 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009387 * This function is used to initialize the key information
9388 */
9389#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309390static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009391 struct net_device *ndev,
9392 u8 key_index, bool pairwise,
9393 const u8 *mac_addr,
9394 struct key_params *params
9395 )
9396#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309397static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009398 struct net_device *ndev,
9399 u8 key_index, const u8 *mac_addr,
9400 struct key_params *params
9401 )
9402#endif
9403{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009404 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07009405 tCsrRoamSetKey setKey;
9406 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309407 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009408 v_U32_t roamId= 0xFF;
9409 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009410 hdd_hostapd_state_t *pHostapdState;
9411 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009412 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309413 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009414
9415 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309416
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309417 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9418 TRACE_CODE_HDD_CFG80211_ADD_KEY,
9419 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309420 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9421 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309422 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009423 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309424 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009425 }
9426
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309427 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9428 __func__, hdd_device_modetoString(pAdapter->device_mode),
9429 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009430
9431 if (CSR_MAX_NUM_KEY <= key_index)
9432 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009433 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009434 key_index);
9435
9436 return -EINVAL;
9437 }
9438
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009439 if (CSR_MAX_KEY_LEN < params->key_len)
9440 {
9441 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
9442 params->key_len);
9443
9444 return -EINVAL;
9445 }
9446
9447 hddLog(VOS_TRACE_LEVEL_INFO,
9448 "%s: called with key index = %d & key length %d",
9449 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009450
9451 /*extract key idx, key len and key*/
9452 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9453 setKey.keyId = key_index;
9454 setKey.keyLength = params->key_len;
9455 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
9456
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009457 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009458 {
9459 case WLAN_CIPHER_SUITE_WEP40:
9460 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
9461 break;
9462
9463 case WLAN_CIPHER_SUITE_WEP104:
9464 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
9465 break;
9466
9467 case WLAN_CIPHER_SUITE_TKIP:
9468 {
9469 u8 *pKey = &setKey.Key[0];
9470 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
9471
9472 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
9473
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009474 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07009475
9476 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009477 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009478 |--------------|----------|----------|
9479 <---16bytes---><--8bytes--><--8bytes-->
9480
9481 */
9482 /*Sme expects the 32 bytes key to be in the below order
9483
9484 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009485 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009486 |--------------|----------|----------|
9487 <---16bytes---><--8bytes--><--8bytes-->
9488 */
9489 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009490 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07009491
9492 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009493 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009494
9495 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009496 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009497
9498
9499 break;
9500 }
9501
9502 case WLAN_CIPHER_SUITE_CCMP:
9503 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
9504 break;
9505
9506#ifdef FEATURE_WLAN_WAPI
9507 case WLAN_CIPHER_SUITE_SMS4:
9508 {
9509 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9510 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
9511 params->key, params->key_len);
9512 return 0;
9513 }
9514#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009515
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009516#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009517 case WLAN_CIPHER_SUITE_KRK:
9518 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
9519 break;
9520#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009521
9522#ifdef WLAN_FEATURE_11W
9523 case WLAN_CIPHER_SUITE_AES_CMAC:
9524 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07009525 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07009526#endif
9527
Jeff Johnson295189b2012-06-20 16:38:30 -07009528 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009529 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009530 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309531 status = -EOPNOTSUPP;
9532 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009533 }
9534
9535 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
9536 __func__, setKey.encType);
9537
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009538 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07009539#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9540 (!pairwise)
9541#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009542 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07009543#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009544 )
9545 {
9546 /* set group key*/
9547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9548 "%s- %d: setting Broadcast key",
9549 __func__, __LINE__);
9550 setKey.keyDirection = eSIR_RX_ONLY;
9551 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9552 }
9553 else
9554 {
9555 /* set pairwise key*/
9556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9557 "%s- %d: setting pairwise key",
9558 __func__, __LINE__);
9559 setKey.keyDirection = eSIR_TX_RX;
9560 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9561 }
9562 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
9563 {
9564 setKey.keyDirection = eSIR_TX_RX;
9565 /*Set the group key*/
9566 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9567 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07009568
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009569 if ( 0 != status )
9570 {
9571 hddLog(VOS_TRACE_LEVEL_ERROR,
9572 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309573 status = -EINVAL;
9574 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009575 }
9576 /*Save the keys here and call sme_RoamSetKey for setting
9577 the PTK after peer joins the IBSS network*/
9578 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
9579 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309580 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009581 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05309582 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
9583 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
9584 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009585 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009586 if( pHostapdState->bssState == BSS_START )
9587 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009588 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9589 vos_status = wlan_hdd_check_ula_done(pAdapter);
9590
9591 if ( vos_status != VOS_STATUS_SUCCESS )
9592 {
9593 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9594 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9595 __LINE__, vos_status );
9596
9597 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9598
9599 status = -EINVAL;
9600 goto end;
9601 }
9602
Jeff Johnson295189b2012-06-20 16:38:30 -07009603 status = WLANSAP_SetKeySta( pVosContext, &setKey);
9604
9605 if ( status != eHAL_STATUS_SUCCESS )
9606 {
9607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9608 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9609 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309610 status = -EINVAL;
9611 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009612 }
9613 }
9614
9615 /* Saving WEP keys */
9616 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
9617 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
9618 {
9619 //Save the wep key in ap context. Issue setkey after the BSS is started.
9620 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9621 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
9622 }
9623 else
9624 {
9625 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009626 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009627 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
9628 }
9629 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009630 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
9631 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009632 {
9633 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9634 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9635
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309636#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9637 if (!pairwise)
9638#else
9639 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9640#endif
9641 {
9642 /* set group key*/
9643 if (pHddStaCtx->roam_info.deferKeyComplete)
9644 {
9645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9646 "%s- %d: Perform Set key Complete",
9647 __func__, __LINE__);
9648 hdd_PerformRoamSetKeyComplete(pAdapter);
9649 }
9650 }
9651
Jeff Johnson295189b2012-06-20 16:38:30 -07009652 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
9653
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08009654 pWextState->roamProfile.Keys.defaultIndex = key_index;
9655
9656
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009657 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009658 params->key, params->key_len);
9659
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309660
Jeff Johnson295189b2012-06-20 16:38:30 -07009661 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9662
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309663 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009664 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309665 __func__, setKey.peerMac[0], setKey.peerMac[1],
9666 setKey.peerMac[2], setKey.peerMac[3],
9667 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009668 setKey.keyDirection);
9669
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009670 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +05309671
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009672 if ( vos_status != VOS_STATUS_SUCCESS )
9673 {
9674 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009675 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9676 __LINE__, vos_status );
9677
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009678 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009679
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009680 status = -EINVAL;
9681 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009682
9683 }
9684
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009685#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309686 /* The supplicant may attempt to set the PTK once pre-authentication
9687 is done. Save the key in the UMAC and include it in the ADD BSS
9688 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009689 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309690 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009691 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309692 hddLog(VOS_TRACE_LEVEL_INFO_MED,
9693 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309694 status = 0;
9695 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309696 }
9697 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
9698 {
9699 hddLog(VOS_TRACE_LEVEL_ERROR,
9700 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309701 status = -EINVAL;
9702 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009703 }
9704#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07009705
9706 /* issue set key request to SME*/
9707 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9708 pAdapter->sessionId, &setKey, &roamId );
9709
9710 if ( 0 != status )
9711 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309712 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009713 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
9714 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309715 status = -EINVAL;
9716 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009717 }
9718
9719
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309720 /* in case of IBSS as there was no information available about WEP keys during
9721 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07009722 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309723 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
9724 !( ( IW_AUTH_KEY_MGMT_802_1X
9725 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07009726 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
9727 )
9728 &&
9729 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
9730 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
9731 )
9732 )
9733 {
9734 setKey.keyDirection = eSIR_RX_ONLY;
9735 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9736
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309737 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009738 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309739 __func__, setKey.peerMac[0], setKey.peerMac[1],
9740 setKey.peerMac[2], setKey.peerMac[3],
9741 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009742 setKey.keyDirection);
9743
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309744 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009745 pAdapter->sessionId, &setKey, &roamId );
9746
9747 if ( 0 != status )
9748 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309749 hddLog(VOS_TRACE_LEVEL_ERROR,
9750 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009751 __func__, status);
9752 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309753 status = -EINVAL;
9754 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009755 }
9756 }
9757 }
9758
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309759end:
9760 /* Need to clear any trace of key value in the memory.
9761 * Thus zero out the memory even though it is local
9762 * variable.
9763 */
9764 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309765 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309766 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009767}
9768
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309769#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9770static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9771 struct net_device *ndev,
9772 u8 key_index, bool pairwise,
9773 const u8 *mac_addr,
9774 struct key_params *params
9775 )
9776#else
9777static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9778 struct net_device *ndev,
9779 u8 key_index, const u8 *mac_addr,
9780 struct key_params *params
9781 )
9782#endif
9783{
9784 int ret;
9785 vos_ssr_protect(__func__);
9786#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9787 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
9788 mac_addr, params);
9789#else
9790 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
9791 params);
9792#endif
9793 vos_ssr_unprotect(__func__);
9794
9795 return ret;
9796}
9797
Jeff Johnson295189b2012-06-20 16:38:30 -07009798/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309799 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009800 * This function is used to get the key information
9801 */
9802#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309803static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309804 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009805 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309806 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009807 const u8 *mac_addr, void *cookie,
9808 void (*callback)(void *cookie, struct key_params*)
9809 )
9810#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309811static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309812 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009813 struct net_device *ndev,
9814 u8 key_index, const u8 *mac_addr, void *cookie,
9815 void (*callback)(void *cookie, struct key_params*)
9816 )
9817#endif
9818{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309819 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309820 hdd_wext_state_t *pWextState = NULL;
9821 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009822 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309823 hdd_context_t *pHddCtx;
9824 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009825
9826 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309827
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309828 if (NULL == pAdapter)
9829 {
9830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9831 "%s: HDD adapter is Null", __func__);
9832 return -ENODEV;
9833 }
9834
9835 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9836 ret = wlan_hdd_validate_context(pHddCtx);
9837 if (0 != ret)
9838 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309839 return ret;
9840 }
9841
9842 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9843 pRoamProfile = &(pWextState->roamProfile);
9844
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309845 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9846 __func__, hdd_device_modetoString(pAdapter->device_mode),
9847 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309848
Jeff Johnson295189b2012-06-20 16:38:30 -07009849 memset(&params, 0, sizeof(params));
9850
9851 if (CSR_MAX_NUM_KEY <= key_index)
9852 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309853 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07009854 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309855 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009856
9857 switch(pRoamProfile->EncryptionType.encryptionType[0])
9858 {
9859 case eCSR_ENCRYPT_TYPE_NONE:
9860 params.cipher = IW_AUTH_CIPHER_NONE;
9861 break;
9862
9863 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
9864 case eCSR_ENCRYPT_TYPE_WEP40:
9865 params.cipher = WLAN_CIPHER_SUITE_WEP40;
9866 break;
9867
9868 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
9869 case eCSR_ENCRYPT_TYPE_WEP104:
9870 params.cipher = WLAN_CIPHER_SUITE_WEP104;
9871 break;
9872
9873 case eCSR_ENCRYPT_TYPE_TKIP:
9874 params.cipher = WLAN_CIPHER_SUITE_TKIP;
9875 break;
9876
9877 case eCSR_ENCRYPT_TYPE_AES:
9878 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
9879 break;
9880
9881 default:
9882 params.cipher = IW_AUTH_CIPHER_NONE;
9883 break;
9884 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309885
c_hpothuaaf19692014-05-17 17:01:48 +05309886 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9887 TRACE_CODE_HDD_CFG80211_GET_KEY,
9888 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309889
Jeff Johnson295189b2012-06-20 16:38:30 -07009890 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
9891 params.seq_len = 0;
9892 params.seq = NULL;
9893 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
9894 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309895 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009896 return 0;
9897}
9898
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309899#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9900static int wlan_hdd_cfg80211_get_key(
9901 struct wiphy *wiphy,
9902 struct net_device *ndev,
9903 u8 key_index, bool pairwise,
9904 const u8 *mac_addr, void *cookie,
9905 void (*callback)(void *cookie, struct key_params*)
9906 )
9907#else
9908static int wlan_hdd_cfg80211_get_key(
9909 struct wiphy *wiphy,
9910 struct net_device *ndev,
9911 u8 key_index, const u8 *mac_addr, void *cookie,
9912 void (*callback)(void *cookie, struct key_params*)
9913 )
9914#endif
9915{
9916 int ret;
9917
9918 vos_ssr_protect(__func__);
9919#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9920 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
9921 mac_addr, cookie, callback);
9922#else
9923 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
9924 callback);
9925#endif
9926 vos_ssr_unprotect(__func__);
9927
9928 return ret;
9929}
9930
Jeff Johnson295189b2012-06-20 16:38:30 -07009931/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309932 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009933 * This function is used to delete the key information
9934 */
9935#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309936static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009937 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309938 u8 key_index,
9939 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009940 const u8 *mac_addr
9941 )
9942#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309943static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009944 struct net_device *ndev,
9945 u8 key_index,
9946 const u8 *mac_addr
9947 )
9948#endif
9949{
9950 int status = 0;
9951
9952 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309953 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009954 //it is observed that this is invalidating peer
9955 //key index whenever re-key is done. This is affecting data link.
9956 //It should be ok to ignore del_key.
9957#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309958 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
9959 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009960 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
9961 tCsrRoamSetKey setKey;
9962 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309963
Jeff Johnson295189b2012-06-20 16:38:30 -07009964 ENTER();
9965
9966 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
9967 __func__,pAdapter->device_mode);
9968
9969 if (CSR_MAX_NUM_KEY <= key_index)
9970 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309971 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009972 key_index);
9973
9974 return -EINVAL;
9975 }
9976
9977 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9978 setKey.keyId = key_index;
9979
9980 if (mac_addr)
9981 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9982 else
9983 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
9984
9985 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
9986
9987 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009988 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309989 )
9990 {
9991
9992 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07009993 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9994 if( pHostapdState->bssState == BSS_START)
9995 {
9996 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309997
Jeff Johnson295189b2012-06-20 16:38:30 -07009998 if ( status != eHAL_STATUS_SUCCESS )
9999 {
10000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10001 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
10002 __LINE__, status );
10003 }
10004 }
10005 }
10006 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010007 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070010008 )
10009 {
10010 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10011
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010012 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
10013
10014 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070010015 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010016 __func__, setKey.peerMac[0], setKey.peerMac[1],
10017 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070010018 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010019 if(pAdapter->sessionCtx.station.conn_info.connState ==
10020 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070010021 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010022 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010023 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010024
Jeff Johnson295189b2012-06-20 16:38:30 -070010025 if ( 0 != status )
10026 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010027 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010028 "%s: sme_RoamSetKey failure, returned %d",
10029 __func__, status);
10030 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
10031 return -EINVAL;
10032 }
10033 }
10034 }
10035#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010036 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010037 return status;
10038}
10039
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010040#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10041static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
10042 struct net_device *ndev,
10043 u8 key_index,
10044 bool pairwise,
10045 const u8 *mac_addr
10046 )
10047#else
10048static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
10049 struct net_device *ndev,
10050 u8 key_index,
10051 const u8 *mac_addr
10052 )
10053#endif
10054{
10055 int ret;
10056
10057 vos_ssr_protect(__func__);
10058#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10059 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
10060 mac_addr);
10061#else
10062 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
10063#endif
10064 vos_ssr_unprotect(__func__);
10065
10066 return ret;
10067}
10068
Jeff Johnson295189b2012-06-20 16:38:30 -070010069/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010070 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010071 * This function is used to set the default tx key index
10072 */
10073#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010074static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010075 struct net_device *ndev,
10076 u8 key_index,
10077 bool unicast, bool multicast)
10078#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010079static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010080 struct net_device *ndev,
10081 u8 key_index)
10082#endif
10083{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010084 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010085 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010086 hdd_wext_state_t *pWextState;
10087 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010088 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010089
10090 ENTER();
10091
Gopichand Nakkala29149562013-05-10 21:43:41 +053010092 if ((NULL == pAdapter))
10093 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010094 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010095 "invalid adapter");
10096 return -EINVAL;
10097 }
10098
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010099 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10100 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
10101 pAdapter->sessionId, key_index));
10102
Gopichand Nakkala29149562013-05-10 21:43:41 +053010103 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10104 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10105
10106 if ((NULL == pWextState) || (NULL == pHddStaCtx))
10107 {
10108 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10109 "invalid Wext state or HDD context");
10110 return -EINVAL;
10111 }
10112
Arif Hussain6d2a3322013-11-17 19:50:10 -080010113 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010114 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010115
Jeff Johnson295189b2012-06-20 16:38:30 -070010116 if (CSR_MAX_NUM_KEY <= key_index)
10117 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010118 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010119 key_index);
10120
10121 return -EINVAL;
10122 }
10123
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010124 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10125 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010126 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010127 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010128 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010129 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010130
Jeff Johnson295189b2012-06-20 16:38:30 -070010131 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010132 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010133 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010134 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053010135 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080010136 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010137 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080010138 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070010139 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010140 {
10141 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070010142 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010143
Jeff Johnson295189b2012-06-20 16:38:30 -070010144 tCsrRoamSetKey setKey;
10145 v_U32_t roamId= 0xFF;
10146 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010147
10148 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010149 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010150
Jeff Johnson295189b2012-06-20 16:38:30 -070010151 Keys->defaultIndex = (u8)key_index;
10152 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10153 setKey.keyId = key_index;
10154 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010155
10156 vos_mem_copy(&setKey.Key[0],
10157 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010158 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010159
Gopichand Nakkala29149562013-05-10 21:43:41 +053010160 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010161
10162 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070010163 &pHddStaCtx->conn_info.bssId[0],
10164 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010165
Gopichand Nakkala29149562013-05-10 21:43:41 +053010166 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
10167 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
10168 eCSR_ENCRYPT_TYPE_WEP104)
10169 {
10170 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
10171 even though ap is configured for WEP-40 encryption. In this canse the key length
10172 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
10173 type(104) and switching encryption type to 40*/
10174 pWextState->roamProfile.EncryptionType.encryptionType[0] =
10175 eCSR_ENCRYPT_TYPE_WEP40;
10176 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
10177 eCSR_ENCRYPT_TYPE_WEP40;
10178 }
10179
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010180 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070010181 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010182
Jeff Johnson295189b2012-06-20 16:38:30 -070010183 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010184 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010185 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010186
Jeff Johnson295189b2012-06-20 16:38:30 -070010187 if ( 0 != status )
10188 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010189 hddLog(VOS_TRACE_LEVEL_ERROR,
10190 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010191 status);
10192 return -EINVAL;
10193 }
10194 }
10195 }
10196
10197 /* In SoftAp mode setting key direction for default mode */
10198 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
10199 {
10200 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
10201 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
10202 (eCSR_ENCRYPT_TYPE_AES !=
10203 pWextState->roamProfile.EncryptionType.encryptionType[0])
10204 )
10205 {
10206 /* Saving key direction for default key index to TX default */
10207 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
10208 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
10209 }
10210 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010211 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010212 return status;
10213}
10214
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010215#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10216static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
10217 struct net_device *ndev,
10218 u8 key_index,
10219 bool unicast, bool multicast)
10220#else
10221static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
10222 struct net_device *ndev,
10223 u8 key_index)
10224#endif
10225{
10226 int ret;
10227 vos_ssr_protect(__func__);
10228#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10229 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
10230 multicast);
10231#else
10232 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
10233#endif
10234 vos_ssr_unprotect(__func__);
10235
10236 return ret;
10237}
10238
Jeff Johnson295189b2012-06-20 16:38:30 -070010239/*
10240 * FUNCTION: wlan_hdd_cfg80211_inform_bss
10241 * This function is used to inform the BSS details to nl80211 interface.
10242 */
10243static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
10244 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
10245{
10246 struct net_device *dev = pAdapter->dev;
10247 struct wireless_dev *wdev = dev->ieee80211_ptr;
10248 struct wiphy *wiphy = wdev->wiphy;
10249 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
10250 int chan_no;
10251 int ie_length;
10252 const char *ie;
10253 unsigned int freq;
10254 struct ieee80211_channel *chan;
10255 int rssi = 0;
10256 struct cfg80211_bss *bss = NULL;
10257
Jeff Johnson295189b2012-06-20 16:38:30 -070010258 if( NULL == pBssDesc )
10259 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010260 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010261 return bss;
10262 }
10263
10264 chan_no = pBssDesc->channelId;
10265 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
10266 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
10267
10268 if( NULL == ie )
10269 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010270 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010271 return bss;
10272 }
10273
10274#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10275 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10276 {
10277 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10278 }
10279 else
10280 {
10281 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10282 }
10283#else
10284 freq = ieee80211_channel_to_frequency(chan_no);
10285#endif
10286
10287 chan = __ieee80211_get_channel(wiphy, freq);
10288
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053010289 if (!chan) {
10290 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
10291 return NULL;
10292 }
10293
Abhishek Singhaee43942014-06-16 18:55:47 +053010294 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070010295
Anand N Sunkad9f80b742015-07-30 20:05:51 +053010296 return cfg80211_inform_bss(wiphy, chan,
10297#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10298 CFG80211_BSS_FTYPE_UNKNOWN,
10299#endif
10300 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010301 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070010302 pBssDesc->capabilityInfo,
10303 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053010304 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070010305}
10306
10307
10308
10309/*
10310 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
10311 * This function is used to inform the BSS details to nl80211 interface.
10312 */
10313struct cfg80211_bss*
10314wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
10315 tSirBssDescription *bss_desc
10316 )
10317{
10318 /*
10319 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
10320 already exists in bss data base of cfg80211 for that particular BSS ID.
10321 Using cfg80211_inform_bss_frame to update the bss entry instead of
10322 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
10323 now there is no possibility to get the mgmt(probe response) frame from PE,
10324 converting bss_desc to ieee80211_mgmt(probe response) and passing to
10325 cfg80211_inform_bss_frame.
10326 */
10327 struct net_device *dev = pAdapter->dev;
10328 struct wireless_dev *wdev = dev->ieee80211_ptr;
10329 struct wiphy *wiphy = wdev->wiphy;
10330 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010331#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10332 qcom_ie_age *qie_age = NULL;
10333 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
10334#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010335 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010336#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010337 const char *ie =
10338 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
10339 unsigned int freq;
10340 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053010341 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010342 struct cfg80211_bss *bss_status = NULL;
10343 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
10344 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070010345 hdd_context_t *pHddCtx;
10346 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070010347#ifdef WLAN_OPEN_SOURCE
10348 struct timespec ts;
10349#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010350
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010351
Wilson Yangf80a0542013-10-07 13:02:37 -070010352 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10353 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070010354 if (0 != status)
10355 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010356 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010357 }
10358
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053010359 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070010360 if (!mgmt)
10361 {
10362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10363 "%s: memory allocation failed ", __func__);
10364 return NULL;
10365 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010366
Jeff Johnson295189b2012-06-20 16:38:30 -070010367 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010368
10369#ifdef WLAN_OPEN_SOURCE
10370 /* Android does not want the timestamp from the frame.
10371 Instead it wants a monotonic increasing value */
10372 get_monotonic_boottime(&ts);
10373 mgmt->u.probe_resp.timestamp =
10374 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
10375#else
10376 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010377 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
10378 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070010379
10380#endif
10381
Jeff Johnson295189b2012-06-20 16:38:30 -070010382 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
10383 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010384
10385#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10386 /* GPS Requirement: need age ie per entry. Using vendor specific. */
10387 /* Assuming this is the last IE, copy at the end */
10388 ie_length -=sizeof(qcom_ie_age);
10389 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
10390 qie_age->element_id = QCOM_VENDOR_IE_ID;
10391 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
10392 qie_age->oui_1 = QCOM_OUI1;
10393 qie_age->oui_2 = QCOM_OUI2;
10394 qie_age->oui_3 = QCOM_OUI3;
10395 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
10396 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
10397#endif
10398
Jeff Johnson295189b2012-06-20 16:38:30 -070010399 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053010400 if (bss_desc->fProbeRsp)
10401 {
10402 mgmt->frame_control |=
10403 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
10404 }
10405 else
10406 {
10407 mgmt->frame_control |=
10408 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
10409 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010410
10411#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010412 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010413 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
10414 {
10415 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10416 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010417 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010418 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
10419
10420 {
10421 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10422 }
10423 else
10424 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010425 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
10426 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070010427 kfree(mgmt);
10428 return NULL;
10429 }
10430#else
10431 freq = ieee80211_channel_to_frequency(chan_no);
10432#endif
10433 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010434 /*when the band is changed on the fly using the GUI, three things are done
10435 * 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)
10436 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
10437 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
10438 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
10439 * and discards the channels correponding to previous band and calls back with zero bss results.
10440 * 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
10441 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
10442 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
10443 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
10444 * So drop the bss and continue to next bss.
10445 */
10446 if(chan == NULL)
10447 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010448 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070010449 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010450 return NULL;
10451 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053010452 /*To keep the rssi icon of the connected AP in the scan window
10453 *and the rssi icon of the wireless networks in sync
10454 * */
10455 if (( eConnectionState_Associated ==
10456 pAdapter->sessionCtx.station.conn_info.connState ) &&
10457 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
10458 pAdapter->sessionCtx.station.conn_info.bssId,
10459 WNI_CFG_BSSID_LEN)) &&
10460 (pHddCtx->hdd_wlan_suspended == FALSE))
10461 {
10462 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
10463 rssi = (pAdapter->rssi * 100);
10464 }
10465 else
10466 {
10467 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
10468 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010469
Nirav Shah20ac06f2013-12-12 18:14:06 +053010470 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053010471 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
10472 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053010473
Jeff Johnson295189b2012-06-20 16:38:30 -070010474 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
10475 frame_len, rssi, GFP_KERNEL);
10476 kfree(mgmt);
10477 return bss_status;
10478}
10479
10480/*
10481 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
10482 * This function is used to update the BSS data base of CFG8011
10483 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010484struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010485 tCsrRoamInfo *pRoamInfo
10486 )
10487{
10488 tCsrRoamConnectedProfile roamProfile;
10489 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10490 struct cfg80211_bss *bss = NULL;
10491
10492 ENTER();
10493
10494 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
10495 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
10496
10497 if (NULL != roamProfile.pBssDesc)
10498 {
Girish Gowlif4b68022014-08-28 23:18:57 +053010499 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10500 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070010501
10502 if (NULL == bss)
10503 {
10504 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
10505 __func__);
10506 }
10507
10508 sme_RoamFreeConnectProfile(hHal, &roamProfile);
10509 }
10510 else
10511 {
10512 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
10513 __func__);
10514 }
10515 return bss;
10516}
10517
10518/*
10519 * FUNCTION: wlan_hdd_cfg80211_update_bss
10520 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010521static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
10522 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070010523 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010524{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010525 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010526 tCsrScanResultInfo *pScanResult;
10527 eHalStatus status = 0;
10528 tScanResultHandle pResult;
10529 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010530 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010531 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070010532 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010533
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010534 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10535 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
10536 NO_SESSION, pAdapter->sessionId));
10537
Wilson Yangf80a0542013-10-07 13:02:37 -070010538 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10539
10540 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070010541 {
Wilson Yangf80a0542013-10-07 13:02:37 -070010542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10543 "%s:LOGP in Progress. Ignore!!!",__func__);
10544 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010545 }
10546
Wilson Yangf80a0542013-10-07 13:02:37 -070010547
10548 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053010549 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070010550 {
10551 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10552 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
10553 return VOS_STATUS_E_PERM;
10554 }
10555
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010556 if (pAdapter->request != NULL)
10557 {
10558 if ((pAdapter->request->n_ssids == 1)
10559 && (pAdapter->request->ssids != NULL)
10560 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
10561 is_p2p_scan = true;
10562 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010563 /*
10564 * start getting scan results and populate cgf80211 BSS database
10565 */
10566 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
10567
10568 /* no scan results */
10569 if (NULL == pResult)
10570 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010571 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
10572 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053010573 wlan_hdd_get_frame_logs(pAdapter,
10574 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070010575 return status;
10576 }
10577
10578 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
10579
10580 while (pScanResult)
10581 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010582 /*
10583 * cfg80211_inform_bss() is not updating ie field of bss entry, if
10584 * entry already exists in bss data base of cfg80211 for that
10585 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
10586 * bss entry instead of cfg80211_inform_bss, But this call expects
10587 * mgmt packet as input. As of now there is no possibility to get
10588 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070010589 * ieee80211_mgmt(probe response) and passing to c
10590 * fg80211_inform_bss_frame.
10591 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010592 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
10593 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
10594 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010595 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10596 continue; //Skip the non p2p bss entries
10597 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010598 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10599 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010600
Jeff Johnson295189b2012-06-20 16:38:30 -070010601
10602 if (NULL == bss_status)
10603 {
10604 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010605 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010606 }
10607 else
10608 {
Yue Maf49ba872013-08-19 12:04:25 -070010609 cfg80211_put_bss(
10610#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
10611 wiphy,
10612#endif
10613 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010614 }
10615
10616 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10617 }
10618
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010619 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010620 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010621 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010622}
10623
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010624void
10625hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
10626{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010627 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080010628 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010629} /****** end hddPrintMacAddr() ******/
10630
10631void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010632hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010633{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010634 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010635 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010636 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
10637 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
10638 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010639} /****** end hddPrintPmkId() ******/
10640
10641//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
10642//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
10643
10644//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
10645//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
10646
10647#define dump_bssid(bssid) \
10648 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010649 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
10650 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010651 }
10652
10653#define dump_pmkid(pMac, pmkid) \
10654 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010655 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
10656 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010657 }
10658
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070010659#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010660/*
10661 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
10662 * This function is used to notify the supplicant of a new PMKSA candidate.
10663 */
10664int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010665 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010666 int index, bool preauth )
10667{
Jeff Johnsone7245742012-09-05 17:12:55 -070010668#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010669 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010670 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010671
10672 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070010673 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010674
10675 if( NULL == pRoamInfo )
10676 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010677 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010678 return -EINVAL;
10679 }
10680
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010681 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
10682 {
10683 dump_bssid(pRoamInfo->bssid);
10684 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010685 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010686 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010687#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010688 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010689}
10690#endif //FEATURE_WLAN_LFR
10691
Yue Maef608272013-04-08 23:09:17 -070010692#ifdef FEATURE_WLAN_LFR_METRICS
10693/*
10694 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
10695 * 802.11r/LFR metrics reporting function to report preauth initiation
10696 *
10697 */
10698#define MAX_LFR_METRICS_EVENT_LENGTH 100
10699VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
10700 tCsrRoamInfo *pRoamInfo)
10701{
10702 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10703 union iwreq_data wrqu;
10704
10705 ENTER();
10706
10707 if (NULL == pAdapter)
10708 {
10709 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10710 return VOS_STATUS_E_FAILURE;
10711 }
10712
10713 /* create the event */
10714 memset(&wrqu, 0, sizeof(wrqu));
10715 memset(metrics_notification, 0, sizeof(metrics_notification));
10716
10717 wrqu.data.pointer = metrics_notification;
10718 wrqu.data.length = scnprintf(metrics_notification,
10719 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
10720 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10721
10722 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10723
10724 EXIT();
10725
10726 return VOS_STATUS_SUCCESS;
10727}
10728
10729/*
10730 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
10731 * 802.11r/LFR metrics reporting function to report preauth completion
10732 * or failure
10733 */
10734VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
10735 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
10736{
10737 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10738 union iwreq_data wrqu;
10739
10740 ENTER();
10741
10742 if (NULL == pAdapter)
10743 {
10744 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10745 return VOS_STATUS_E_FAILURE;
10746 }
10747
10748 /* create the event */
10749 memset(&wrqu, 0, sizeof(wrqu));
10750 memset(metrics_notification, 0, sizeof(metrics_notification));
10751
10752 scnprintf(metrics_notification, sizeof(metrics_notification),
10753 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
10754 MAC_ADDR_ARRAY(pRoamInfo->bssid));
10755
10756 if (1 == preauth_status)
10757 strncat(metrics_notification, " TRUE", 5);
10758 else
10759 strncat(metrics_notification, " FALSE", 6);
10760
10761 wrqu.data.pointer = metrics_notification;
10762 wrqu.data.length = strlen(metrics_notification);
10763
10764 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10765
10766 EXIT();
10767
10768 return VOS_STATUS_SUCCESS;
10769}
10770
10771/*
10772 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
10773 * 802.11r/LFR metrics reporting function to report handover initiation
10774 *
10775 */
10776VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
10777 tCsrRoamInfo *pRoamInfo)
10778{
10779 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10780 union iwreq_data wrqu;
10781
10782 ENTER();
10783
10784 if (NULL == pAdapter)
10785 {
10786 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10787 return VOS_STATUS_E_FAILURE;
10788 }
10789
10790 /* create the event */
10791 memset(&wrqu, 0, sizeof(wrqu));
10792 memset(metrics_notification, 0, sizeof(metrics_notification));
10793
10794 wrqu.data.pointer = metrics_notification;
10795 wrqu.data.length = scnprintf(metrics_notification,
10796 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
10797 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10798
10799 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10800
10801 EXIT();
10802
10803 return VOS_STATUS_SUCCESS;
10804}
10805#endif
10806
Jeff Johnson295189b2012-06-20 16:38:30 -070010807/*
10808 * FUNCTION: hdd_cfg80211_scan_done_callback
10809 * scanning callback function, called after finishing scan
10810 *
10811 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010812static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070010813 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
10814{
10815 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010816 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070010817 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010818 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010819 struct cfg80211_scan_request *req = NULL;
10820 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010821 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010822 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010823 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010824 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010825
10826 ENTER();
10827
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010828 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053010829 if (NULL == pHddCtx) {
10830 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010831 goto allow_suspend;
10832 }
10833
10834 pScanInfo = &pHddCtx->scan_info;
10835
Jeff Johnson295189b2012-06-20 16:38:30 -070010836 hddLog(VOS_TRACE_LEVEL_INFO,
10837 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080010838 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010839 __func__, halHandle, pContext, (int) scanId, (int) status);
10840
Kiet Lamac06e2c2013-10-23 16:25:07 +053010841 pScanInfo->mScanPendingCounter = 0;
10842
Jeff Johnson295189b2012-06-20 16:38:30 -070010843 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010844 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070010845 &pScanInfo->scan_req_completion_event,
10846 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010847 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070010848 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010849 hddLog(VOS_TRACE_LEVEL_ERROR,
10850 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070010851 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010852 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010853 }
10854
Yue Maef608272013-04-08 23:09:17 -070010855 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010856 {
10857 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010858 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010859 }
10860
10861 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010862 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070010863 {
10864 hddLog(VOS_TRACE_LEVEL_INFO,
10865 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010866 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070010867 (int) scanId);
10868 }
10869
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010870 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010871 pAdapter);
10872
10873 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010874 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010875
10876
10877 /* If any client wait scan result through WEXT
10878 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010879 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070010880 {
10881 /* The other scan request waiting for current scan finish
10882 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010883 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010884 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010885 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070010886 }
10887 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010888 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010889 {
10890 struct net_device *dev = pAdapter->dev;
10891 union iwreq_data wrqu;
10892 int we_event;
10893 char *msg;
10894
10895 memset(&wrqu, '\0', sizeof(wrqu));
10896 we_event = SIOCGIWSCAN;
10897 msg = NULL;
10898 wireless_send_event(dev, we_event, &wrqu, msg);
10899 }
10900 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010901 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010902
10903 /* Get the Scan Req */
10904 req = pAdapter->request;
10905
10906 if (!req)
10907 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010908 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010909 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010910 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010911 }
10912
Jeff Johnson295189b2012-06-20 16:38:30 -070010913 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070010914 /* Scan is no longer pending */
10915 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010916
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010917 /* last_scan_timestamp is used to decide if new scan
10918 * is needed or not on station interface. If last station
10919 * scan time and new station scan time is less then
10920 * last_scan_timestamp ; driver will return cached scan.
10921 */
10922 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
10923 {
10924 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
10925
10926 if ( req->n_channels )
10927 {
10928 for (i = 0; i < req->n_channels ; i++ )
10929 {
10930 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
10931 }
10932 /* store no of channel scanned */
10933 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
10934 }
10935
10936 }
10937
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070010938 /*
10939 * cfg80211_scan_done informing NL80211 about completion
10940 * of scanning
10941 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010942 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
10943 {
10944 aborted = true;
10945 }
10946 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080010947 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010948
Siddharth Bhal76972212014-10-15 16:22:51 +053010949 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
10950 /* Generate new random mac addr for next scan */
10951 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
10952 hdd_processSpoofMacAddrRequest(pHddCtx);
10953 }
10954
Jeff Johnsone7245742012-09-05 17:12:55 -070010955allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010956 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010957 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010958
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010959 /* Acquire wakelock to handle the case where APP's tries to suspend
10960 * immediatly after the driver gets connect request(i.e after scan)
10961 * from supplicant, this result in app's is suspending and not able
10962 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010963 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010964
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010965#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010966 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010967#endif
10968
Jeff Johnson295189b2012-06-20 16:38:30 -070010969 EXIT();
10970 return 0;
10971}
10972
10973/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053010974 * FUNCTION: hdd_isConnectionInProgress
10975 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010976 *
10977 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010978v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010979{
10980 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10981 hdd_station_ctx_t *pHddStaCtx = NULL;
10982 hdd_adapter_t *pAdapter = NULL;
10983 VOS_STATUS status = 0;
10984 v_U8_t staId = 0;
10985 v_U8_t *staMac = NULL;
10986
c_hpothu9b781ba2013-12-30 20:57:45 +053010987 if (TRUE == pHddCtx->btCoexModeSet)
10988 {
10989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053010990 FL("BTCoex Mode operation in progress"));
10991 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053010992 }
10993
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010994 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10995
10996 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10997 {
10998 pAdapter = pAdapterNode->pAdapter;
10999
11000 if( pAdapter )
11001 {
11002 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011003 "%s: Adapter with device mode %s (%d) exists",
11004 __func__, hdd_device_modetoString(pAdapter->device_mode),
11005 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011006 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053011007 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11008 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
11009 (eConnectionState_Connecting ==
11010 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
11011 {
11012 hddLog(VOS_TRACE_LEVEL_ERROR,
11013 "%s: %p(%d) Connection is in progress", __func__,
11014 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
11015 return VOS_TRUE;
11016 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011017 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053011018 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011019 {
11020 hddLog(VOS_TRACE_LEVEL_ERROR,
11021 "%s: %p(%d) Reassociation is in progress", __func__,
11022 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
11023 return VOS_TRUE;
11024 }
11025 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011026 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11027 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011028 {
11029 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11030 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011031 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011032 {
11033 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
11034 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080011035 "%s: client " MAC_ADDRESS_STR
11036 " is in the middle of WPS/EAPOL exchange.", __func__,
11037 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053011038 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011039 }
11040 }
11041 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
11042 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
11043 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011044 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11045 ptSapContext pSapCtx = NULL;
11046 pSapCtx = VOS_GET_SAP_CB(pVosContext);
11047 if(pSapCtx == NULL){
11048 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11049 FL("psapCtx is NULL"));
11050 return VOS_FALSE;
11051 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011052 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
11053 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011054 if ((pSapCtx->aStaInfo[staId].isUsed) &&
11055 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011056 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011057 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011058
11059 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080011060 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
11061 "middle of WPS/EAPOL exchange.", __func__,
11062 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053011063 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011064 }
11065 }
11066 }
11067 }
11068 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11069 pAdapterNode = pNext;
11070 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053011071 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011072}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011073
11074/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011075 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070011076 * this scan respond to scan trigger and update cfg80211 scan database
11077 * later, scan dump command can be used to recieve scan results
11078 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011079int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080011080#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11081 struct net_device *dev,
11082#endif
11083 struct cfg80211_scan_request *request)
11084{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011085 hdd_adapter_t *pAdapter = NULL;
11086 hdd_context_t *pHddCtx = NULL;
11087 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011088 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011089 tCsrScanRequest scanRequest;
11090 tANI_U8 *channelList = NULL, i;
11091 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011092 int status;
11093 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011094 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011095 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053011096 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011097 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053011098 v_S7_t rssi=0;
11099 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011100
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011101#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
11102 struct net_device *dev = NULL;
11103 if (NULL == request)
11104 {
11105 hddLog(VOS_TRACE_LEVEL_ERROR,
11106 "%s: scan req param null", __func__);
11107 return -EINVAL;
11108 }
11109 dev = request->wdev->netdev;
11110#endif
11111
11112 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11113 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
11114 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11115
Jeff Johnson295189b2012-06-20 16:38:30 -070011116 ENTER();
11117
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011118 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11119 __func__, hdd_device_modetoString(pAdapter->device_mode),
11120 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011121
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011122 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011123 if (0 != status)
11124 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011125 return status;
11126 }
11127
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011128 if (NULL == pwextBuf)
11129 {
11130 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
11131 __func__);
11132 return -EIO;
11133 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011134 cfg_param = pHddCtx->cfg_ini;
11135 pScanInfo = &pHddCtx->scan_info;
11136
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053011137 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11138 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
11139 {
11140 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
11141 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
11142 }
11143
Jeff Johnson295189b2012-06-20 16:38:30 -070011144#ifdef WLAN_BTAMP_FEATURE
11145 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011146 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070011147 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011148 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011149 "%s: No scanning when AMP is on", __func__);
11150 return -EOPNOTSUPP;
11151 }
11152#endif
11153 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011154 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011155 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011156 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011157 "%s: Not scanning on device_mode = %s (%d)",
11158 __func__, hdd_device_modetoString(pAdapter->device_mode),
11159 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011160 return -EOPNOTSUPP;
11161 }
11162
11163 if (TRUE == pScanInfo->mScanPending)
11164 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053011165 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
11166 {
11167 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
11168 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011169 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070011170 }
11171
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053011172 // Don't allow scan if PNO scan is going on.
11173 if (pHddCtx->isPnoEnable)
11174 {
11175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11176 FL("pno scan in progress"));
11177 return -EBUSY;
11178 }
11179
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011180 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070011181 //Channel and action frame is pending
11182 //Otherwise Cancel Remain On Channel and allow Scan
11183 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011184 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070011185 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053011186 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011187 return -EBUSY;
11188 }
11189
Jeff Johnson295189b2012-06-20 16:38:30 -070011190 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
11191 {
11192 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080011193 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011194 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011195 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011196 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
11197 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011198 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011199 "%s: MAX TM Level Scan not allowed", __func__);
11200 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011201 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070011202 }
11203 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
11204
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011205 /* Check if scan is allowed at this point of time.
11206 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011207 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011208 {
11209 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
11210 return -EBUSY;
11211 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011212
Jeff Johnson295189b2012-06-20 16:38:30 -070011213 vos_mem_zero( &scanRequest, sizeof(scanRequest));
11214
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011215 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
11216 * Becasue of this, driver is assuming that this is not wildcard scan and so
11217 * is not aging out the scan results.
11218 */
11219 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011220 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011221 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011222 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011223
11224 if ((request->ssids) && (0 < request->n_ssids))
11225 {
11226 tCsrSSIDInfo *SsidInfo;
11227 int j;
11228 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
11229 /* Allocate num_ssid tCsrSSIDInfo structure */
11230 SsidInfo = scanRequest.SSIDs.SSIDList =
11231 ( tCsrSSIDInfo *)vos_mem_malloc(
11232 request->n_ssids*sizeof(tCsrSSIDInfo));
11233
11234 if(NULL == scanRequest.SSIDs.SSIDList)
11235 {
11236 hddLog(VOS_TRACE_LEVEL_ERROR,
11237 "%s: memory alloc failed SSIDInfo buffer", __func__);
11238 return -ENOMEM;
11239 }
11240
11241 /* copy all the ssid's and their length */
11242 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
11243 {
11244 /* get the ssid length */
11245 SsidInfo->SSID.length = request->ssids[j].ssid_len;
11246 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
11247 SsidInfo->SSID.length);
11248 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
11249 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
11250 j, SsidInfo->SSID.ssId);
11251 }
11252 /* set the scan type to active */
11253 scanRequest.scanType = eSIR_ACTIVE_SCAN;
11254 }
11255 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011256 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011257 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11258 TRACE_CODE_HDD_CFG80211_SCAN,
11259 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070011260 /* set the scan type to active */
11261 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070011262 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011263 else
11264 {
11265 /*Set the scan type to default type, in this case it is ACTIVE*/
11266 scanRequest.scanType = pScanInfo->scan_mode;
11267 }
11268 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
11269 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070011270
11271 /* set BSSType to default type */
11272 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
11273
11274 /*TODO: scan the requested channels only*/
11275
11276 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011277 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070011278 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011279 hddLog(VOS_TRACE_LEVEL_WARN,
11280 "No of Scan Channels exceeded limit: %d", request->n_channels);
11281 request->n_channels = MAX_CHANNEL;
11282 }
11283
11284 hddLog(VOS_TRACE_LEVEL_INFO,
11285 "No of Scan Channels: %d", request->n_channels);
11286
11287
11288 if( request->n_channels )
11289 {
11290 char chList [(request->n_channels*5)+1];
11291 int len;
11292 channelList = vos_mem_malloc( request->n_channels );
11293 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053011294 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011295 hddLog(VOS_TRACE_LEVEL_ERROR,
11296 "%s: memory alloc failed channelList", __func__);
11297 status = -ENOMEM;
11298 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053011299 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011300
11301 for( i = 0, len = 0; i < request->n_channels ; i++ )
11302 {
11303 channelList[i] = request->channels[i]->hw_value;
11304 len += snprintf(chList+len, 5, "%d ", channelList[i]);
11305 }
11306
Nirav Shah20ac06f2013-12-12 18:14:06 +053011307 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011308 "Channel-List: %s ", chList);
11309 }
c_hpothu53512302014-04-15 18:49:53 +053011310
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011311 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
11312 scanRequest.ChannelInfo.ChannelList = channelList;
11313
11314 /* set requestType to full scan */
11315 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
11316
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011317 /* if there is back to back scan happening in driver with in
11318 * nDeferScanTimeInterval interval driver should defer new scan request
11319 * and should provide last cached scan results instead of new channel list.
11320 * This rule is not applicable if scan is p2p scan.
11321 * This condition will work only in case when last request no of channels
11322 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053011323 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053011324 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011325 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011326
Sushant Kaushik86592172015-04-27 16:35:03 +053011327 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
11328 /* if wps ie is NULL , then only defer scan */
11329 if ( pWpsIe == NULL &&
11330 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053011331 {
11332 if ( pScanInfo->last_scan_timestamp !=0 &&
11333 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
11334 {
11335 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
11336 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
11337 vos_mem_compare(pScanInfo->last_scan_channelList,
11338 channelList, pScanInfo->last_scan_numChannels))
11339 {
11340 hddLog(VOS_TRACE_LEVEL_WARN,
11341 " New and old station scan time differ is less then %u",
11342 pHddCtx->cfg_ini->nDeferScanTimeInterval);
11343
11344 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011345 pAdapter);
11346
Agarwal Ashish57e84372014-12-05 18:26:53 +053011347 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053011348 "Return old cached scan as all channels and no of channels are same");
11349
Agarwal Ashish57e84372014-12-05 18:26:53 +053011350 if (0 > ret)
11351 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011352
Agarwal Ashish57e84372014-12-05 18:26:53 +053011353 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053011354
11355 status = eHAL_STATUS_SUCCESS;
11356 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053011357 }
11358 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011359 }
11360
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011361 /* Flush the scan results(only p2p beacons) for STA scan and P2P
11362 * search (Flush on both full scan and social scan but not on single
11363 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
11364 */
11365
11366 /* Supplicant does single channel scan after 8-way handshake
11367 * and in that case driver shoudnt flush scan results. If
11368 * driver flushes the scan results here and unfortunately if
11369 * the AP doesnt respond to our probe req then association
11370 * fails which is not desired
11371 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011372 if ((request->n_ssids == 1)
11373 && (request->ssids != NULL)
11374 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
11375 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011376
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011377 if( is_p2p_scan ||
11378 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011379 {
11380 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
11381 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
11382 pAdapter->sessionId );
11383 }
11384
11385 if( request->ie_len )
11386 {
11387 /* save this for future association (join requires this) */
11388 /*TODO: Array needs to be converted to dynamic allocation,
11389 * as multiple ie.s can be sent in cfg80211_scan_request structure
11390 * CR 597966
11391 */
11392 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
11393 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
11394 pScanInfo->scanAddIE.length = request->ie_len;
11395
11396 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11397 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11398 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011399 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011400 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070011401 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011402 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
11403 memcpy( pwextBuf->roamProfile.addIEScan,
11404 request->ie, request->ie_len);
11405 }
11406 else
11407 {
11408 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
11409 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011410 }
11411
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011412 }
11413 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
11414 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
11415
11416 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
11417 request->ie_len);
11418 if (pP2pIe != NULL)
11419 {
11420#ifdef WLAN_FEATURE_P2P_DEBUG
11421 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
11422 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
11423 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053011424 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011425 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
11426 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11427 "Go nego completed to Connection is started");
11428 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11429 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053011430 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011431 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
11432 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011433 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011434 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
11435 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11436 "Disconnected state to Connection is started");
11437 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11438 "for 4way Handshake");
11439 }
11440#endif
11441
11442 /* no_cck will be set during p2p find to disable 11b rates */
11443 if(TRUE == request->no_cck)
11444 {
11445 hddLog(VOS_TRACE_LEVEL_INFO,
11446 "%s: This is a P2P Search", __func__);
11447 scanRequest.p2pSearch = 1;
11448
11449 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053011450 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011451 /* set requestType to P2P Discovery */
11452 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
11453 }
11454
11455 /*
11456 Skip Dfs Channel in case of P2P Search
11457 if it is set in ini file
11458 */
11459 if(cfg_param->skipDfsChnlInP2pSearch)
11460 {
11461 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011462 }
11463 else
11464 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011465 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011466 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011467
Agarwal Ashish4f616132013-12-30 23:32:50 +053011468 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011469 }
11470 }
11471
11472 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
11473
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011474#ifdef FEATURE_WLAN_TDLS
11475 /* if tdls disagree scan right now, return immediately.
11476 tdls will schedule the scan when scan is allowed. (return SUCCESS)
11477 or will reject the scan if any TDLS is in progress. (return -EBUSY)
11478 */
11479 status = wlan_hdd_tdls_scan_callback (pAdapter,
11480 wiphy,
11481#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11482 dev,
11483#endif
11484 request);
11485 if(status <= 0)
11486 {
11487 if(!status)
11488 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
11489 "scan rejected %d", __func__, status);
11490 else
11491 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
11492 __func__, status);
11493
11494 return status;
11495 }
11496#endif
11497
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011498 /* acquire the wakelock to avoid the apps suspend during the scan. To
11499 * address the following issues.
11500 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
11501 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
11502 * for long time, this result in apps running at full power for long time.
11503 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
11504 * be stuck in full power because of resume BMPS
11505 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011506 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011507
Nirav Shah20ac06f2013-12-12 18:14:06 +053011508 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11509 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011510 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
11511 scanRequest.requestType, scanRequest.scanType,
11512 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053011513 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
11514
Siddharth Bhal76972212014-10-15 16:22:51 +053011515 if (pHddCtx->spoofMacAddr.isEnabled)
11516 {
11517 hddLog(VOS_TRACE_LEVEL_INFO,
11518 "%s: MAC Spoofing enabled for current scan", __func__);
11519 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
11520 * to fill TxBds for probe request during current scan
11521 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011522 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053011523 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011524
11525 if(status != VOS_STATUS_SUCCESS)
11526 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011527 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011528 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053011529#ifdef FEATURE_WLAN_TDLS
11530 wlan_hdd_tdls_scan_done_callback(pAdapter);
11531#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011532 goto free_mem;
11533 }
Siddharth Bhal76972212014-10-15 16:22:51 +053011534 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053011535 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070011536 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011537 pAdapter->sessionId, &scanRequest, &scanId,
11538 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070011539
Jeff Johnson295189b2012-06-20 16:38:30 -070011540 if (eHAL_STATUS_SUCCESS != status)
11541 {
11542 hddLog(VOS_TRACE_LEVEL_ERROR,
11543 "%s: sme_ScanRequest returned error %d", __func__, status);
11544 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011545 if(eHAL_STATUS_RESOURCES == status)
11546 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011547 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
11548 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011549 status = -EBUSY;
11550 } else {
11551 status = -EIO;
11552 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011553 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011554
11555#ifdef FEATURE_WLAN_TDLS
11556 wlan_hdd_tdls_scan_done_callback(pAdapter);
11557#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011558 goto free_mem;
11559 }
11560
11561 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011562 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011563 pAdapter->request = request;
11564 pScanInfo->scanId = scanId;
11565
11566 complete(&pScanInfo->scan_req_completion_event);
11567
11568free_mem:
11569 if( scanRequest.SSIDs.SSIDList )
11570 {
11571 vos_mem_free(scanRequest.SSIDs.SSIDList);
11572 }
11573
11574 if( channelList )
11575 vos_mem_free( channelList );
11576
11577 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011578 return status;
11579}
11580
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011581int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
11582#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11583 struct net_device *dev,
11584#endif
11585 struct cfg80211_scan_request *request)
11586{
11587 int ret;
11588
11589 vos_ssr_protect(__func__);
11590 ret = __wlan_hdd_cfg80211_scan(wiphy,
11591#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11592 dev,
11593#endif
11594 request);
11595 vos_ssr_unprotect(__func__);
11596
11597 return ret;
11598}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011599
11600void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
11601{
11602 v_U8_t iniDot11Mode =
11603 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
11604 eHddDot11Mode hddDot11Mode = iniDot11Mode;
11605
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011606 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
11607 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011608 switch ( iniDot11Mode )
11609 {
11610 case eHDD_DOT11_MODE_AUTO:
11611 case eHDD_DOT11_MODE_11ac:
11612 case eHDD_DOT11_MODE_11ac_ONLY:
11613#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053011614 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
11615 sme_IsFeatureSupportedByFW(DOT11AC) )
11616 hddDot11Mode = eHDD_DOT11_MODE_11ac;
11617 else
11618 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011619#else
11620 hddDot11Mode = eHDD_DOT11_MODE_11n;
11621#endif
11622 break;
11623 case eHDD_DOT11_MODE_11n:
11624 case eHDD_DOT11_MODE_11n_ONLY:
11625 hddDot11Mode = eHDD_DOT11_MODE_11n;
11626 break;
11627 default:
11628 hddDot11Mode = iniDot11Mode;
11629 break;
11630 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011631#ifdef WLAN_FEATURE_AP_HT40_24G
11632 if (operationChannel > SIR_11B_CHANNEL_END)
11633#endif
11634 {
11635 /* This call decides required channel bonding mode */
11636 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011637 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
11638 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011639 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011640}
11641
Jeff Johnson295189b2012-06-20 16:38:30 -070011642/*
11643 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011644 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011645 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011646int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011647 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070011648{
11649 int status = 0;
11650 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080011651 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011652 v_U32_t roamId;
11653 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070011654 eCsrAuthType RSNAuthType;
11655
11656 ENTER();
11657
11658 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080011659 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11660
11661 status = wlan_hdd_validate_context(pHddCtx);
11662 if (status)
11663 {
Yue Mae36e3552014-03-05 17:06:20 -080011664 return status;
11665 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011666
Jeff Johnson295189b2012-06-20 16:38:30 -070011667 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
11668 {
11669 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
11670 return -EINVAL;
11671 }
11672
11673 pRoamProfile = &pWextState->roamProfile;
11674
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011675 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070011676 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011677 hdd_station_ctx_t *pHddStaCtx;
11678 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011679
Siddharth Bhalda0d1622015-04-24 15:47:49 +053011680 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
11681
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011682 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070011683 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
11684 {
11685 /*QoS not enabled in cfg file*/
11686 pRoamProfile->uapsd_mask = 0;
11687 }
11688 else
11689 {
11690 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011691 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070011692 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
11693 }
11694
11695 pRoamProfile->SSIDs.numOfSSIDs = 1;
11696 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
11697 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011698 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070011699 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
11700 ssid, ssid_len);
11701
11702 if (bssid)
11703 {
11704 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
11705 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
11706 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011707 /* Save BSSID in seperate variable as well, as RoamProfile
11708 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070011709 case of join failure we should send valid BSSID to supplicant
11710 */
11711 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
11712 WNI_CFG_BSSID_LEN);
11713 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070011714 else
11715 {
11716 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
11717 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011718
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011719 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
11720 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011721 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
11722 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011723 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011724 /*set gen ie*/
11725 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
11726 /*set auth*/
11727 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
11728 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011729#ifdef FEATURE_WLAN_WAPI
11730 if (pAdapter->wapi_info.nWapiMode)
11731 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011732 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011733 switch (pAdapter->wapi_info.wapiAuthMode)
11734 {
11735 case WAPI_AUTH_MODE_PSK:
11736 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011737 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011738 pAdapter->wapi_info.wapiAuthMode);
11739 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
11740 break;
11741 }
11742 case WAPI_AUTH_MODE_CERT:
11743 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011744 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011745 pAdapter->wapi_info.wapiAuthMode);
11746 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
11747 break;
11748 }
11749 } // End of switch
11750 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
11751 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
11752 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011753 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011754 pRoamProfile->AuthType.numEntries = 1;
11755 pRoamProfile->EncryptionType.numEntries = 1;
11756 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11757 pRoamProfile->mcEncryptionType.numEntries = 1;
11758 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11759 }
11760 }
11761#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011762#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011763 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011764 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11765 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
11766 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011767 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
11768 sizeof (tSirGtkOffloadParams));
11769 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011770 }
11771#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011772 pRoamProfile->csrPersona = pAdapter->device_mode;
11773
Jeff Johnson32d95a32012-09-10 13:15:23 -070011774 if( operatingChannel )
11775 {
11776 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
11777 pRoamProfile->ChannelInfo.numOfChannels = 1;
11778 }
Chet Lanctot186b5732013-03-18 10:26:30 -070011779 else
11780 {
11781 pRoamProfile->ChannelInfo.ChannelList = NULL;
11782 pRoamProfile->ChannelInfo.numOfChannels = 0;
11783 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011784 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
11785 {
11786 hdd_select_cbmode(pAdapter,operatingChannel);
11787 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011788
Agarwal Ashish40f9b872015-09-01 16:17:35 +053011789 /*
11790 * Change conn_state to connecting before sme_RoamConnect(),
11791 * because sme_RoamConnect() has a direct path to call
11792 * hdd_smeRoamCallback(), which will change the conn_state
11793 * If direct path, conn_state will be accordingly changed
11794 * to NotConnected or Associated by either
11795 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
11796 * in sme_RoamCallback()
11797 * if sme_RomConnect is to be queued,
11798 * Connecting state will remain until it is completed.
11799 * If connection state is not changed,
11800 * connection state will remain in eConnectionState_NotConnected state.
11801 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
11802 * if conn state is eConnectionState_NotConnected.
11803 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
11804 * informed of connect result indication which is an issue.
11805 */
11806
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011807 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11808 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053011809 {
11810 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053011811 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011812 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
11813 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053011814 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011815 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011816 pAdapter->sessionId, pRoamProfile, &roamId);
11817
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011818 if ((eHAL_STATUS_SUCCESS != status) &&
11819 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11820 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011821
11822 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053011823 hddLog(VOS_TRACE_LEVEL_ERROR,
11824 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
11825 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011826 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011827 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011828 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011829 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011830
11831 pRoamProfile->ChannelInfo.ChannelList = NULL;
11832 pRoamProfile->ChannelInfo.numOfChannels = 0;
11833
Jeff Johnson295189b2012-06-20 16:38:30 -070011834 }
11835 else
11836 {
11837 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
11838 return -EINVAL;
11839 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011840 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011841 return status;
11842}
11843
11844/*
11845 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
11846 * This function is used to set the authentication type (OPEN/SHARED).
11847 *
11848 */
11849static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
11850 enum nl80211_auth_type auth_type)
11851{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011852 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011853 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11854
11855 ENTER();
11856
11857 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011858 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070011859 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011860 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011861 hddLog(VOS_TRACE_LEVEL_INFO,
11862 "%s: set authentication type to AUTOSWITCH", __func__);
11863 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
11864 break;
11865
11866 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011867#ifdef WLAN_FEATURE_VOWIFI_11R
11868 case NL80211_AUTHTYPE_FT:
11869#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011870 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011871 "%s: set authentication type to OPEN", __func__);
11872 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11873 break;
11874
11875 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011876 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011877 "%s: set authentication type to SHARED", __func__);
11878 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
11879 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011880#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011881 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011882 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011883 "%s: set authentication type to CCKM WPA", __func__);
11884 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
11885 break;
11886#endif
11887
11888
11889 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011890 hddLog(VOS_TRACE_LEVEL_ERROR,
11891 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011892 auth_type);
11893 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
11894 return -EINVAL;
11895 }
11896
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011897 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011898 pHddStaCtx->conn_info.authType;
11899 return 0;
11900}
11901
11902/*
11903 * FUNCTION: wlan_hdd_set_akm_suite
11904 * This function is used to set the key mgmt type(PSK/8021x).
11905 *
11906 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011907static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011908 u32 key_mgmt
11909 )
11910{
11911 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11912 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053011913 /* Should be in ieee802_11_defs.h */
11914#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
11915#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070011916 /*set key mgmt type*/
11917 switch(key_mgmt)
11918 {
11919 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053011920 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011921#ifdef WLAN_FEATURE_VOWIFI_11R
11922 case WLAN_AKM_SUITE_FT_PSK:
11923#endif
11924 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070011925 __func__);
11926 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
11927 break;
11928
11929 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053011930 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011931#ifdef WLAN_FEATURE_VOWIFI_11R
11932 case WLAN_AKM_SUITE_FT_8021X:
11933#endif
11934 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070011935 __func__);
11936 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11937 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011938#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011939#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
11940#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
11941 case WLAN_AKM_SUITE_CCKM:
11942 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
11943 __func__);
11944 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
11945 break;
11946#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070011947#ifndef WLAN_AKM_SUITE_OSEN
11948#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
11949 case WLAN_AKM_SUITE_OSEN:
11950 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
11951 __func__);
11952 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11953 break;
11954#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011955
11956 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011957 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011958 __func__, key_mgmt);
11959 return -EINVAL;
11960
11961 }
11962 return 0;
11963}
11964
11965/*
11966 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011967 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070011968 * (NONE/WEP40/WEP104/TKIP/CCMP).
11969 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011970static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
11971 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070011972 bool ucast
11973 )
11974{
11975 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011976 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011977 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11978
11979 ENTER();
11980
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011981 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011982 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053011983 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070011984 __func__, cipher);
11985 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11986 }
11987 else
11988 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011989
Jeff Johnson295189b2012-06-20 16:38:30 -070011990 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011991 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011992 {
11993 case IW_AUTH_CIPHER_NONE:
11994 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11995 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011996
Jeff Johnson295189b2012-06-20 16:38:30 -070011997 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011998 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070011999 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012000
Jeff Johnson295189b2012-06-20 16:38:30 -070012001 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012002 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070012003 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012004
Jeff Johnson295189b2012-06-20 16:38:30 -070012005 case WLAN_CIPHER_SUITE_TKIP:
12006 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
12007 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012008
Jeff Johnson295189b2012-06-20 16:38:30 -070012009 case WLAN_CIPHER_SUITE_CCMP:
12010 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12011 break;
12012#ifdef FEATURE_WLAN_WAPI
12013 case WLAN_CIPHER_SUITE_SMS4:
12014 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
12015 break;
12016#endif
12017
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012018#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012019 case WLAN_CIPHER_SUITE_KRK:
12020 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
12021 break;
12022#endif
12023 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012024 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012025 __func__, cipher);
12026 return -EOPNOTSUPP;
12027 }
12028 }
12029
12030 if (ucast)
12031 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012032 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012033 __func__, encryptionType);
12034 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12035 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012036 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012037 encryptionType;
12038 }
12039 else
12040 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012041 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012042 __func__, encryptionType);
12043 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
12044 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
12045 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
12046 }
12047
12048 return 0;
12049}
12050
12051
12052/*
12053 * FUNCTION: wlan_hdd_cfg80211_set_ie
12054 * This function is used to parse WPA/RSN IE's.
12055 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012056int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012057#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12058 const u8 *ie,
12059#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012060 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012061#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012062 size_t ie_len
12063 )
12064{
12065 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012066#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12067 const u8 *genie = ie;
12068#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012069 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012070#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012071 v_U16_t remLen = ie_len;
12072#ifdef FEATURE_WLAN_WAPI
12073 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
12074 u16 *tmp;
12075 v_U16_t akmsuiteCount;
12076 int *akmlist;
12077#endif
12078 ENTER();
12079
12080 /* clear previous assocAddIE */
12081 pWextState->assocAddIE.length = 0;
12082 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012083 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012084
12085 while (remLen >= 2)
12086 {
12087 v_U16_t eLen = 0;
12088 v_U8_t elementId;
12089 elementId = *genie++;
12090 eLen = *genie++;
12091 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012092
Arif Hussain6d2a3322013-11-17 19:50:10 -080012093 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070012094 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012095
12096 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070012097 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012098 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012099 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 -070012100 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012101 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012102 "%s: Invalid WPA IE", __func__);
12103 return -EINVAL;
12104 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012105 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070012106 {
12107 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012108 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012109 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012110
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012111 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012112 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012113 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
12114 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012115 VOS_ASSERT(0);
12116 return -ENOMEM;
12117 }
12118 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
12119 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12120 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012121
Jeff Johnson295189b2012-06-20 16:38:30 -070012122 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
12123 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12124 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12125 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012126 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
12127 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012128 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
12129 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
12130 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
12131 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
12132 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
12133 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012134 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053012135 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070012136 {
12137 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012138 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012139 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012140
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012141 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012142 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012143 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12144 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012145 VOS_ASSERT(0);
12146 return -ENOMEM;
12147 }
12148 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
12149 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12150 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012151
Jeff Johnson295189b2012-06-20 16:38:30 -070012152 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12153 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12154 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012155#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012156 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
12157 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012158 /*Consider WFD IE, only for P2P Client */
12159 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
12160 {
12161 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012162 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012163 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012164
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012165 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012166 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012167 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12168 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012169 VOS_ASSERT(0);
12170 return -ENOMEM;
12171 }
12172 // WFD IE is saved to Additional IE ; it should be accumulated to handle
12173 // WPS IE + P2P IE + WFD IE
12174 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12175 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012176
Jeff Johnson295189b2012-06-20 16:38:30 -070012177 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12178 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12179 }
12180#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012181 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012182 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012183 HS20_OUI_TYPE_SIZE)) )
12184 {
12185 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012186 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012187 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012188
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012189 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012190 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012191 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12192 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012193 VOS_ASSERT(0);
12194 return -ENOMEM;
12195 }
12196 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12197 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012198
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012199 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12200 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12201 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012202 /* Appending OSEN Information Element in Assiciation Request */
12203 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
12204 OSEN_OUI_TYPE_SIZE)) )
12205 {
12206 v_U16_t curAddIELen = pWextState->assocAddIE.length;
12207 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
12208 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012209
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012210 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012211 {
12212 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12213 "Need bigger buffer space");
12214 VOS_ASSERT(0);
12215 return -ENOMEM;
12216 }
12217 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12218 pWextState->assocAddIE.length += eLen + 2;
12219
12220 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
12221 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12222 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12223 }
12224
Abhishek Singh4322e622015-06-10 15:42:54 +053012225 /* Update only for WPA IE */
12226 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
12227 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070012228
12229 /* populating as ADDIE in beacon frames */
12230 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012231 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070012232 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
12233 {
12234 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
12235 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
12236 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
12237 {
12238 hddLog(LOGE,
12239 "Coldn't pass "
12240 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
12241 }
12242 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
12243 else
12244 hddLog(LOGE,
12245 "Could not pass on "
12246 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
12247
12248 /* IBSS mode doesn't contain params->proberesp_ies still
12249 beaconIE's need to be populated in probe response frames */
12250 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
12251 {
12252 u16 rem_probe_resp_ie_len = eLen + 2;
12253 u8 probe_rsp_ie_len[3] = {0};
12254 u8 counter = 0;
12255
12256 /* Check Probe Resp Length if it is greater then 255 then
12257 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
12258 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
12259 not able Store More then 255 bytes into One Variable */
12260
12261 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
12262 {
12263 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
12264 {
12265 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
12266 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
12267 }
12268 else
12269 {
12270 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
12271 rem_probe_resp_ie_len = 0;
12272 }
12273 }
12274
12275 rem_probe_resp_ie_len = 0;
12276
12277 if (probe_rsp_ie_len[0] > 0)
12278 {
12279 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12280 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
12281 (tANI_U8*)(genie - 2),
12282 probe_rsp_ie_len[0], NULL,
12283 eANI_BOOLEAN_FALSE)
12284 == eHAL_STATUS_FAILURE)
12285 {
12286 hddLog(LOGE,
12287 "Could not pass"
12288 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
12289 }
12290 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
12291 }
12292
12293 if (probe_rsp_ie_len[1] > 0)
12294 {
12295 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12296 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
12297 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
12298 probe_rsp_ie_len[1], NULL,
12299 eANI_BOOLEAN_FALSE)
12300 == eHAL_STATUS_FAILURE)
12301 {
12302 hddLog(LOGE,
12303 "Could not pass"
12304 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
12305 }
12306 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
12307 }
12308
12309 if (probe_rsp_ie_len[2] > 0)
12310 {
12311 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12312 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
12313 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
12314 probe_rsp_ie_len[2], NULL,
12315 eANI_BOOLEAN_FALSE)
12316 == eHAL_STATUS_FAILURE)
12317 {
12318 hddLog(LOGE,
12319 "Could not pass"
12320 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
12321 }
12322 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
12323 }
12324
12325 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
12326 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
12327 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
12328 {
12329 hddLog(LOGE,
12330 "Could not pass"
12331 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
12332 }
12333 }
12334 else
12335 {
12336 // Reset WNI_CFG_PROBE_RSP Flags
12337 wlan_hdd_reset_prob_rspies(pAdapter);
12338
12339 hddLog(VOS_TRACE_LEVEL_INFO,
12340 "%s: No Probe Response IE received in set beacon",
12341 __func__);
12342 }
12343 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012344 break;
12345 case DOT11F_EID_RSN:
12346 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
12347 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
12348 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
12349 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
12350 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
12351 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053012352
12353 /* Appending Extended Capabilities with Interworking bit set
12354 * in Assoc Req.
12355 *
12356 * In assoc req this EXT Cap will only be taken into account if
12357 * interworkingService bit is set to 1. Currently
12358 * driver is only interested in interworkingService capability
12359 * from supplicant. If in future any other EXT Cap info is
12360 * required from supplicat, it needs to be handled while
12361 * sending Assoc Req in LIM.
12362 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012363 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012364 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012365 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012366 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012367 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012368
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012369 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012370 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012371 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12372 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012373 VOS_ASSERT(0);
12374 return -ENOMEM;
12375 }
12376 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12377 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012378
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012379 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12380 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12381 break;
12382 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012383#ifdef FEATURE_WLAN_WAPI
12384 case WLAN_EID_WAPI:
12385 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012386 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012387 pAdapter->wapi_info.nWapiMode);
12388 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012389 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070012390 akmsuiteCount = WPA_GET_LE16(tmp);
12391 tmp = tmp + 1;
12392 akmlist = (int *)(tmp);
12393 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
12394 {
12395 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
12396 }
12397 else
12398 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012399 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070012400 VOS_ASSERT(0);
12401 return -EINVAL;
12402 }
12403
12404 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
12405 {
12406 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012407 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012408 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012409 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012410 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012411 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012412 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012413 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012414 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
12415 }
12416 break;
12417#endif
12418 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012419 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012420 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012421 /* when Unknown IE is received we should break and continue
12422 * to the next IE in the buffer instead we were returning
12423 * so changing this to break */
12424 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070012425 }
12426 genie += eLen;
12427 remLen -= eLen;
12428 }
12429 EXIT();
12430 return 0;
12431}
12432
12433/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012434 * FUNCTION: hdd_isWPAIEPresent
12435 * Parse the received IE to find the WPA IE
12436 *
12437 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012438static bool hdd_isWPAIEPresent(
12439#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
12440 const u8 *ie,
12441#else
12442 u8 *ie,
12443#endif
12444 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012445{
12446 v_U8_t eLen = 0;
12447 v_U16_t remLen = ie_len;
12448 v_U8_t elementId = 0;
12449
12450 while (remLen >= 2)
12451 {
12452 elementId = *ie++;
12453 eLen = *ie++;
12454 remLen -= 2;
12455 if (eLen > remLen)
12456 {
12457 hddLog(VOS_TRACE_LEVEL_ERROR,
12458 "%s: IE length is wrong %d", __func__, eLen);
12459 return FALSE;
12460 }
12461 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
12462 {
12463 /* OUI - 0x00 0X50 0XF2
12464 WPA Information Element - 0x01
12465 WPA version - 0x01*/
12466 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
12467 return TRUE;
12468 }
12469 ie += eLen;
12470 remLen -= eLen;
12471 }
12472 return FALSE;
12473}
12474
12475/*
Jeff Johnson295189b2012-06-20 16:38:30 -070012476 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012477 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012478 * parameters during connect operation.
12479 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012480int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012481 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012482 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012483{
12484 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012485 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012486 ENTER();
12487
12488 /*set wpa version*/
12489 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
12490
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012491 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012492 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053012493 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012494 {
12495 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12496 }
12497 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
12498 {
12499 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12500 }
12501 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012502
12503 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012504 pWextState->wpaVersion);
12505
12506 /*set authentication type*/
12507 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
12508
12509 if (0 > status)
12510 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012511 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012512 "%s: failed to set authentication type ", __func__);
12513 return status;
12514 }
12515
12516 /*set key mgmt type*/
12517 if (req->crypto.n_akm_suites)
12518 {
12519 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
12520 if (0 > status)
12521 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012522 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070012523 __func__);
12524 return status;
12525 }
12526 }
12527
12528 /*set pairwise cipher type*/
12529 if (req->crypto.n_ciphers_pairwise)
12530 {
12531 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
12532 req->crypto.ciphers_pairwise[0], true);
12533 if (0 > status)
12534 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012535 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012536 "%s: failed to set unicast cipher type", __func__);
12537 return status;
12538 }
12539 }
12540 else
12541 {
12542 /*Reset previous cipher suite to none*/
12543 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
12544 if (0 > status)
12545 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012546 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012547 "%s: failed to set unicast cipher type", __func__);
12548 return status;
12549 }
12550 }
12551
12552 /*set group cipher type*/
12553 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
12554 false);
12555
12556 if (0 > status)
12557 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012558 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070012559 __func__);
12560 return status;
12561 }
12562
Chet Lanctot186b5732013-03-18 10:26:30 -070012563#ifdef WLAN_FEATURE_11W
12564 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
12565#endif
12566
Jeff Johnson295189b2012-06-20 16:38:30 -070012567 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
12568 if (req->ie_len)
12569 {
12570 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
12571 if ( 0 > status)
12572 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012573 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012574 __func__);
12575 return status;
12576 }
12577 }
12578
12579 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012580 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012581 {
12582 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
12583 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
12584 )
12585 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012586 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070012587 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
12588 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012589 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012590 __func__);
12591 return -EOPNOTSUPP;
12592 }
12593 else
12594 {
12595 u8 key_len = req->key_len;
12596 u8 key_idx = req->key_idx;
12597
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012598 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012599 && (CSR_MAX_NUM_KEY > key_idx)
12600 )
12601 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012602 hddLog(VOS_TRACE_LEVEL_INFO,
12603 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012604 __func__, key_idx, key_len);
12605 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012606 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012607 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012608 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012609 (u8)key_len;
12610 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
12611 }
12612 }
12613 }
12614 }
12615
12616 return status;
12617}
12618
12619/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012620 * FUNCTION: wlan_hdd_try_disconnect
12621 * This function is used to disconnect from previous
12622 * connection
12623 */
12624static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
12625{
12626 long ret = 0;
12627 hdd_station_ctx_t *pHddStaCtx;
12628 eMib_dot11DesiredBssType connectedBssType;
12629
12630 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12631
12632 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
12633
12634 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
12635 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
12636 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
12637 {
12638 /* Issue disconnect to CSR */
12639 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12640 if( eHAL_STATUS_SUCCESS ==
12641 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12642 pAdapter->sessionId,
12643 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12644 {
12645 ret = wait_for_completion_interruptible_timeout(
12646 &pAdapter->disconnect_comp_var,
12647 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12648 if (0 >= ret)
12649 {
12650 hddLog(LOGE, FL("Failed to receive disconnect event"));
12651 return -EALREADY;
12652 }
12653 }
12654 }
12655 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
12656 {
12657 ret = wait_for_completion_interruptible_timeout(
12658 &pAdapter->disconnect_comp_var,
12659 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12660 if (0 >= ret)
12661 {
12662 hddLog(LOGE, FL("Failed to receive disconnect event"));
12663 return -EALREADY;
12664 }
12665 }
12666
12667 return 0;
12668}
12669
12670/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053012671 * FUNCTION: __wlan_hdd_cfg80211_connect
12672 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070012673 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012674static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012675 struct net_device *ndev,
12676 struct cfg80211_connect_params *req
12677 )
12678{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012679 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012680 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012681 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053012682 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012683
12684 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012685
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012686 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12687 TRACE_CODE_HDD_CFG80211_CONNECT,
12688 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012689 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012690 "%s: device_mode = %s (%d)", __func__,
12691 hdd_device_modetoString(pAdapter->device_mode),
12692 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012693
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012694 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012695 if (!pHddCtx)
12696 {
12697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12698 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053012699 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012700 }
12701
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012702 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012703 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012704 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012705 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012706 }
12707
Agarwal Ashish51325b52014-06-16 16:50:49 +053012708 if (vos_max_concurrent_connections_reached()) {
12709 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12710 return -ECONNREFUSED;
12711 }
12712
Jeff Johnson295189b2012-06-20 16:38:30 -070012713#ifdef WLAN_BTAMP_FEATURE
12714 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012715 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070012716 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012717 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012718 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012719 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070012720 }
12721#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012722
12723 //If Device Mode is Station Concurrent Sessions Exit BMps
12724 //P2P Mode will be taken care in Open/close adapter
12725 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012726 (vos_concurrent_open_sessions_running())) {
12727 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
12728 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012729 }
12730
12731 /*Try disconnecting if already in connected state*/
12732 status = wlan_hdd_try_disconnect(pAdapter);
12733 if ( 0 > status)
12734 {
12735 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12736 " connection"));
12737 return -EALREADY;
12738 }
12739
Jeff Johnson295189b2012-06-20 16:38:30 -070012740 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012741 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070012742
12743 if ( 0 > status)
12744 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012745 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070012746 __func__);
12747 return status;
12748 }
Mohit Khanna765234a2012-09-11 15:08:35 -070012749 if ( req->channel )
12750 {
12751 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
12752 req->ssid_len, req->bssid,
12753 req->channel->hw_value);
12754 }
12755 else
12756 {
12757 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012758 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070012759 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012760
Sushant Kaushikd7083982015-03-18 14:33:24 +053012761 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012762 {
12763 //ReEnable BMPS if disabled
12764 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
12765 (NULL != pHddCtx))
12766 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012767 if (pHddCtx->hdd_wlan_suspended)
12768 {
12769 hdd_set_pwrparams(pHddCtx);
12770 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012771 //ReEnable Bmps and Imps back
12772 hdd_enable_bmps_imps(pHddCtx);
12773 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053012774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070012775 return status;
12776 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012777 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012778 EXIT();
12779 return status;
12780}
12781
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012782static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
12783 struct net_device *ndev,
12784 struct cfg80211_connect_params *req)
12785{
12786 int ret;
12787 vos_ssr_protect(__func__);
12788 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
12789 vos_ssr_unprotect(__func__);
12790
12791 return ret;
12792}
Jeff Johnson295189b2012-06-20 16:38:30 -070012793
12794/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012795 * FUNCTION: wlan_hdd_disconnect
12796 * This function is used to issue a disconnect request to SME
12797 */
12798int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
12799{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012800 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012801 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012802 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012803 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012804
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012805 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012806
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012807 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012808 if (0 != status)
12809 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012810 return status;
12811 }
12812
Sushant Kaushikb4834d22015-07-15 15:29:05 +053012813 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
12814 {
12815 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
12816 pAdapter->sessionId);
12817 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012818 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012819
Agarwal Ashish47d18112014-08-04 19:55:07 +053012820 /* Need to apply spin lock before decreasing active sessions
12821 * as there can be chance for double decrement if context switch
12822 * Calls hdd_DisConnectHandler.
12823 */
12824
12825 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012826 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
12827 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012828 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
12829 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053012830 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
12831 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012832
Abhishek Singhf4669da2014-05-26 15:07:49 +053012833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053012834 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
12835
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012836 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012837
Mihir Shete182a0b22014-08-18 16:08:48 +053012838 /*
12839 * stop tx queues before deleting STA/BSS context from the firmware.
12840 * tx has to be disabled because the firmware can get busy dropping
12841 * the tx frames after BSS/STA has been deleted and will not send
12842 * back a response resulting in WDI timeout
12843 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053012844 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053012845 netif_tx_disable(pAdapter->dev);
12846 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012847
Mihir Shete182a0b22014-08-18 16:08:48 +053012848 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012849 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12850 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012851 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
12852 {
12853 hddLog(VOS_TRACE_LEVEL_INFO,
12854 FL("status = %d, already disconnected"),
12855 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012856
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012857 }
12858 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012859 {
12860 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012861 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012862 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012863 result = -EINVAL;
12864 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012865 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012866 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012867 &pAdapter->disconnect_comp_var,
12868 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012869 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012870 {
12871 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012872 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012873 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012874 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012875 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012876 {
12877 hddLog(VOS_TRACE_LEVEL_ERROR,
12878 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012879 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012880 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012881disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012882 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12883 FL("Set HDD connState to eConnectionState_NotConnected"));
12884 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
12885
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012886 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012887 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012888}
12889
12890
12891/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012892 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070012893 * This function is used to issue a disconnect request to SME
12894 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012895static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012896 struct net_device *dev,
12897 u16 reason
12898 )
12899{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012900 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012901 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012902 tCsrRoamProfile *pRoamProfile;
12903 hdd_station_ctx_t *pHddStaCtx;
12904 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012905#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012906 tANI_U8 staIdx;
12907#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012908
Jeff Johnson295189b2012-06-20 16:38:30 -070012909 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012910
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012911 if (!pAdapter) {
12912 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
12913 return -EINVAL;
12914 }
12915
12916 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12917 if (!pHddStaCtx) {
12918 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
12919 return -EINVAL;
12920 }
12921
12922 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12923 status = wlan_hdd_validate_context(pHddCtx);
12924 if (0 != status)
12925 {
12926 return status;
12927 }
12928
12929 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
12930
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012931 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12932 TRACE_CODE_HDD_CFG80211_DISCONNECT,
12933 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012934 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
12935 __func__, hdd_device_modetoString(pAdapter->device_mode),
12936 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012937
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012938 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
12939 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070012940
Jeff Johnson295189b2012-06-20 16:38:30 -070012941 if (NULL != pRoamProfile)
12942 {
12943 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012944 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
12945 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070012946 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012947 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070012948 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012949 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012950 switch(reason)
12951 {
12952 case WLAN_REASON_MIC_FAILURE:
12953 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
12954 break;
12955
12956 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
12957 case WLAN_REASON_DISASSOC_AP_BUSY:
12958 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
12959 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
12960 break;
12961
12962 case WLAN_REASON_PREV_AUTH_NOT_VALID:
12963 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053012964 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070012965 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
12966 break;
12967
Jeff Johnson295189b2012-06-20 16:38:30 -070012968 default:
12969 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
12970 break;
12971 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012972 pScanInfo = &pHddCtx->scan_info;
12973 if (pScanInfo->mScanPending)
12974 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012975 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012976 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012977 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012978 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012979 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053012980 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012981#ifdef FEATURE_WLAN_TDLS
12982 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012983 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012984 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012985 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
12986 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012987 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012988 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012989 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012990 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012991 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012992 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012993 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012994 status = sme_DeleteTdlsPeerSta(
12995 WLAN_HDD_GET_HAL_CTX(pAdapter),
12996 pAdapter->sessionId,
12997 mac);
12998 if (status != eHAL_STATUS_SUCCESS) {
12999 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
13000 return -EPERM;
13001 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013002 }
13003 }
13004#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013005 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013006 status = wlan_hdd_disconnect(pAdapter, reasonCode);
13007 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070013008 {
13009 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013010 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013011 __func__, (int)status );
13012 return -EINVAL;
13013 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013014 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053013015 else
13016 {
13017 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
13018 "called while in %d state", __func__,
13019 pHddStaCtx->conn_info.connState);
13020 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013021 }
13022 else
13023 {
13024 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
13025 }
13026
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013027 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013028 return status;
13029}
13030
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013031static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
13032 struct net_device *dev,
13033 u16 reason
13034 )
13035{
13036 int ret;
13037 vos_ssr_protect(__func__);
13038 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
13039 vos_ssr_unprotect(__func__);
13040
13041 return ret;
13042}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013043
Jeff Johnson295189b2012-06-20 16:38:30 -070013044/*
13045 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013046 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070013047 * settings in IBSS mode.
13048 */
13049static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013050 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013051 struct cfg80211_ibss_params *params
13052 )
13053{
13054 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013055 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013056 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13057 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013058
Jeff Johnson295189b2012-06-20 16:38:30 -070013059 ENTER();
13060
13061 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070013062 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070013063
13064 if (params->ie_len && ( NULL != params->ie) )
13065 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013066 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
13067 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070013068 {
13069 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
13070 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13071 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013072 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070013073 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013074 tDot11fIEWPA dot11WPAIE;
13075 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013076 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013077
Wilson Yang00256342013-10-10 23:13:38 -070013078 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013079 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
13080 params->ie_len, DOT11F_EID_WPA);
13081 if ( NULL != ie )
13082 {
13083 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
13084 // Unpack the WPA IE
13085 //Skip past the EID byte and length byte - and four byte WiFi OUI
13086 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
13087 &ie[2+4],
13088 ie[1] - 4,
13089 &dot11WPAIE);
13090 /*Extract the multicast cipher, the encType for unicast
13091 cipher for wpa-none is none*/
13092 encryptionType =
13093 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
13094 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013095 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013096
Jeff Johnson295189b2012-06-20 16:38:30 -070013097 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
13098
13099 if (0 > status)
13100 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013101 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070013102 __func__);
13103 return status;
13104 }
13105 }
13106
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013107 pWextState->roamProfile.AuthType.authType[0] =
13108 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013109 eCSR_AUTH_TYPE_OPEN_SYSTEM;
13110
13111 if (params->privacy)
13112 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013113 /* Security enabled IBSS, At this time there is no information available
13114 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070013115 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013116 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070013117 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013118 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070013119 *enable privacy bit in beacons */
13120
13121 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13122 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013123 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
13124 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070013125 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13126 pWextState->roamProfile.EncryptionType.numEntries = 1;
13127 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070013128 return status;
13129}
13130
13131/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013132 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013133 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070013134 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013135static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013136 struct net_device *dev,
13137 struct cfg80211_ibss_params *params
13138 )
13139{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013140 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013141 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13142 tCsrRoamProfile *pRoamProfile;
13143 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013144 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13145 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013146 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070013147
13148 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013149
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013150 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13151 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
13152 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013153 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013154 "%s: device_mode = %s (%d)", __func__,
13155 hdd_device_modetoString(pAdapter->device_mode),
13156 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013157
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)
Jeff Johnson295189b2012-06-20 16:38:30 -070013160 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013161 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013162 }
13163
13164 if (NULL == pWextState)
13165 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013166 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070013167 __func__);
13168 return -EIO;
13169 }
13170
Agarwal Ashish51325b52014-06-16 16:50:49 +053013171 if (vos_max_concurrent_connections_reached()) {
13172 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13173 return -ECONNREFUSED;
13174 }
13175
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013176 /*Try disconnecting if already in connected state*/
13177 status = wlan_hdd_try_disconnect(pAdapter);
13178 if ( 0 > status)
13179 {
13180 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
13181 " IBSS connection"));
13182 return -EALREADY;
13183 }
13184
Jeff Johnson295189b2012-06-20 16:38:30 -070013185 pRoamProfile = &pWextState->roamProfile;
13186
13187 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
13188 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013189 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013190 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013191 return -EINVAL;
13192 }
13193
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013194 /* BSSID is provided by upper layers hence no need to AUTO generate */
13195 if (NULL != params->bssid) {
13196 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
13197 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
13198 hddLog (VOS_TRACE_LEVEL_ERROR,
13199 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
13200 return -EIO;
13201 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013202 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013203 }
krunal sonie9002db2013-11-25 14:24:17 -080013204 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
13205 {
13206 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
13207 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
13208 {
13209 hddLog (VOS_TRACE_LEVEL_ERROR,
13210 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
13211 return -EIO;
13212 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013213
13214 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080013215 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013216 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080013217 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013218
Jeff Johnson295189b2012-06-20 16:38:30 -070013219 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070013220 if (NULL !=
13221#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
13222 params->chandef.chan)
13223#else
13224 params->channel)
13225#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013226 {
13227 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013228 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13229 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
13230 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13231 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013232
13233 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013234 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070013235 ieee80211_frequency_to_channel(
13236#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
13237 params->chandef.chan->center_freq);
13238#else
13239 params->channel->center_freq);
13240#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013241
13242 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13243 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070013244 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013245 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
13246 __func__);
13247 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070013248 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013249
13250 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013251 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013252 if (channelNum == validChan[indx])
13253 {
13254 break;
13255 }
13256 }
13257 if (indx >= numChans)
13258 {
13259 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013260 __func__, channelNum);
13261 return -EINVAL;
13262 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013263 /* Set the Operational Channel */
13264 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
13265 channelNum);
13266 pRoamProfile->ChannelInfo.numOfChannels = 1;
13267 pHddStaCtx->conn_info.operationChannel = channelNum;
13268 pRoamProfile->ChannelInfo.ChannelList =
13269 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070013270 }
13271
13272 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013273 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070013274 if (status < 0)
13275 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013276 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070013277 __func__);
13278 return status;
13279 }
13280
13281 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013282 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013283 params->ssid_len, params->bssid,
13284 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013285
13286 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013287 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013288
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013289 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013290 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013291}
13292
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013293static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
13294 struct net_device *dev,
13295 struct cfg80211_ibss_params *params
13296 )
13297{
13298 int ret = 0;
13299
13300 vos_ssr_protect(__func__);
13301 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
13302 vos_ssr_unprotect(__func__);
13303
13304 return ret;
13305}
13306
Jeff Johnson295189b2012-06-20 16:38:30 -070013307/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013308 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013309 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070013310 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013311static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013312 struct net_device *dev
13313 )
13314{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013315 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013316 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13317 tCsrRoamProfile *pRoamProfile;
13318 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013319 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013320
13321 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013322
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013323 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13324 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
13325 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013326 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013327 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013328 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013329 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013330 }
13331
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013332 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
13333 hdd_device_modetoString(pAdapter->device_mode),
13334 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013335 if (NULL == pWextState)
13336 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013337 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070013338 __func__);
13339 return -EIO;
13340 }
13341
13342 pRoamProfile = &pWextState->roamProfile;
13343
13344 /* Issue disconnect only if interface type is set to IBSS */
13345 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
13346 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013347 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070013348 __func__);
13349 return -EINVAL;
13350 }
13351
13352 /* Issue Disconnect request */
13353 INIT_COMPLETION(pAdapter->disconnect_comp_var);
13354 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13355 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
13356
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013357 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013358 return 0;
13359}
13360
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013361static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
13362 struct net_device *dev
13363 )
13364{
13365 int ret = 0;
13366
13367 vos_ssr_protect(__func__);
13368 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
13369 vos_ssr_unprotect(__func__);
13370
13371 return ret;
13372}
13373
Jeff Johnson295189b2012-06-20 16:38:30 -070013374/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013375 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070013376 * This function is used to set the phy parameters
13377 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
13378 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013379static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013380 u32 changed)
13381{
13382 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13383 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013384 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013385
13386 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013387
13388 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013389 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
13390 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013391
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013392 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013393 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013394 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013395 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013396 }
13397
Jeff Johnson295189b2012-06-20 16:38:30 -070013398 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
13399 {
13400 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
13401 WNI_CFG_RTS_THRESHOLD_STAMAX :
13402 wiphy->rts_threshold;
13403
13404 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013405 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070013406 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013407 hddLog(VOS_TRACE_LEVEL_ERROR,
13408 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013409 __func__, rts_threshold);
13410 return -EINVAL;
13411 }
13412
13413 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
13414 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013415 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013416 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013417 hddLog(VOS_TRACE_LEVEL_ERROR,
13418 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013419 __func__, rts_threshold);
13420 return -EIO;
13421 }
13422
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013423 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013424 rts_threshold);
13425 }
13426
13427 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
13428 {
13429 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
13430 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
13431 wiphy->frag_threshold;
13432
13433 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013434 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013435 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013436 hddLog(VOS_TRACE_LEVEL_ERROR,
13437 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013438 frag_threshold);
13439 return -EINVAL;
13440 }
13441
13442 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
13443 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013444 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013445 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013446 hddLog(VOS_TRACE_LEVEL_ERROR,
13447 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013448 __func__, frag_threshold);
13449 return -EIO;
13450 }
13451
13452 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
13453 frag_threshold);
13454 }
13455
13456 if ((changed & WIPHY_PARAM_RETRY_SHORT)
13457 || (changed & WIPHY_PARAM_RETRY_LONG))
13458 {
13459 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
13460 wiphy->retry_short :
13461 wiphy->retry_long;
13462
13463 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
13464 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
13465 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013466 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013467 __func__, retry_value);
13468 return -EINVAL;
13469 }
13470
13471 if (changed & WIPHY_PARAM_RETRY_SHORT)
13472 {
13473 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
13474 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013475 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013476 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013477 hddLog(VOS_TRACE_LEVEL_ERROR,
13478 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013479 __func__, retry_value);
13480 return -EIO;
13481 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013482 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013483 __func__, retry_value);
13484 }
13485 else if (changed & WIPHY_PARAM_RETRY_SHORT)
13486 {
13487 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
13488 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013489 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013490 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013491 hddLog(VOS_TRACE_LEVEL_ERROR,
13492 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013493 __func__, retry_value);
13494 return -EIO;
13495 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013496 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013497 __func__, retry_value);
13498 }
13499 }
13500
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013501 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013502 return 0;
13503}
13504
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013505static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
13506 u32 changed)
13507{
13508 int ret;
13509
13510 vos_ssr_protect(__func__);
13511 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
13512 vos_ssr_unprotect(__func__);
13513
13514 return ret;
13515}
13516
Jeff Johnson295189b2012-06-20 16:38:30 -070013517/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013518 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013519 * This function is used to set the txpower
13520 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013521static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013522#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13523 struct wireless_dev *wdev,
13524#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013525#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013526 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013527#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013528 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013529#endif
13530 int dbm)
13531{
13532 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013533 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013534 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13535 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013536 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013537
13538 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013539
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013540 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13541 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
13542 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013543 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013544 if (0 != status)
13545 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013546 return status;
13547 }
13548
13549 hHal = pHddCtx->hHal;
13550
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013551 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
13552 dbm, ccmCfgSetCallback,
13553 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013554 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013555 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013556 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
13557 return -EIO;
13558 }
13559
13560 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
13561 dbm);
13562
13563 switch(type)
13564 {
13565 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
13566 /* Fall through */
13567 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
13568 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
13569 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013570 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
13571 __func__);
13572 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013573 }
13574 break;
13575 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013576 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070013577 __func__);
13578 return -EOPNOTSUPP;
13579 break;
13580 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013581 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
13582 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070013583 return -EIO;
13584 }
13585
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013586 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013587 return 0;
13588}
13589
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013590static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
13591#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13592 struct wireless_dev *wdev,
13593#endif
13594#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13595 enum tx_power_setting type,
13596#else
13597 enum nl80211_tx_power_setting type,
13598#endif
13599 int dbm)
13600{
13601 int ret;
13602 vos_ssr_protect(__func__);
13603 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
13604#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13605 wdev,
13606#endif
13607#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13608 type,
13609#else
13610 type,
13611#endif
13612 dbm);
13613 vos_ssr_unprotect(__func__);
13614
13615 return ret;
13616}
13617
Jeff Johnson295189b2012-06-20 16:38:30 -070013618/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013619 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013620 * This function is used to read the txpower
13621 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013622static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013623#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13624 struct wireless_dev *wdev,
13625#endif
13626 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070013627{
13628
13629 hdd_adapter_t *pAdapter;
13630 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013631 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013632
Jeff Johnsone7245742012-09-05 17:12:55 -070013633 ENTER();
13634
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013635 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013636 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013637 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013638 *dbm = 0;
13639 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013640 }
13641
Jeff Johnson295189b2012-06-20 16:38:30 -070013642 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
13643 if (NULL == pAdapter)
13644 {
13645 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
13646 return -ENOENT;
13647 }
13648
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053013649 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13650 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
13651 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013652 wlan_hdd_get_classAstats(pAdapter);
13653 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
13654
Jeff Johnsone7245742012-09-05 17:12:55 -070013655 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013656 return 0;
13657}
13658
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013659static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
13660#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13661 struct wireless_dev *wdev,
13662#endif
13663 int *dbm)
13664{
13665 int ret;
13666
13667 vos_ssr_protect(__func__);
13668 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
13669#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13670 wdev,
13671#endif
13672 dbm);
13673 vos_ssr_unprotect(__func__);
13674
13675 return ret;
13676}
13677
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013678static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013679#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13680 const u8* mac,
13681#else
13682 u8* mac,
13683#endif
13684 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070013685{
13686 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13687 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13688 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053013689 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013690
13691 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
13692 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070013693
13694 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
13695 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
13696 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
13697 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
13698 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
13699 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
13700 tANI_U16 maxRate = 0;
13701 tANI_U16 myRate;
13702 tANI_U16 currentRate = 0;
13703 tANI_U8 maxSpeedMCS = 0;
13704 tANI_U8 maxMCSIdx = 0;
13705 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053013706 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013707 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013708 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013709
Leo Chang6f8870f2013-03-26 18:11:36 -070013710#ifdef WLAN_FEATURE_11AC
13711 tANI_U32 vht_mcs_map;
13712 eDataRate11ACMaxMcs vhtMaxMcs;
13713#endif /* WLAN_FEATURE_11AC */
13714
Jeff Johnsone7245742012-09-05 17:12:55 -070013715 ENTER();
13716
Jeff Johnson295189b2012-06-20 16:38:30 -070013717 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
13718 (0 == ssidlen))
13719 {
13720 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
13721 " Invalid ssidlen, %d", __func__, ssidlen);
13722 /*To keep GUI happy*/
13723 return 0;
13724 }
13725
Mukul Sharma811205f2014-07-09 21:07:30 +053013726 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
13727 {
13728 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13729 "%s: Roaming in progress, so unable to proceed this request", __func__);
13730 return 0;
13731 }
13732
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013733 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013734 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013735 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013736 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013737 }
13738
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053013739 wlan_hdd_get_station_stats(pAdapter);
13740 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013741
Kiet Lam3b17fc82013-09-27 05:24:08 +053013742 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
13743 sinfo->filled |= STATION_INFO_SIGNAL;
13744
c_hpothu09f19542014-05-30 21:53:31 +053013745 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053013746 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
13747 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053013748 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053013749 {
13750 rate_flags = pAdapter->maxRateFlags;
13751 }
c_hpothu44ff4e02014-05-08 00:13:57 +053013752
Jeff Johnson295189b2012-06-20 16:38:30 -070013753 //convert to the UI units of 100kbps
13754 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
13755
13756#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070013757 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 -070013758 sinfo->signal,
13759 pCfg->reportMaxLinkSpeed,
13760 myRate,
13761 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013762 (int) pCfg->linkSpeedRssiMid,
13763 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070013764 (int) rate_flags,
13765 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013766#endif //LINKSPEED_DEBUG_ENABLED
13767
13768 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
13769 {
13770 // we do not want to necessarily report the current speed
13771 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
13772 {
13773 // report the max possible speed
13774 rssidx = 0;
13775 }
13776 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
13777 {
13778 // report the max possible speed with RSSI scaling
13779 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
13780 {
13781 // report the max possible speed
13782 rssidx = 0;
13783 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013784 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070013785 {
13786 // report middle speed
13787 rssidx = 1;
13788 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013789 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
13790 {
13791 // report middle speed
13792 rssidx = 2;
13793 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013794 else
13795 {
13796 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013797 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070013798 }
13799 }
13800 else
13801 {
13802 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
13803 hddLog(VOS_TRACE_LEVEL_ERROR,
13804 "%s: Invalid value for reportMaxLinkSpeed: %u",
13805 __func__, pCfg->reportMaxLinkSpeed);
13806 rssidx = 0;
13807 }
13808
13809 maxRate = 0;
13810
13811 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013812 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
13813 OperationalRates, &ORLeng))
13814 {
13815 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13816 /*To keep GUI happy*/
13817 return 0;
13818 }
13819
Jeff Johnson295189b2012-06-20 16:38:30 -070013820 for (i = 0; i < ORLeng; i++)
13821 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013822 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013823 {
13824 /* Validate Rate Set */
13825 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
13826 {
13827 currentRate = supported_data_rate[j].supported_rate[rssidx];
13828 break;
13829 }
13830 }
13831 /* Update MAX rate */
13832 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13833 }
13834
13835 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013836 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
13837 ExtendedRates, &ERLeng))
13838 {
13839 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13840 /*To keep GUI happy*/
13841 return 0;
13842 }
13843
Jeff Johnson295189b2012-06-20 16:38:30 -070013844 for (i = 0; i < ERLeng; i++)
13845 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013846 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013847 {
13848 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
13849 {
13850 currentRate = supported_data_rate[j].supported_rate[rssidx];
13851 break;
13852 }
13853 }
13854 /* Update MAX rate */
13855 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13856 }
c_hpothu79aab322014-07-14 21:11:01 +053013857
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013858 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053013859 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013860 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053013861 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070013862 {
c_hpothu79aab322014-07-14 21:11:01 +053013863 if (rate_flags & eHAL_TX_RATE_VHT80)
13864 mode = 2;
13865 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
13866 mode = 1;
13867 else
13868 mode = 0;
13869
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013870 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
13871 MCSRates, &MCSLeng))
13872 {
13873 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13874 /*To keep GUI happy*/
13875 return 0;
13876 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013877 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070013878#ifdef WLAN_FEATURE_11AC
13879 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013880 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070013881 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013882 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013883 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070013884 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070013885 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013886 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013887 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013888 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070013889 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013890 maxMCSIdx = 7;
13891 }
13892 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
13893 {
13894 maxMCSIdx = 8;
13895 }
13896 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
13897 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013898 //VHT20 is supporting 0~8
13899 if (rate_flags & eHAL_TX_RATE_VHT20)
13900 maxMCSIdx = 8;
13901 else
13902 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070013903 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013904
c_hpothu79aab322014-07-14 21:11:01 +053013905 if (0 != rssidx)/*check for scaled */
13906 {
13907 //get middle rate MCS index if rssi=1/2
13908 for (i=0; i <= maxMCSIdx; i++)
13909 {
13910 if (sinfo->signal <= rssiMcsTbl[mode][i])
13911 {
13912 maxMCSIdx = i;
13913 break;
13914 }
13915 }
13916 }
13917
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013918 if (rate_flags & eHAL_TX_RATE_VHT80)
13919 {
13920 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
13921 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
13922 }
13923 else if (rate_flags & eHAL_TX_RATE_VHT40)
13924 {
13925 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
13926 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
13927 }
13928 else if (rate_flags & eHAL_TX_RATE_VHT20)
13929 {
13930 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
13931 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
13932 }
13933
Leo Chang6f8870f2013-03-26 18:11:36 -070013934 maxSpeedMCS = 1;
13935 if (currentRate > maxRate)
13936 {
13937 maxRate = currentRate;
13938 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013939
Leo Chang6f8870f2013-03-26 18:11:36 -070013940 }
13941 else
13942#endif /* WLAN_FEATURE_11AC */
13943 {
13944 if (rate_flags & eHAL_TX_RATE_HT40)
13945 {
13946 rateFlag |= 1;
13947 }
13948 if (rate_flags & eHAL_TX_RATE_SGI)
13949 {
13950 rateFlag |= 2;
13951 }
13952
Girish Gowli01abcee2014-07-31 20:18:55 +053013953 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053013954 if (rssidx == 1 || rssidx == 2)
13955 {
13956 //get middle rate MCS index if rssi=1/2
13957 for (i=0; i <= 7; i++)
13958 {
13959 if (sinfo->signal <= rssiMcsTbl[mode][i])
13960 {
13961 temp = i+1;
13962 break;
13963 }
13964 }
13965 }
c_hpothu79aab322014-07-14 21:11:01 +053013966
13967 for (i = 0; i < MCSLeng; i++)
13968 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013969 for (j = 0; j < temp; j++)
13970 {
13971 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
13972 {
13973 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053013974 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013975 break;
13976 }
13977 }
13978 if ((j < temp) && (currentRate > maxRate))
13979 {
13980 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070013981 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013982 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053013983 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013984 }
13985 }
13986
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013987 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
13988 {
13989 maxRate = myRate;
13990 maxSpeedMCS = 1;
13991 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13992 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013993 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053013994 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070013995 {
13996 maxRate = myRate;
13997 if (rate_flags & eHAL_TX_RATE_LEGACY)
13998 {
13999 maxSpeedMCS = 0;
14000 }
14001 else
14002 {
14003 maxSpeedMCS = 1;
14004 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
14005 }
14006 }
14007
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014008 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070014009 {
14010 sinfo->txrate.legacy = maxRate;
14011#ifdef LINKSPEED_DEBUG_ENABLED
14012 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
14013#endif //LINKSPEED_DEBUG_ENABLED
14014 }
14015 else
14016 {
14017 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070014018#ifdef WLAN_FEATURE_11AC
14019 sinfo->txrate.nss = 1;
14020 if (rate_flags & eHAL_TX_RATE_VHT80)
14021 {
14022 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014023 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070014024 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014025 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070014026 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014027 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14028 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14029 }
14030 else if (rate_flags & eHAL_TX_RATE_VHT20)
14031 {
14032 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14033 }
14034#endif /* WLAN_FEATURE_11AC */
14035 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
14036 {
14037 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
14038 if (rate_flags & eHAL_TX_RATE_HT40)
14039 {
14040 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14041 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014042 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014043 if (rate_flags & eHAL_TX_RATE_SGI)
14044 {
14045 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
14046 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014047
Jeff Johnson295189b2012-06-20 16:38:30 -070014048#ifdef LINKSPEED_DEBUG_ENABLED
14049 pr_info("Reporting MCS rate %d flags %x\n",
14050 sinfo->txrate.mcs,
14051 sinfo->txrate.flags );
14052#endif //LINKSPEED_DEBUG_ENABLED
14053 }
14054 }
14055 else
14056 {
14057 // report current rate instead of max rate
14058
14059 if (rate_flags & eHAL_TX_RATE_LEGACY)
14060 {
14061 //provide to the UI in units of 100kbps
14062 sinfo->txrate.legacy = myRate;
14063#ifdef LINKSPEED_DEBUG_ENABLED
14064 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
14065#endif //LINKSPEED_DEBUG_ENABLED
14066 }
14067 else
14068 {
14069 //must be MCS
14070 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070014071#ifdef WLAN_FEATURE_11AC
14072 sinfo->txrate.nss = 1;
14073 if (rate_flags & eHAL_TX_RATE_VHT80)
14074 {
14075 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14076 }
14077 else
14078#endif /* WLAN_FEATURE_11AC */
14079 {
14080 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
14081 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014082 if (rate_flags & eHAL_TX_RATE_SGI)
14083 {
14084 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
14085 }
14086 if (rate_flags & eHAL_TX_RATE_HT40)
14087 {
14088 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14089 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014090#ifdef WLAN_FEATURE_11AC
14091 else if (rate_flags & eHAL_TX_RATE_VHT80)
14092 {
14093 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
14094 }
14095#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070014096#ifdef LINKSPEED_DEBUG_ENABLED
14097 pr_info("Reporting actual MCS rate %d flags %x\n",
14098 sinfo->txrate.mcs,
14099 sinfo->txrate.flags );
14100#endif //LINKSPEED_DEBUG_ENABLED
14101 }
14102 }
14103 sinfo->filled |= STATION_INFO_TX_BITRATE;
14104
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070014105 sinfo->tx_packets =
14106 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
14107 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
14108 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
14109 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
14110
14111 sinfo->tx_retries =
14112 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
14113 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
14114 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
14115 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
14116
14117 sinfo->tx_failed =
14118 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
14119 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
14120 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
14121 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
14122
14123 sinfo->filled |=
14124 STATION_INFO_TX_PACKETS |
14125 STATION_INFO_TX_RETRIES |
14126 STATION_INFO_TX_FAILED;
14127
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014128 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14129 TRACE_CODE_HDD_CFG80211_GET_STA,
14130 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070014131 EXIT();
14132 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014133}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014134#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14135static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
14136 const u8* mac, struct station_info *sinfo)
14137#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014138static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
14139 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014140#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014141{
14142 int ret;
14143
14144 vos_ssr_protect(__func__);
14145 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
14146 vos_ssr_unprotect(__func__);
14147
14148 return ret;
14149}
14150
14151static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070014152 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070014153{
14154 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014155 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014156 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014157 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014158
Jeff Johnsone7245742012-09-05 17:12:55 -070014159 ENTER();
14160
Jeff Johnson295189b2012-06-20 16:38:30 -070014161 if (NULL == pAdapter)
14162 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014163 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014164 return -ENODEV;
14165 }
14166
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014167 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14168 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
14169 pAdapter->sessionId, timeout));
14170
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014171 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014172 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014173 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014174 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014175 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014176 }
14177
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014178 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
14179 (TRUE == pHddCtx->hdd_wlan_suspended) &&
14180 (pHddCtx->cfg_ini->fhostArpOffload) &&
14181 (eConnectionState_Associated ==
14182 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14183 {
Amar Singhald53568e2013-09-26 11:03:45 -070014184
14185 hddLog(VOS_TRACE_LEVEL_INFO,
14186 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053014187 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014188 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14189 {
14190 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014191 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014192 __func__, vos_status);
14193 }
14194 }
14195
Jeff Johnson295189b2012-06-20 16:38:30 -070014196 /**The get power cmd from the supplicant gets updated by the nl only
14197 *on successful execution of the function call
14198 *we are oppositely mapped w.r.t mode in the driver
14199 **/
14200 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
14201
14202 if (VOS_STATUS_E_FAILURE == vos_status)
14203 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014204 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14205 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014206 return -EINVAL;
14207 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014208 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014209 return 0;
14210}
14211
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014212static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
14213 struct net_device *dev, bool mode, int timeout)
14214{
14215 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014216
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014217 vos_ssr_protect(__func__);
14218 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
14219 vos_ssr_unprotect(__func__);
14220
14221 return ret;
14222}
Jeff Johnson295189b2012-06-20 16:38:30 -070014223#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014224static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
14225 struct net_device *netdev,
14226 u8 key_index)
14227{
14228 ENTER();
14229 return 0;
14230}
14231
Jeff Johnson295189b2012-06-20 16:38:30 -070014232static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014233 struct net_device *netdev,
14234 u8 key_index)
14235{
14236 int ret;
14237 vos_ssr_protect(__func__);
14238 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
14239 vos_ssr_unprotect(__func__);
14240 return ret;
14241}
14242#endif //LINUX_VERSION_CODE
14243
14244#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
14245static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
14246 struct net_device *dev,
14247 struct ieee80211_txq_params *params)
14248{
14249 ENTER();
14250 return 0;
14251}
14252#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14253static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
14254 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070014255{
Jeff Johnsone7245742012-09-05 17:12:55 -070014256 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070014257 return 0;
14258}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014259#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070014260
14261#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
14262static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014263 struct net_device *dev,
14264 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070014265{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014266 int ret;
14267
14268 vos_ssr_protect(__func__);
14269 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
14270 vos_ssr_unprotect(__func__);
14271 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014272}
14273#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14274static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
14275 struct ieee80211_txq_params *params)
14276{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014277 int ret;
14278
14279 vos_ssr_protect(__func__);
14280 ret = __wlan_hdd_set_txq_params(wiphy, params);
14281 vos_ssr_unprotect(__func__);
14282 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014283}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014284#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014285
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014286static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014287 struct net_device *dev,
14288 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070014289{
14290 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014291 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014292 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014293 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014294 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014295 v_CONTEXT_t pVosContext = NULL;
14296 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014297
Jeff Johnsone7245742012-09-05 17:12:55 -070014298 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014299
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014300 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070014301 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014302 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014303 return -EINVAL;
14304 }
14305
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014306 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14307 TRACE_CODE_HDD_CFG80211_DEL_STA,
14308 pAdapter->sessionId, pAdapter->device_mode));
14309
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014310 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14311 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014312 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014313 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014314 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014315 }
14316
Jeff Johnson295189b2012-06-20 16:38:30 -070014317 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014318 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014319 )
14320 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014321 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14322 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14323 if(pSapCtx == NULL){
14324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14325 FL("psapCtx is NULL"));
14326 return -ENOENT;
14327 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014328 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070014329 {
14330 v_U16_t i;
14331 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
14332 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014333 if ((pSapCtx->aStaInfo[i].isUsed) &&
14334 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070014335 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014336 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014337 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014338 ETHER_ADDR_LEN);
14339
Jeff Johnson295189b2012-06-20 16:38:30 -070014340 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014341 "%s: Delete STA with MAC::"
14342 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014343 __func__,
14344 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
14345 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070014346 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014347 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014348 }
14349 }
14350 }
14351 else
14352 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014353
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014354 vos_status = hdd_softap_GetStaId(pAdapter,
14355 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014356 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14357 {
14358 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014359 "%s: Skip this DEL STA as this is not used::"
14360 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014361 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014362 return -ENOENT;
14363 }
14364
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014365 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014366 {
14367 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014368 "%s: Skip this DEL STA as deauth is in progress::"
14369 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014370 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014371 return -ENOENT;
14372 }
14373
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014374 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014375
Jeff Johnson295189b2012-06-20 16:38:30 -070014376 hddLog(VOS_TRACE_LEVEL_INFO,
14377 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014378 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014379 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014380 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014381
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014382 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014383 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14384 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014385 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014386 hddLog(VOS_TRACE_LEVEL_INFO,
14387 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014388 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014389 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014390 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014391 return -ENOENT;
14392 }
14393
Jeff Johnson295189b2012-06-20 16:38:30 -070014394 }
14395 }
14396
14397 EXIT();
14398
14399 return 0;
14400}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014401
14402#ifdef CFG80211_DEL_STA_V2
14403static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14404 struct net_device *dev,
14405 struct station_del_parameters *param)
14406#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014407#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14408static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14409 struct net_device *dev, const u8 *mac)
14410#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014411static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14412 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014413#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014414#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014415{
14416 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014417 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070014418
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014419 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014420
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014421#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014422 if (NULL == param) {
14423 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014424 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014425 return -EINVAL;
14426 }
14427
14428 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
14429 param->subtype, &delStaParams);
14430
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014431#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014432 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014433 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014434#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014435 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
14436
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014437 vos_ssr_unprotect(__func__);
14438
14439 return ret;
14440}
14441
14442static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014443 struct net_device *dev,
14444#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14445 const u8 *mac,
14446#else
14447 u8 *mac,
14448#endif
14449 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014450{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014451 hdd_adapter_t *pAdapter;
14452 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014453 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014454#ifdef FEATURE_WLAN_TDLS
14455 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014456
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014457 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014458
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014459 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14460 if (NULL == pAdapter)
14461 {
14462 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14463 "%s: Adapter is NULL",__func__);
14464 return -EINVAL;
14465 }
14466 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14467 status = wlan_hdd_validate_context(pHddCtx);
14468 if (0 != status)
14469 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014470 return status;
14471 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014472
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014473 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14474 TRACE_CODE_HDD_CFG80211_ADD_STA,
14475 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014476 mask = params->sta_flags_mask;
14477
14478 set = params->sta_flags_set;
14479
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014481 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
14482 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014483
14484 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
14485 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014486 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014487 }
14488 }
14489#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014490 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014491 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014492}
14493
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014494#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14495static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14496 struct net_device *dev, const u8 *mac,
14497 struct station_parameters *params)
14498#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014499static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14500 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014501#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014502{
14503 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014504
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014505 vos_ssr_protect(__func__);
14506 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
14507 vos_ssr_unprotect(__func__);
14508
14509 return ret;
14510}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014511#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070014512
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014513static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070014514 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014515{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014516 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14517 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014518 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014519 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014520 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014521 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070014522
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014523 ENTER();
14524
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014525 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014526 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014527 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014528 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014529 return -EINVAL;
14530 }
14531
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014532 if (!pmksa) {
14533 hddLog(LOGE, FL("pmksa is NULL"));
14534 return -EINVAL;
14535 }
14536
14537 if (!pmksa->bssid || !pmksa->pmkid) {
14538 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
14539 pmksa->bssid, pmksa->pmkid);
14540 return -EINVAL;
14541 }
14542
14543 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
14544 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14545
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014546 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14547 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014548 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014549 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014550 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014551 }
14552
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014553 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014554 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14555
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014556 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
14557 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014558
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014559 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014560 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014561 &pmk_id, 1, FALSE);
14562
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014563 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14564 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
14565 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014566
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014567 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014568 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014569}
14570
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014571static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
14572 struct cfg80211_pmksa *pmksa)
14573{
14574 int ret;
14575
14576 vos_ssr_protect(__func__);
14577 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
14578 vos_ssr_unprotect(__func__);
14579
14580 return ret;
14581}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014582
Wilson Yang6507c4e2013-10-01 20:11:19 -070014583
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014584static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070014585 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014586{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014587 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14588 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014589 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014590 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014591
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014592 ENTER();
14593
Wilson Yang6507c4e2013-10-01 20:11:19 -070014594 /* Validate pAdapter */
14595 if (NULL == pAdapter)
14596 {
14597 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
14598 return -EINVAL;
14599 }
14600
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014601 if (!pmksa) {
14602 hddLog(LOGE, FL("pmksa is NULL"));
14603 return -EINVAL;
14604 }
14605
14606 if (!pmksa->bssid) {
14607 hddLog(LOGE, FL("pmksa->bssid is NULL"));
14608 return -EINVAL;
14609 }
14610
Kiet Lam98c46a12014-10-31 15:34:57 -070014611 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
14612 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14613
Wilson Yang6507c4e2013-10-01 20:11:19 -070014614 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14615 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014616 if (0 != status)
14617 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014618 return status;
14619 }
14620
14621 /*Retrieve halHandle*/
14622 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14623
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014624 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14625 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
14626 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014627 /* Delete the PMKID CSR cache */
14628 if (eHAL_STATUS_SUCCESS !=
14629 sme_RoamDelPMKIDfromCache(halHandle,
14630 pAdapter->sessionId, pmksa->bssid, FALSE)) {
14631 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
14632 MAC_ADDR_ARRAY(pmksa->bssid));
14633 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014634 }
14635
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014636 EXIT();
14637 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014638}
14639
Wilson Yang6507c4e2013-10-01 20:11:19 -070014640
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014641static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
14642 struct cfg80211_pmksa *pmksa)
14643{
14644 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014645
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014646 vos_ssr_protect(__func__);
14647 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
14648 vos_ssr_unprotect(__func__);
14649
14650 return ret;
14651
14652}
14653
14654static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014655{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014656 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14657 tHalHandle halHandle;
14658 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014659 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014660
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014661 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070014662
14663 /* Validate pAdapter */
14664 if (NULL == pAdapter)
14665 {
14666 hddLog(VOS_TRACE_LEVEL_ERROR,
14667 "%s: Invalid Adapter" ,__func__);
14668 return -EINVAL;
14669 }
14670
14671 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14672 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014673 if (0 != status)
14674 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014675 return status;
14676 }
14677
14678 /*Retrieve halHandle*/
14679 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14680
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014681 /* Flush the PMKID cache in CSR */
14682 if (eHAL_STATUS_SUCCESS !=
14683 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
14684 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
14685 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014686 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014687 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080014688 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014689}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014690
14691static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
14692{
14693 int ret;
14694
14695 vos_ssr_protect(__func__);
14696 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
14697 vos_ssr_unprotect(__func__);
14698
14699 return ret;
14700}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014701#endif
14702
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014703#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014704static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14705 struct net_device *dev,
14706 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014707{
14708 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14709 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014710 hdd_context_t *pHddCtx;
14711 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014712
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014713 ENTER();
14714
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014715 if (NULL == pAdapter)
14716 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014717 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014718 return -ENODEV;
14719 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014720 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14721 ret = wlan_hdd_validate_context(pHddCtx);
14722 if (0 != ret)
14723 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014724 return ret;
14725 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014726 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014727 if (NULL == pHddStaCtx)
14728 {
14729 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
14730 return -EINVAL;
14731 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014732
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014733 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14734 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
14735 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014736 // Added for debug on reception of Re-assoc Req.
14737 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
14738 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014739 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014740 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080014741 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014742 }
14743
14744#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080014745 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014746 ftie->ie_len);
14747#endif
14748
14749 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014750 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
14751 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014752 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014753
14754 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014755 return 0;
14756}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014757
14758static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14759 struct net_device *dev,
14760 struct cfg80211_update_ft_ies_params *ftie)
14761{
14762 int ret;
14763
14764 vos_ssr_protect(__func__);
14765 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
14766 vos_ssr_unprotect(__func__);
14767
14768 return ret;
14769}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014770#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014771
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014772#ifdef FEATURE_WLAN_SCAN_PNO
14773
14774void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
14775 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
14776{
14777 int ret;
14778 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
14779 hdd_context_t *pHddCtx;
14780
Nirav Shah80830bf2013-12-31 16:35:12 +053014781 ENTER();
14782
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014783 if (NULL == pAdapter)
14784 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014785 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014786 "%s: HDD adapter is Null", __func__);
14787 return ;
14788 }
14789
14790 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14791 if (NULL == pHddCtx)
14792 {
14793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14794 "%s: HDD context is Null!!!", __func__);
14795 return ;
14796 }
14797
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014798 spin_lock(&pHddCtx->schedScan_lock);
14799 if (TRUE == pHddCtx->isWiphySuspended)
14800 {
14801 pHddCtx->isSchedScanUpdatePending = TRUE;
14802 spin_unlock(&pHddCtx->schedScan_lock);
14803 hddLog(VOS_TRACE_LEVEL_INFO,
14804 "%s: Update cfg80211 scan database after it resume", __func__);
14805 return ;
14806 }
14807 spin_unlock(&pHddCtx->schedScan_lock);
14808
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014809 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
14810
14811 if (0 > ret)
14812 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
14813
14814 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14816 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014817}
14818
14819/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014820 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014821 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014822 */
14823static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
14824{
14825 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14826 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014827 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014828 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14829 int status = 0;
14830 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
14831
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014832 /* The current firmware design does not allow PNO during any
14833 * active sessions. Hence, determine the active sessions
14834 * and return a failure.
14835 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014836 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
14837 {
14838 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014839 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014840
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014841 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
14842 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
14843 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
14844 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
14845 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053014846 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014847 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014848 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014849 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014850 }
14851 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14852 pAdapterNode = pNext;
14853 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014854 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014855}
14856
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014857void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
14858{
14859 hdd_adapter_t *pAdapter = callbackContext;
14860 hdd_context_t *pHddCtx;
14861
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014862 ENTER();
14863
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014864 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
14865 {
14866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14867 FL("Invalid adapter or adapter has invalid magic"));
14868 return;
14869 }
14870
14871 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14872 if (0 != wlan_hdd_validate_context(pHddCtx))
14873 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014874 return;
14875 }
14876
c_hpothub53c45d2014-08-18 16:53:14 +053014877 if (VOS_STATUS_SUCCESS != status)
14878 {
14879 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014880 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053014881 pHddCtx->isPnoEnable = FALSE;
14882 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014883
14884 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
14885 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014886 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014887}
14888
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014889/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014890 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
14891 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014892 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014893static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014894 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14895{
14896 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014897 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014898 hdd_context_t *pHddCtx;
14899 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014900 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053014901 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
14902 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014903 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14904 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014905 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014906 hdd_config_t *pConfig = NULL;
14907 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014908
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014909 ENTER();
14910
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014911 if (NULL == pAdapter)
14912 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014914 "%s: HDD adapter is Null", __func__);
14915 return -ENODEV;
14916 }
14917
14918 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014919 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014920
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014921 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014922 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014923 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014924 }
14925
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014926 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014927 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14928 if (NULL == hHal)
14929 {
14930 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14931 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014932 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014933 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014934 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14935 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
14936 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053014937 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014938 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053014939 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014940 {
14941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14942 "%s: aborting the existing scan is unsuccessfull", __func__);
14943 return -EBUSY;
14944 }
14945
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014946 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014947 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014949 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014950 return -EBUSY;
14951 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014952
c_hpothu37f21312014-04-09 21:49:54 +053014953 if (TRUE == pHddCtx->isPnoEnable)
14954 {
14955 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14956 FL("already PNO is enabled"));
14957 return -EBUSY;
14958 }
c_hpothu225aa7c2014-10-22 17:45:13 +053014959
14960 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
14961 {
14962 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14963 "%s: abort ROC failed ", __func__);
14964 return -EBUSY;
14965 }
14966
c_hpothu37f21312014-04-09 21:49:54 +053014967 pHddCtx->isPnoEnable = TRUE;
14968
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014969 pnoRequest.enable = 1; /*Enable PNO */
14970 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014971
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014972 if (( !pnoRequest.ucNetworksCount ) ||
14973 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014974 {
14975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014976 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014977 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014978 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014979 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014980 goto error;
14981 }
14982
14983 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
14984 {
14985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014986 "%s: Incorrect number of channels %d",
14987 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014988 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014989 goto error;
14990 }
14991
14992 /* Framework provides one set of channels(all)
14993 * common for all saved profile */
14994 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14995 channels_allowed, &num_channels_allowed))
14996 {
14997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14998 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014999 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015000 goto error;
15001 }
15002 /* Checking each channel against allowed channel list */
15003 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053015004 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015005 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015006 char chList [(request->n_channels*5)+1];
15007 int len;
15008 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015009 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015010 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015011 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015012 if (request->channels[i]->hw_value == channels_allowed[indx])
15013 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015014 if ((!pConfig->enableDFSPnoChnlScan) &&
15015 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
15016 {
15017 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15018 "%s : Dropping DFS channel : %d",
15019 __func__,channels_allowed[indx]);
15020 num_ignore_dfs_ch++;
15021 break;
15022 }
15023
Nirav Shah80830bf2013-12-31 16:35:12 +053015024 valid_ch[num_ch++] = request->channels[i]->hw_value;
15025 len += snprintf(chList+len, 5, "%d ",
15026 request->channels[i]->hw_value);
15027 break ;
15028 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015029 }
15030 }
Nirav Shah80830bf2013-12-31 16:35:12 +053015031 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015032
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015033 /*If all channels are DFS and dropped, then ignore the PNO request*/
15034 if (num_ignore_dfs_ch == request->n_channels)
15035 {
15036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15037 "%s : All requested channels are DFS channels", __func__);
15038 ret = -EINVAL;
15039 goto error;
15040 }
15041 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015042
15043 pnoRequest.aNetworks =
15044 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15045 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015046 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015047 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15048 FL("failed to allocate memory aNetworks %u"),
15049 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15050 goto error;
15051 }
15052 vos_mem_zero(pnoRequest.aNetworks,
15053 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15054
15055 /* Filling per profile params */
15056 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
15057 {
15058 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015059 request->match_sets[i].ssid.ssid_len;
15060
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015061 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
15062 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015063 {
15064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015065 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015066 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015067 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015068 goto error;
15069 }
15070
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015071 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015072 request->match_sets[i].ssid.ssid,
15073 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015074 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15075 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015076 i, pnoRequest.aNetworks[i].ssId.ssId);
15077 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
15078 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
15079 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015080
15081 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015082 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
15083 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015084
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015085 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015086 }
15087
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015088 for (i = 0; i < request->n_ssids; i++)
15089 {
15090 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015091 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015092 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015093 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015094 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015095 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015096 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015097 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015098 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015099 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015100 break;
15101 }
15102 j++;
15103 }
15104 }
15105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15106 "Number of hidden networks being Configured = %d",
15107 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015108 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080015109 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015110
15111 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
15112 if (pnoRequest.p24GProbeTemplate == NULL)
15113 {
15114 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15115 FL("failed to allocate memory p24GProbeTemplate %u"),
15116 SIR_PNO_MAX_PB_REQ_SIZE);
15117 goto error;
15118 }
15119
15120 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
15121 if (pnoRequest.p5GProbeTemplate == NULL)
15122 {
15123 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15124 FL("failed to allocate memory p5GProbeTemplate %u"),
15125 SIR_PNO_MAX_PB_REQ_SIZE);
15126 goto error;
15127 }
15128
15129 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
15130 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
15131
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053015132 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
15133 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015134 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015135 pnoRequest.us24GProbeTemplateLen = request->ie_len;
15136 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
15137 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015138
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015139 pnoRequest.us5GProbeTemplateLen = request->ie_len;
15140 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
15141 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015142 }
15143
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015144 /* Driver gets only one time interval which is hardcoded in
15145 * supplicant for 10000ms. Taking power consumption into account 6 timers
15146 * will be used, Timervalue is increased exponentially i.e 10,20,40,
15147 * 80,160,320 secs. And number of scan cycle for each timer
15148 * is configurable through INI param gPNOScanTimerRepeatValue.
15149 * If it is set to 0 only one timer will be used and PNO scan cycle
15150 * will be repeated after each interval specified by supplicant
15151 * till PNO is disabled.
15152 */
15153 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015154 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015155 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015156 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015157 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
15158
15159 tempInterval = (request->interval)/1000;
15160 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15161 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
15162 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015163 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015164 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015165 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015166 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015167 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015168 tempInterval *= 2;
15169 }
15170 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015171 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015172
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015173 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015174
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015175 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015176 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
15177 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015178 pAdapter->pno_req_status = 0;
15179
Nirav Shah80830bf2013-12-31 16:35:12 +053015180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15181 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015182 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
15183 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053015184
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015185 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015186 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015187 hdd_cfg80211_sched_scan_done_callback, pAdapter);
15188 if (eHAL_STATUS_SUCCESS != status)
15189 {
15190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015191 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015192 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015193 goto error;
15194 }
15195
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015196 ret = wait_for_completion_timeout(
15197 &pAdapter->pno_comp_var,
15198 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
15199 if (0 >= ret)
15200 {
15201 // Did not receive the response for PNO enable in time.
15202 // Assuming the PNO enable was success.
15203 // Returning error from here, because we timeout, results
15204 // in side effect of Wifi (Wifi Setting) not to work.
15205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15206 FL("Timed out waiting for PNO to be Enabled"));
15207 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015208 }
15209
15210 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053015211 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015212
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015213error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15215 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053015216 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015217 if (pnoRequest.aNetworks)
15218 vos_mem_free(pnoRequest.aNetworks);
15219 if (pnoRequest.p24GProbeTemplate)
15220 vos_mem_free(pnoRequest.p24GProbeTemplate);
15221 if (pnoRequest.p5GProbeTemplate)
15222 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015223
15224 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015225 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015226}
15227
15228/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015229 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
15230 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015231 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015232static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
15233 struct net_device *dev, struct cfg80211_sched_scan_request *request)
15234{
15235 int ret;
15236
15237 vos_ssr_protect(__func__);
15238 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
15239 vos_ssr_unprotect(__func__);
15240
15241 return ret;
15242}
15243
15244/*
15245 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
15246 * Function to disable PNO
15247 */
15248static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015249 struct net_device *dev)
15250{
15251 eHalStatus status = eHAL_STATUS_FAILURE;
15252 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15253 hdd_context_t *pHddCtx;
15254 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015255 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015256 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015257
15258 ENTER();
15259
15260 if (NULL == pAdapter)
15261 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015262 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015263 "%s: HDD adapter is Null", __func__);
15264 return -ENODEV;
15265 }
15266
15267 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015268
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015269 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015270 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015272 "%s: HDD context is Null", __func__);
15273 return -ENODEV;
15274 }
15275
15276 /* The return 0 is intentional when isLogpInProgress and
15277 * isLoadUnloadInProgress. We did observe a crash due to a return of
15278 * failure in sched_scan_stop , especially for a case where the unload
15279 * of the happens at the same time. The function __cfg80211_stop_sched_scan
15280 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
15281 * success. If it returns a failure , then its next invocation due to the
15282 * clean up of the second interface will have the dev pointer corresponding
15283 * to the first one leading to a crash.
15284 */
15285 if (pHddCtx->isLogpInProgress)
15286 {
15287 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15288 "%s: LOGP in Progress. Ignore!!!", __func__);
15289 return ret;
15290 }
15291
Mihir Shete18156292014-03-11 15:38:30 +053015292 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015293 {
15294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15295 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15296 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015297 }
15298
15299 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15300 if (NULL == hHal)
15301 {
15302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15303 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015304 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015305 }
15306
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015307 pnoRequest.enable = 0; /* Disable PNO */
15308 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015309
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015310 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15311 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
15312 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015313 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015314 pAdapter->sessionId,
15315 NULL, pAdapter);
15316 if (eHAL_STATUS_SUCCESS != status)
15317 {
15318 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15319 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015320 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015321 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015322 }
c_hpothu37f21312014-04-09 21:49:54 +053015323 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015324
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015325error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015327 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015328
15329 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015330 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015331}
15332
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015333/*
15334 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
15335 * NL interface to disable PNO
15336 */
15337static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
15338 struct net_device *dev)
15339{
15340 int ret;
15341
15342 vos_ssr_protect(__func__);
15343 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
15344 vos_ssr_unprotect(__func__);
15345
15346 return ret;
15347}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015348#endif /*FEATURE_WLAN_SCAN_PNO*/
15349
15350
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015351#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015352#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015353static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15354 struct net_device *dev,
15355 u8 *peer, u8 action_code,
15356 u8 dialog_token,
15357 u16 status_code, u32 peer_capability,
15358 const u8 *buf, size_t len)
15359#else /* TDLS_MGMT_VERSION2 */
15360#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
15361static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15362 struct net_device *dev,
15363 const u8 *peer, u8 action_code,
15364 u8 dialog_token, u16 status_code,
15365 u32 peer_capability, bool initiator,
15366 const u8 *buf, size_t len)
15367#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
15368static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15369 struct net_device *dev,
15370 const u8 *peer, u8 action_code,
15371 u8 dialog_token, u16 status_code,
15372 u32 peer_capability, const u8 *buf,
15373 size_t len)
15374#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
15375static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15376 struct net_device *dev,
15377 u8 *peer, u8 action_code,
15378 u8 dialog_token,
15379 u16 status_code, u32 peer_capability,
15380 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015381#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015382static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15383 struct net_device *dev,
15384 u8 *peer, u8 action_code,
15385 u8 dialog_token,
15386 u16 status_code, const u8 *buf,
15387 size_t len)
15388#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015389#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015390{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015391 hdd_adapter_t *pAdapter;
15392 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015393 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070015394 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080015395 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070015396 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015397 int ret;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015398#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015399 u32 peer_capability = 0;
15400#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015401 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015402 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015403
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015404 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15405 if (NULL == pAdapter)
15406 {
15407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15408 "%s: Adapter is NULL",__func__);
15409 return -EINVAL;
15410 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015411 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15412 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
15413 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015414
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015415 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015416 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015417 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015419 "Invalid arguments");
15420 return -EINVAL;
15421 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015422
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015423 if (pHddCtx->isLogpInProgress)
15424 {
15425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15426 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053015427 wlan_hdd_tdls_set_link_status(pAdapter,
15428 peer,
15429 eTDLS_LINK_IDLE,
15430 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015431 return -EBUSY;
15432 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015433
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015434 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
15435 {
15436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15437 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15438 return -EAGAIN;
15439 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015440
Hoonki Lee27511902013-03-14 18:19:06 -070015441 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015442 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015444 "%s: TDLS mode is disabled OR not enabled in FW."
15445 MAC_ADDRESS_STR " action %d declined.",
15446 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015447 return -ENOTSUPP;
15448 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015449
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015450 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15451
15452 if( NULL == pHddStaCtx )
15453 {
15454 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15455 "%s: HDD station context NULL ",__func__);
15456 return -EINVAL;
15457 }
15458
15459 /* STA should be connected and authenticated
15460 * before sending any TDLS frames
15461 */
15462 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15463 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
15464 {
15465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15466 "STA is not connected or unauthenticated. "
15467 "connState %u, uIsAuthenticated %u",
15468 pHddStaCtx->conn_info.connState,
15469 pHddStaCtx->conn_info.uIsAuthenticated);
15470 return -EAGAIN;
15471 }
15472
Hoonki Lee27511902013-03-14 18:19:06 -070015473 /* other than teardown frame, other mgmt frames are not sent if disabled */
15474 if (SIR_MAC_TDLS_TEARDOWN != action_code)
15475 {
15476 /* if tdls_mode is disabled to respond to peer's request */
15477 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
15478 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015480 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015481 " TDLS mode is disabled. action %d declined.",
15482 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070015483
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015484 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070015485 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053015486
15487 if (vos_max_concurrent_connections_reached())
15488 {
15489 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15490 return -EINVAL;
15491 }
Hoonki Lee27511902013-03-14 18:19:06 -070015492 }
15493
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015494 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
15495 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053015496 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015497 {
15498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015499 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015500 " TDLS setup is ongoing. action %d declined.",
15501 __func__, MAC_ADDR_ARRAY(peer), action_code);
15502 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015503 }
15504 }
15505
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015506 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
15507 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080015508 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015509 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15510 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015511 {
15512 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
15513 we return error code at 'add_station()'. Hence we have this
15514 check again in addtion to add_station().
15515 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015516 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015517 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15519 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015520 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
15521 __func__, MAC_ADDR_ARRAY(peer), action_code,
15522 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053015523 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080015524 }
15525 else
15526 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015527 /* maximum reached. tweak to send error code to peer and return
15528 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015529 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15531 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015532 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
15533 __func__, MAC_ADDR_ARRAY(peer), status_code,
15534 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070015535 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015536 /* fall through to send setup resp with failure status
15537 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015538 }
15539 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015540 else
15541 {
15542 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053015543 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015544 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015545 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015547 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
15548 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015549 return -EPERM;
15550 }
15551 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015552 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015553
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015555 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015556 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
15557 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015558
Hoonki Leea34dd892013-02-05 22:56:02 -080015559 /*Except teardown responder will not be used so just make 0*/
15560 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015561 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080015562 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015563
15564 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015565 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015566
15567 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
15568 responder = pTdlsPeer->is_responder;
15569 else
Hoonki Leea34dd892013-02-05 22:56:02 -080015570 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015572 "%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 -070015573 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
15574 dialog_token, status_code, len);
15575 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080015576 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015577 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015578
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015579 /* For explicit trigger of DIS_REQ come out of BMPS for
15580 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070015581 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015582 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
15583 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070015584 {
15585 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
15586 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015588 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015589 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
15590 if (status != VOS_STATUS_SUCCESS) {
15591 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
15592 }
Hoonki Lee14621352013-04-16 17:51:19 -070015593 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015594 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015595 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015596 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
15597 }
15598 }
Hoonki Lee14621352013-04-16 17:51:19 -070015599 }
15600
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015601 /* make sure doesn't call send_mgmt() while it is pending */
15602 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
15603 {
15604 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015605 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015606 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015607 ret = -EBUSY;
15608 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015609 }
15610
15611 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015612 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
15613
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015614 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
15615 pAdapter->sessionId, peer, action_code, dialog_token,
15616 status_code, peer_capability, (tANI_U8 *)buf, len,
15617 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015618
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015619 if (VOS_STATUS_SUCCESS != status)
15620 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15622 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015623 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015624 ret = -EINVAL;
15625 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015626 }
15627
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015628 if ((SIR_MAC_TDLS_DIS_REQ == action_code) ||
15629 (SIR_MAC_TDLS_DIS_RSP == action_code))
15630 {
15631 /* for DIS_REQ/DIS_RSP, supplicant don't consider the return status.
15632 * So we no need to wait for tdls_mgmt_comp for sending ack status.
15633 */
15634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15635 "%s: tx done for frm %u", __func__, action_code);
15636 return 0;
15637 }
15638
15639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15640 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
15641 WAIT_TIME_TDLS_MGMT);
15642
Hoonki Leed37cbb32013-04-20 00:31:14 -070015643 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
15644 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
15645
15646 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015647 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070015648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015649 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070015650 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015651 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080015652
15653 if (pHddCtx->isLogpInProgress)
15654 {
15655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15656 "%s: LOGP in Progress. Ignore!!!", __func__);
15657 return -EAGAIN;
15658 }
15659
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015660 ret = -EINVAL;
15661 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015662 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015663 else
15664 {
15665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15666 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
15667 __func__, rc, pAdapter->mgmtTxCompletionStatus);
15668 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015669
Gopichand Nakkala05922802013-03-14 12:23:19 -070015670 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070015671 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015672 ret = max_sta_failed;
15673 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070015674 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015675
Hoonki Leea34dd892013-02-05 22:56:02 -080015676 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
15677 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015678 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15680 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015681 }
15682 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
15683 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015684 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15686 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015687 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015688
15689 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015690
15691tx_failed:
15692 /* add_station will be called before sending TDLS_SETUP_REQ and
15693 * TDLS_SETUP_RSP and as part of add_station driver will enable
15694 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
15695 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
15696 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
15697 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
15698 */
15699
15700 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
15701 (SIR_MAC_TDLS_SETUP_RSP == action_code))
15702 wlan_hdd_tdls_check_bmps(pAdapter);
15703 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015704}
15705
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015706#if TDLS_MGMT_VERSION2
15707static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15708 u8 *peer, u8 action_code, u8 dialog_token,
15709 u16 status_code, u32 peer_capability,
15710 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015711#else /* TDLS_MGMT_VERSION2 */
15712#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
15713static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15714 struct net_device *dev,
15715 const u8 *peer, u8 action_code,
15716 u8 dialog_token, u16 status_code,
15717 u32 peer_capability, bool initiator,
15718 const u8 *buf, size_t len)
15719#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15720static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15721 struct net_device *dev,
15722 const u8 *peer, u8 action_code,
15723 u8 dialog_token, u16 status_code,
15724 u32 peer_capability, const u8 *buf,
15725 size_t len)
15726#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
15727static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15728 struct net_device *dev,
15729 u8 *peer, u8 action_code,
15730 u8 dialog_token,
15731 u16 status_code, u32 peer_capability,
15732 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015733#else
15734static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15735 u8 *peer, u8 action_code, u8 dialog_token,
15736 u16 status_code, const u8 *buf, size_t len)
15737#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015738#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015739{
15740 int ret;
15741
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015742 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015743#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015744 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15745 dialog_token, status_code,
15746 peer_capability, buf, len);
15747#else /* TDLS_MGMT_VERSION2 */
15748#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
15749 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15750 dialog_token, status_code,
15751 peer_capability, initiator,
15752 buf, len);
15753#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
15754 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15755 dialog_token, status_code,
15756 peer_capability, buf, len);
15757#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
15758 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15759 dialog_token, status_code,
15760 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015761#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015762 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15763 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015764#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015765#endif
15766 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015767
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015768 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015769}
Atul Mittal115287b2014-07-08 13:26:33 +053015770
15771int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015772#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15773 const u8 *peer,
15774#else
Atul Mittal115287b2014-07-08 13:26:33 +053015775 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015776#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015777 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053015778 cfg80211_exttdls_callback callback)
15779{
15780
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015781 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053015782 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015783 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053015784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15785 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
15786 __func__, MAC_ADDR_ARRAY(peer));
15787
15788 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15789 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15790
15791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015792 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15793 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15794 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015795 return -ENOTSUPP;
15796 }
15797
15798 /* To cater the requirement of establishing the TDLS link
15799 * irrespective of the data traffic , get an entry of TDLS peer.
15800 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015801 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015802 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
15803 if (pTdlsPeer == NULL) {
15804 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15805 "%s: peer " MAC_ADDRESS_STR " not existing",
15806 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015807 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015808 return -EINVAL;
15809 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015810 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015811
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015812 /* check FW TDLS Off Channel capability */
15813 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015814 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015815 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015816 {
15817 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
15818 pTdlsPeer->peerParams.global_operating_class =
15819 tdls_peer_params->global_operating_class;
15820 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
15821 pTdlsPeer->peerParams.min_bandwidth_kbps =
15822 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015823 /* check configured channel is valid, non dfs and
15824 * not current operating channel */
15825 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
15826 tdls_peer_params->channel)) &&
15827 (pHddStaCtx) &&
15828 (tdls_peer_params->channel !=
15829 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015830 {
15831 pTdlsPeer->isOffChannelConfigured = TRUE;
15832 }
15833 else
15834 {
15835 pTdlsPeer->isOffChannelConfigured = FALSE;
15836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15837 "%s: Configured Tdls Off Channel is not valid", __func__);
15838
15839 }
15840 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015841 "%s: tdls_off_channel %d isOffChannelConfigured %d "
15842 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015843 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015844 pTdlsPeer->isOffChannelConfigured,
15845 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015846 }
15847 else
15848 {
15849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015850 "%s: TDLS off channel FW capability %d, "
15851 "host capab %d or Invalid TDLS Peer Params", __func__,
15852 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
15853 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015854 }
15855
Atul Mittal115287b2014-07-08 13:26:33 +053015856 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
15857
15858 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15859 " %s TDLS Add Force Peer Failed",
15860 __func__);
15861 return -EINVAL;
15862 }
15863 /*EXT TDLS*/
15864
15865 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
15866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15867 " %s TDLS set callback Failed",
15868 __func__);
15869 return -EINVAL;
15870 }
15871
15872 return(0);
15873
15874}
15875
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015876int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
15877#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15878 const u8 *peer
15879#else
15880 u8 *peer
15881#endif
15882)
Atul Mittal115287b2014-07-08 13:26:33 +053015883{
15884
15885 hddTdlsPeer_t *pTdlsPeer;
15886 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15888 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
15889 __func__, MAC_ADDR_ARRAY(peer));
15890
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015891 if (0 != wlan_hdd_validate_context(pHddCtx)) {
15892 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
15893 return -EINVAL;
15894 }
15895
Atul Mittal115287b2014-07-08 13:26:33 +053015896 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15897 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15898
15899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015900 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15901 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15902 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015903 return -ENOTSUPP;
15904 }
15905
15906
15907 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15908
15909 if ( NULL == pTdlsPeer ) {
15910 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015911 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053015912 __func__, MAC_ADDR_ARRAY(peer));
15913 return -EINVAL;
15914 }
15915 else {
15916 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
15917 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015918 /* if channel switch is configured, reset
15919 the channel for this peer */
15920 if (TRUE == pTdlsPeer->isOffChannelConfigured)
15921 {
15922 pTdlsPeer->peerParams.channel = 0;
15923 pTdlsPeer->isOffChannelConfigured = FALSE;
15924 }
Atul Mittal115287b2014-07-08 13:26:33 +053015925 }
15926
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015927 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
15928 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053015929 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015930 }
Atul Mittal115287b2014-07-08 13:26:33 +053015931
15932 /*EXT TDLS*/
15933
15934 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
15935
15936 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15937 " %s TDLS set callback Failed",
15938 __func__);
15939 return -EINVAL;
15940 }
15941 return(0);
15942
15943}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015944static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015945#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15946 const u8 *peer,
15947#else
15948 u8 *peer,
15949#endif
15950 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015951{
15952 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15953 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015954 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015955 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015956
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015957 ENTER();
15958
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015959 if (!pAdapter) {
15960 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15961 return -EINVAL;
15962 }
15963
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015964 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15965 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
15966 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015967 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015968 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015969 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070015970 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015971 return -EINVAL;
15972 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015973
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015974 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015975 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015976 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015977 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015978 }
15979
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015980
15981 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015982 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015983 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015984 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015985 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
15986 "Cannot process TDLS commands",
15987 pHddCtx->cfg_ini->fEnableTDLSSupport,
15988 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015989 return -ENOTSUPP;
15990 }
15991
15992 switch (oper) {
15993 case NL80211_TDLS_ENABLE_LINK:
15994 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015995 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015996 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015997 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053015998 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015999 tANI_U16 numCurrTdlsPeers = 0;
16000 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016001 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016002
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16004 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
16005 __func__, MAC_ADDR_ARRAY(peer));
Sunil Dutt41de4e22013-11-14 18:09:02 +053016006 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053016007 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053016008 if ( NULL == pTdlsPeer ) {
16009 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
16010 " (oper %d) not exsting. ignored",
16011 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
16012 return -EINVAL;
16013 }
16014
16015 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16016 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
16017 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
16018 "NL80211_TDLS_ENABLE_LINK");
16019
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070016020 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
16021 {
16022 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
16023 MAC_ADDRESS_STR " failed",
16024 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
16025 return -EINVAL;
16026 }
16027
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053016028 /* before starting tdls connection, set tdls
16029 * off channel established status to default value */
16030 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016031 /* TDLS Off Channel, Disable tdls channel switch,
16032 when there are more than one tdls link */
16033 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053016034 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016035 {
16036 /* get connected peer and send disable tdls off chan */
16037 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016038 if ((connPeer) &&
16039 (connPeer->isOffChannelSupported == TRUE) &&
16040 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016041 {
16042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16043 "%s: More then one peer connected, Disable "
16044 "TDLS channel switch", __func__);
16045
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016046 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016047 ret = sme_SendTdlsChanSwitchReq(
16048 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016049 pAdapter->sessionId,
16050 connPeer->peerMac,
16051 connPeer->peerParams.channel,
16052 TDLS_OFF_CHANNEL_BW_OFFSET,
16053 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016054 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016055 hddLog(VOS_TRACE_LEVEL_ERROR,
16056 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016057 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016058 }
16059 else
16060 {
16061 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16062 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016063 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016064 "isOffChannelConfigured %d",
16065 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016066 (connPeer ? (connPeer->isOffChannelSupported)
16067 : -1),
16068 (connPeer ? (connPeer->isOffChannelConfigured)
16069 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016070 }
16071 }
16072
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016073 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016074 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016075 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053016076
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016077 if (0 != wlan_hdd_tdls_get_link_establish_params(
16078 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016079 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016080 return -EINVAL;
16081 }
16082 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016083
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016084 ret = sme_SendTdlsLinkEstablishParams(
16085 WLAN_HDD_GET_HAL_CTX(pAdapter),
16086 pAdapter->sessionId, peer,
16087 &tdlsLinkEstablishParams);
16088 if (ret != VOS_STATUS_SUCCESS) {
16089 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
16090 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016091 /* Send TDLS peer UAPSD capabilities to the firmware and
16092 * register with the TL on after the response for this operation
16093 * is received .
16094 */
16095 ret = wait_for_completion_interruptible_timeout(
16096 &pAdapter->tdls_link_establish_req_comp,
16097 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
16098 if (ret <= 0)
16099 {
16100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016101 FL("Link Establish Request Failed Status %ld"),
16102 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016103 return -EINVAL;
16104 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016105 }
Atul Mittal115287b2014-07-08 13:26:33 +053016106 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
16107 eTDLS_LINK_CONNECTED,
16108 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053016109 staDesc.ucSTAId = pTdlsPeer->staId;
16110 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016111 ret = WLANTL_UpdateTdlsSTAClient(
16112 pHddCtx->pvosContext,
16113 &staDesc);
16114 if (ret != VOS_STATUS_SUCCESS) {
16115 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
16116 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053016117
Gopichand Nakkala471708b2013-06-04 20:03:01 +053016118 /* Mark TDLS client Authenticated .*/
16119 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
16120 pTdlsPeer->staId,
16121 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070016122 if (VOS_STATUS_SUCCESS == status)
16123 {
Hoonki Lee14621352013-04-16 17:51:19 -070016124 if (pTdlsPeer->is_responder == 0)
16125 {
16126 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
16127
16128 wlan_hdd_tdls_timer_restart(pAdapter,
16129 &pTdlsPeer->initiatorWaitTimeoutTimer,
16130 WAIT_TIME_TDLS_INITIATOR);
16131 /* suspend initiator TX until it receives direct packet from the
16132 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016133 ret = WLANTL_SuspendDataTx(
16134 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
16135 &staId, NULL);
16136 if (ret != VOS_STATUS_SUCCESS) {
16137 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
16138 }
Hoonki Lee14621352013-04-16 17:51:19 -070016139 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016140
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016141 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016142 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016143 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016144 suppChannelLen =
16145 tdlsLinkEstablishParams.supportedChannelsLen;
16146
16147 if ((suppChannelLen > 0) &&
16148 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
16149 {
16150 tANI_U8 suppPeerChannel = 0;
16151 int i = 0;
16152 for (i = 0U; i < suppChannelLen; i++)
16153 {
16154 suppPeerChannel =
16155 tdlsLinkEstablishParams.supportedChannels[i];
16156
16157 pTdlsPeer->isOffChannelSupported = FALSE;
16158 if (suppPeerChannel ==
16159 pTdlsPeer->peerParams.channel)
16160 {
16161 pTdlsPeer->isOffChannelSupported = TRUE;
16162 break;
16163 }
16164 }
16165 }
16166 else
16167 {
16168 pTdlsPeer->isOffChannelSupported = FALSE;
16169 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016170 }
16171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16172 "%s: TDLS channel switch request for channel "
16173 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016174 "%d isOffChannelSupported %d", __func__,
16175 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016176 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016177 suppChannelLen,
16178 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016179
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016180 /* TDLS Off Channel, Enable tdls channel switch,
16181 when their is only one tdls link and it supports */
16182 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16183 if ((numCurrTdlsPeers == 1) &&
16184 (TRUE == pTdlsPeer->isOffChannelSupported) &&
16185 (TRUE == pTdlsPeer->isOffChannelConfigured))
16186 {
16187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16188 "%s: Send TDLS channel switch request for channel %d",
16189 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016190
16191 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016192 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
16193 pAdapter->sessionId,
16194 pTdlsPeer->peerMac,
16195 pTdlsPeer->peerParams.channel,
16196 TDLS_OFF_CHANNEL_BW_OFFSET,
16197 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016198 if (ret != VOS_STATUS_SUCCESS) {
16199 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
16200 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016201 }
16202 else
16203 {
16204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16205 "%s: TDLS channel switch request not sent"
16206 " numCurrTdlsPeers %d "
16207 "isOffChannelSupported %d "
16208 "isOffChannelConfigured %d",
16209 __func__, numCurrTdlsPeers,
16210 pTdlsPeer->isOffChannelSupported,
16211 pTdlsPeer->isOffChannelConfigured);
16212 }
16213
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070016214 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016215 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016216
16217 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016218 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
16219 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016220 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016221 int ac;
16222 uint8 ucAc[4] = { WLANTL_AC_VO,
16223 WLANTL_AC_VI,
16224 WLANTL_AC_BK,
16225 WLANTL_AC_BE };
16226 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
16227 for(ac=0; ac < 4; ac++)
16228 {
16229 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
16230 pTdlsPeer->staId, ucAc[ac],
16231 tlTid[ac], tlTid[ac], 0, 0,
16232 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016233 if (status != VOS_STATUS_SUCCESS) {
16234 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
16235 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016236 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016237 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016238 }
16239
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016240 }
16241 break;
16242 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080016243 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016244 tANI_U16 numCurrTdlsPeers = 0;
16245 hddTdlsPeer_t *connPeer = NULL;
16246
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016247 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16248 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
16249 __func__, MAC_ADDR_ARRAY(peer));
16250
Sunil Dutt41de4e22013-11-14 18:09:02 +053016251 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
16252
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016253
Sunil Dutt41de4e22013-11-14 18:09:02 +053016254 if ( NULL == pTdlsPeer ) {
16255 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
16256 " (oper %d) not exsting. ignored",
16257 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
16258 return -EINVAL;
16259 }
16260
16261 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16262 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
16263 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
16264 "NL80211_TDLS_DISABLE_LINK");
16265
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016266 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080016267 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016268 long status;
16269
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053016270 /* set tdls off channel status to false for this peer */
16271 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053016272 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
16273 eTDLS_LINK_TEARING,
16274 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
16275 eTDLS_LINK_UNSPECIFIED:
16276 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016277 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
16278
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016279 status = sme_DeleteTdlsPeerSta(
16280 WLAN_HDD_GET_HAL_CTX(pAdapter),
16281 pAdapter->sessionId, peer );
16282 if (status != VOS_STATUS_SUCCESS) {
16283 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16284 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016285
16286 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
16287 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053016288 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053016289 eTDLS_LINK_IDLE,
16290 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016291 if (status <= 0)
16292 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16294 "%s: Del station failed status %ld",
16295 __func__, status);
16296 return -EPERM;
16297 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016298
16299 /* TDLS Off Channel, Enable tdls channel switch,
16300 when their is only one tdls link and it supports */
16301 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16302 if (numCurrTdlsPeers == 1)
16303 {
16304 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
16305 if ((connPeer) &&
16306 (connPeer->isOffChannelSupported == TRUE) &&
16307 (connPeer->isOffChannelConfigured == TRUE))
16308 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016309 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016310 status = sme_SendTdlsChanSwitchReq(
16311 WLAN_HDD_GET_HAL_CTX(pAdapter),
16312 pAdapter->sessionId,
16313 connPeer->peerMac,
16314 connPeer->peerParams.channel,
16315 TDLS_OFF_CHANNEL_BW_OFFSET,
16316 TDLS_CHANNEL_SWITCH_ENABLE);
16317 if (status != VOS_STATUS_SUCCESS) {
16318 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
16319 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016320 }
16321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16322 "%s: TDLS channel switch "
16323 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016324 "isOffChannelConfigured %d "
16325 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016326 __func__,
16327 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016328 (connPeer ? connPeer->isOffChannelConfigured : -1),
16329 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016330 }
16331 else
16332 {
16333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16334 "%s: TDLS channel switch request not sent "
16335 "numCurrTdlsPeers %d ",
16336 __func__, numCurrTdlsPeers);
16337 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016338 }
16339 else
16340 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16342 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080016343 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016344 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016345 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016346 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053016347 {
Atul Mittal115287b2014-07-08 13:26:33 +053016348 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053016349
Atul Mittal115287b2014-07-08 13:26:33 +053016350 if (0 != status)
16351 {
16352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016353 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053016354 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053016355 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053016356 break;
16357 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016358 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053016359 {
Atul Mittal115287b2014-07-08 13:26:33 +053016360 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
16361 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016362 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053016363 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053016364
Atul Mittal115287b2014-07-08 13:26:33 +053016365 if (0 != status)
16366 {
16367 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016368 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053016369 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053016370 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053016371 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053016372 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016373 case NL80211_TDLS_DISCOVERY_REQ:
16374 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016376 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016377 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016378 return -ENOTSUPP;
16379 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16381 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016382 return -ENOTSUPP;
16383 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016384
16385 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016386 return 0;
16387}
Chilam NG571c65a2013-01-19 12:27:36 +053016388
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016389static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016390#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16391 const u8 *peer,
16392#else
16393 u8 *peer,
16394#endif
16395 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016396{
16397 int ret;
16398
16399 vos_ssr_protect(__func__);
16400 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
16401 vos_ssr_unprotect(__func__);
16402
16403 return ret;
16404}
16405
Chilam NG571c65a2013-01-19 12:27:36 +053016406int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
16407 struct net_device *dev, u8 *peer)
16408{
Arif Hussaina7c8e412013-11-20 11:06:42 -080016409 hddLog(VOS_TRACE_LEVEL_INFO,
16410 "tdls send discover req: "MAC_ADDRESS_STR,
16411 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053016412
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016413#if TDLS_MGMT_VERSION2
16414 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16415 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16416#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016417#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
16418 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16419 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
16420#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16421 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16422 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16423#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
16424 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16425 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16426#else
Chilam NG571c65a2013-01-19 12:27:36 +053016427 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16428 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016429#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016430#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053016431}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016432#endif
16433
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016434#ifdef WLAN_FEATURE_GTK_OFFLOAD
16435/*
16436 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
16437 * Callback rountine called upon receiving response for
16438 * get offload info
16439 */
16440void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
16441 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
16442{
16443
16444 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016445 tANI_U8 tempReplayCounter[8];
16446 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016447
16448 ENTER();
16449
16450 if (NULL == pAdapter)
16451 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016452 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016453 "%s: HDD adapter is Null", __func__);
16454 return ;
16455 }
16456
16457 if (NULL == pGtkOffloadGetInfoRsp)
16458 {
16459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16460 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
16461 return ;
16462 }
16463
16464 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
16465 {
16466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16467 "%s: wlan Failed to get replay counter value",
16468 __func__);
16469 return ;
16470 }
16471
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016472 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16473 /* Update replay counter */
16474 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
16475 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16476
16477 {
16478 /* changing from little to big endian since supplicant
16479 * works on big endian format
16480 */
16481 int i;
16482 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16483
16484 for (i = 0; i < 8; i++)
16485 {
16486 tempReplayCounter[7-i] = (tANI_U8)p[i];
16487 }
16488 }
16489
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016490 /* Update replay counter to NL */
16491 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016492 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016493}
16494
16495/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016496 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016497 * This function is used to offload GTK rekeying job to the firmware.
16498 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016499int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016500 struct cfg80211_gtk_rekey_data *data)
16501{
16502 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16503 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16504 hdd_station_ctx_t *pHddStaCtx;
16505 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016506 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016507 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016508 eHalStatus status = eHAL_STATUS_FAILURE;
16509
16510 ENTER();
16511
16512 if (NULL == pAdapter)
16513 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016515 "%s: HDD adapter is Null", __func__);
16516 return -ENODEV;
16517 }
16518
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016519 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16520 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
16521 pAdapter->sessionId, pAdapter->device_mode));
16522
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016523 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016524 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016525 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016526 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016527 }
16528
16529 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16530 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16531 if (NULL == hHal)
16532 {
16533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16534 "%s: HAL context is Null!!!", __func__);
16535 return -EAGAIN;
16536 }
16537
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016538 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
16539 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
16540 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
16541 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016542 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016543 {
16544 /* changing from big to little endian since driver
16545 * works on little endian format
16546 */
16547 tANI_U8 *p =
16548 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
16549 int i;
16550
16551 for (i = 0; i < 8; i++)
16552 {
16553 p[7-i] = data->replay_ctr[i];
16554 }
16555 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016556
16557 if (TRUE == pHddCtx->hdd_wlan_suspended)
16558 {
16559 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016560 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
16561 sizeof (tSirGtkOffloadParams));
16562 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016563 pAdapter->sessionId);
16564
16565 if (eHAL_STATUS_SUCCESS != status)
16566 {
16567 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16568 "%s: sme_SetGTKOffload failed, returned %d",
16569 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016570
16571 /* Need to clear any trace of key value in the memory.
16572 * Thus zero out the memory even though it is local
16573 * variable.
16574 */
16575 vos_mem_zero(&hddGtkOffloadReqParams,
16576 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016577 return status;
16578 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16580 "%s: sme_SetGTKOffload successfull", __func__);
16581 }
16582 else
16583 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16585 "%s: wlan not suspended GTKOffload request is stored",
16586 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016587 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016588
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016589 /* Need to clear any trace of key value in the memory.
16590 * Thus zero out the memory even though it is local
16591 * variable.
16592 */
16593 vos_mem_zero(&hddGtkOffloadReqParams,
16594 sizeof(hddGtkOffloadReqParams));
16595
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016596 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016597 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016598}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016599
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016600int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
16601 struct cfg80211_gtk_rekey_data *data)
16602{
16603 int ret;
16604
16605 vos_ssr_protect(__func__);
16606 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
16607 vos_ssr_unprotect(__func__);
16608
16609 return ret;
16610}
16611#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016612/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016613 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016614 * This function is used to set access control policy
16615 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016616static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16617 struct net_device *dev,
16618 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016619{
16620 int i;
16621 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16622 hdd_hostapd_state_t *pHostapdState;
16623 tsap_Config_t *pConfig;
16624 v_CONTEXT_t pVosContext = NULL;
16625 hdd_context_t *pHddCtx;
16626 int status;
16627
16628 ENTER();
16629
16630 if (NULL == pAdapter)
16631 {
16632 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16633 "%s: HDD adapter is Null", __func__);
16634 return -ENODEV;
16635 }
16636
16637 if (NULL == params)
16638 {
16639 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16640 "%s: params is Null", __func__);
16641 return -EINVAL;
16642 }
16643
16644 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16645 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016646 if (0 != status)
16647 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016648 return status;
16649 }
16650
16651 pVosContext = pHddCtx->pvosContext;
16652 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
16653
16654 if (NULL == pHostapdState)
16655 {
16656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16657 "%s: pHostapdState is Null", __func__);
16658 return -EINVAL;
16659 }
16660
16661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
16662 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016663 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16664 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
16665 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016666
16667 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
16668 {
16669 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
16670
16671 /* default value */
16672 pConfig->num_accept_mac = 0;
16673 pConfig->num_deny_mac = 0;
16674
16675 /**
16676 * access control policy
16677 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
16678 * listed in hostapd.deny file.
16679 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
16680 * listed in hostapd.accept file.
16681 */
16682 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
16683 {
16684 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
16685 }
16686 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
16687 {
16688 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
16689 }
16690 else
16691 {
16692 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16693 "%s:Acl Policy : %d is not supported",
16694 __func__, params->acl_policy);
16695 return -ENOTSUPP;
16696 }
16697
16698 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
16699 {
16700 pConfig->num_accept_mac = params->n_acl_entries;
16701 for (i = 0; i < params->n_acl_entries; i++)
16702 {
16703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16704 "** Add ACL MAC entry %i in WhiletList :"
16705 MAC_ADDRESS_STR, i,
16706 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16707
16708 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
16709 sizeof(qcmacaddr));
16710 }
16711 }
16712 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
16713 {
16714 pConfig->num_deny_mac = params->n_acl_entries;
16715 for (i = 0; i < params->n_acl_entries; i++)
16716 {
16717 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16718 "** Add ACL MAC entry %i in BlackList :"
16719 MAC_ADDRESS_STR, i,
16720 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16721
16722 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
16723 sizeof(qcmacaddr));
16724 }
16725 }
16726
16727 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
16728 {
16729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16730 "%s: SAP Set Mac Acl fail", __func__);
16731 return -EINVAL;
16732 }
16733 }
16734 else
16735 {
16736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016737 "%s: Invalid device_mode = %s (%d)",
16738 __func__, hdd_device_modetoString(pAdapter->device_mode),
16739 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016740 return -EINVAL;
16741 }
16742
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016743 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016744 return 0;
16745}
16746
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016747static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16748 struct net_device *dev,
16749 const struct cfg80211_acl_data *params)
16750{
16751 int ret;
16752 vos_ssr_protect(__func__);
16753 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
16754 vos_ssr_unprotect(__func__);
16755
16756 return ret;
16757}
16758
Leo Chang9056f462013-08-01 19:21:11 -070016759#ifdef WLAN_NL80211_TESTMODE
16760#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070016761void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070016762(
16763 void *pAdapter,
16764 void *indCont
16765)
16766{
Leo Changd9df8aa2013-09-26 13:32:26 -070016767 tSirLPHBInd *lphbInd;
16768 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053016769 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070016770
16771 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016772 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070016773
c_hpothu73f35e62014-04-18 13:40:08 +053016774 if (pAdapter == NULL)
16775 {
16776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16777 "%s: pAdapter is NULL\n",__func__);
16778 return;
16779 }
16780
Leo Chang9056f462013-08-01 19:21:11 -070016781 if (NULL == indCont)
16782 {
16783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016784 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070016785 return;
16786 }
16787
c_hpothu73f35e62014-04-18 13:40:08 +053016788 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070016789 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070016790 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053016791 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070016792 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070016793 GFP_ATOMIC);
16794 if (!skb)
16795 {
16796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16797 "LPHB timeout, NL buffer alloc fail");
16798 return;
16799 }
16800
Leo Changac3ba772013-10-07 09:47:04 -070016801 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070016802 {
16803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16804 "WLAN_HDD_TM_ATTR_CMD put fail");
16805 goto nla_put_failure;
16806 }
Leo Changac3ba772013-10-07 09:47:04 -070016807 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070016808 {
16809 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16810 "WLAN_HDD_TM_ATTR_TYPE put fail");
16811 goto nla_put_failure;
16812 }
Leo Changac3ba772013-10-07 09:47:04 -070016813 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070016814 sizeof(tSirLPHBInd), lphbInd))
16815 {
16816 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16817 "WLAN_HDD_TM_ATTR_DATA put fail");
16818 goto nla_put_failure;
16819 }
Leo Chang9056f462013-08-01 19:21:11 -070016820 cfg80211_testmode_event(skb, GFP_ATOMIC);
16821 return;
16822
16823nla_put_failure:
16824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16825 "NLA Put fail");
16826 kfree_skb(skb);
16827
16828 return;
16829}
16830#endif /* FEATURE_WLAN_LPHB */
16831
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016832static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070016833{
16834 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
16835 int err = 0;
16836#ifdef FEATURE_WLAN_LPHB
16837 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070016838 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016839
16840 ENTER();
16841
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016842 err = wlan_hdd_validate_context(pHddCtx);
16843 if (0 != err)
16844 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016845 return err;
16846 }
Leo Chang9056f462013-08-01 19:21:11 -070016847#endif /* FEATURE_WLAN_LPHB */
16848
16849 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
16850 if (err)
16851 {
16852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16853 "%s Testmode INV ATTR", __func__);
16854 return err;
16855 }
16856
16857 if (!tb[WLAN_HDD_TM_ATTR_CMD])
16858 {
16859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16860 "%s Testmode INV CMD", __func__);
16861 return -EINVAL;
16862 }
16863
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016864 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16865 TRACE_CODE_HDD_CFG80211_TESTMODE,
16866 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070016867 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
16868 {
16869#ifdef FEATURE_WLAN_LPHB
16870 /* Low Power Heartbeat configuration request */
16871 case WLAN_HDD_TM_CMD_WLAN_HB:
16872 {
16873 int buf_len;
16874 void *buf;
16875 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080016876 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070016877
16878 if (!tb[WLAN_HDD_TM_ATTR_DATA])
16879 {
16880 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16881 "%s Testmode INV DATA", __func__);
16882 return -EINVAL;
16883 }
16884
16885 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
16886 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080016887
16888 hb_params_temp =(tSirLPHBReq *)buf;
16889 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
16890 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
16891 return -EINVAL;
16892
Leo Chang9056f462013-08-01 19:21:11 -070016893 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
16894 if (NULL == hb_params)
16895 {
16896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16897 "%s Request Buffer Alloc Fail", __func__);
16898 return -EINVAL;
16899 }
16900
16901 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070016902 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
16903 hb_params,
16904 wlan_hdd_cfg80211_lphb_ind_handler);
16905 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070016906 {
Leo Changd9df8aa2013-09-26 13:32:26 -070016907 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16908 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070016909 vos_mem_free(hb_params);
16910 }
Leo Chang9056f462013-08-01 19:21:11 -070016911 return 0;
16912 }
16913#endif /* FEATURE_WLAN_LPHB */
16914 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016915 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16916 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070016917 return -EOPNOTSUPP;
16918 }
16919
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016920 EXIT();
16921 return err;
Leo Chang9056f462013-08-01 19:21:11 -070016922}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016923
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053016924static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
16925#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
16926 struct wireless_dev *wdev,
16927#endif
16928 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016929{
16930 int ret;
16931
16932 vos_ssr_protect(__func__);
16933 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
16934 vos_ssr_unprotect(__func__);
16935
16936 return ret;
16937}
Leo Chang9056f462013-08-01 19:21:11 -070016938#endif /* CONFIG_NL80211_TESTMODE */
16939
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016940static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016941 struct net_device *dev,
16942 int idx, struct survey_info *survey)
16943{
16944 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16945 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053016946 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016947 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053016948 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016949 v_S7_t snr,rssi;
16950 int status, i, j, filled = 0;
16951
16952 ENTER();
16953
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016954 if (NULL == pAdapter)
16955 {
16956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16957 "%s: HDD adapter is Null", __func__);
16958 return -ENODEV;
16959 }
16960
16961 if (NULL == wiphy)
16962 {
16963 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16964 "%s: wiphy is Null", __func__);
16965 return -ENODEV;
16966 }
16967
16968 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16969 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016970 if (0 != status)
16971 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016972 return status;
16973 }
16974
Mihir Sheted9072e02013-08-21 17:02:29 +053016975 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16976
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016977 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053016978 0 != pAdapter->survey_idx ||
16979 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016980 {
16981 /* The survey dump ops when implemented completely is expected to
16982 * return a survey of all channels and the ops is called by the
16983 * kernel with incremental values of the argument 'idx' till it
16984 * returns -ENONET. But we can only support the survey for the
16985 * operating channel for now. survey_idx is used to track
16986 * that the ops is called only once and then return -ENONET for
16987 * the next iteration
16988 */
16989 pAdapter->survey_idx = 0;
16990 return -ENONET;
16991 }
16992
Mukul Sharma9d5233b2015-06-11 20:28:20 +053016993 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16994 {
16995 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16996 "%s: Roaming in progress, hence return ", __func__);
16997 return -ENONET;
16998 }
16999
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017000 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17001
17002 wlan_hdd_get_snr(pAdapter, &snr);
17003 wlan_hdd_get_rssi(pAdapter, &rssi);
17004
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017005 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17006 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
17007 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017008 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
17009 hdd_wlan_get_freq(channel, &freq);
17010
17011
17012 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
17013 {
17014 if (NULL == wiphy->bands[i])
17015 {
17016 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
17017 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
17018 continue;
17019 }
17020
17021 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
17022 {
17023 struct ieee80211_supported_band *band = wiphy->bands[i];
17024
17025 if (band->channels[j].center_freq == (v_U16_t)freq)
17026 {
17027 survey->channel = &band->channels[j];
17028 /* The Rx BDs contain SNR values in dB for the received frames
17029 * while the supplicant expects noise. So we calculate and
17030 * return the value of noise (dBm)
17031 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
17032 */
17033 survey->noise = rssi - snr;
17034 survey->filled = SURVEY_INFO_NOISE_DBM;
17035 filled = 1;
17036 }
17037 }
17038 }
17039
17040 if (filled)
17041 pAdapter->survey_idx = 1;
17042 else
17043 {
17044 pAdapter->survey_idx = 0;
17045 return -ENONET;
17046 }
17047
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017048 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017049 return 0;
17050}
17051
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017052static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
17053 struct net_device *dev,
17054 int idx, struct survey_info *survey)
17055{
17056 int ret;
17057
17058 vos_ssr_protect(__func__);
17059 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
17060 vos_ssr_unprotect(__func__);
17061
17062 return ret;
17063}
17064
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017065/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017066 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017067 * this is called when cfg80211 driver resume
17068 * driver updates latest sched_scan scan result(if any) to cfg80211 database
17069 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017070int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017071{
17072 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17073 hdd_adapter_t *pAdapter;
17074 hdd_adapter_list_node_t *pAdapterNode, *pNext;
17075 VOS_STATUS status = VOS_STATUS_SUCCESS;
17076
17077 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017078
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017079 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017080 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017081 return 0;
17082 }
17083
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017084 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
17085 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017086 spin_lock(&pHddCtx->schedScan_lock);
17087 pHddCtx->isWiphySuspended = FALSE;
17088 if (TRUE != pHddCtx->isSchedScanUpdatePending)
17089 {
17090 spin_unlock(&pHddCtx->schedScan_lock);
17091 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17092 "%s: Return resume is not due to PNO indication", __func__);
17093 return 0;
17094 }
17095 // Reset flag to avoid updatating cfg80211 data old results again
17096 pHddCtx->isSchedScanUpdatePending = FALSE;
17097 spin_unlock(&pHddCtx->schedScan_lock);
17098
17099 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
17100
17101 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
17102 {
17103 pAdapter = pAdapterNode->pAdapter;
17104 if ( (NULL != pAdapter) &&
17105 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
17106 {
17107 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017108 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
17110 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017111 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017112 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017113 {
17114 /* Acquire wakelock to handle the case where APP's tries to
17115 * suspend immediately after updating the scan results. Whis
17116 * results in app's is in suspended state and not able to
17117 * process the connect request to AP
17118 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053017119 hdd_prevent_suspend_timeout(2000,
17120 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017121 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017122 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017123
17124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17125 "%s : cfg80211 scan result database updated", __func__);
17126
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017127 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017128 return 0;
17129
17130 }
17131 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
17132 pAdapterNode = pNext;
17133 }
17134
17135 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17136 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017137 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017138 return 0;
17139}
17140
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017141int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
17142{
17143 int ret;
17144
17145 vos_ssr_protect(__func__);
17146 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
17147 vos_ssr_unprotect(__func__);
17148
17149 return ret;
17150}
17151
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017152/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017153 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017154 * this is called when cfg80211 driver suspends
17155 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017156int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017157 struct cfg80211_wowlan *wow)
17158{
17159 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017160 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017161
17162 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017163
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017164 ret = wlan_hdd_validate_context(pHddCtx);
17165 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017166 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017167 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017168 }
17169
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017170
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017171 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17172 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
17173 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017174 pHddCtx->isWiphySuspended = TRUE;
17175
17176 EXIT();
17177
17178 return 0;
17179}
17180
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017181int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
17182 struct cfg80211_wowlan *wow)
17183{
17184 int ret;
17185
17186 vos_ssr_protect(__func__);
17187 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
17188 vos_ssr_unprotect(__func__);
17189
17190 return ret;
17191}
Jeff Johnson295189b2012-06-20 16:38:30 -070017192/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017193static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070017194{
17195 .add_virtual_intf = wlan_hdd_add_virtual_intf,
17196 .del_virtual_intf = wlan_hdd_del_virtual_intf,
17197 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
17198 .change_station = wlan_hdd_change_station,
17199#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
17200 .add_beacon = wlan_hdd_cfg80211_add_beacon,
17201 .del_beacon = wlan_hdd_cfg80211_del_beacon,
17202 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017203#else
17204 .start_ap = wlan_hdd_cfg80211_start_ap,
17205 .change_beacon = wlan_hdd_cfg80211_change_beacon,
17206 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070017207#endif
17208 .change_bss = wlan_hdd_cfg80211_change_bss,
17209 .add_key = wlan_hdd_cfg80211_add_key,
17210 .get_key = wlan_hdd_cfg80211_get_key,
17211 .del_key = wlan_hdd_cfg80211_del_key,
17212 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080017213#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070017214 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080017215#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017216 .scan = wlan_hdd_cfg80211_scan,
17217 .connect = wlan_hdd_cfg80211_connect,
17218 .disconnect = wlan_hdd_cfg80211_disconnect,
17219 .join_ibss = wlan_hdd_cfg80211_join_ibss,
17220 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
17221 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
17222 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
17223 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070017224 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
17225 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053017226 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070017227#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17228 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
17229 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
17230 .set_txq_params = wlan_hdd_set_txq_params,
17231#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017232 .get_station = wlan_hdd_cfg80211_get_station,
17233 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
17234 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017235 .add_station = wlan_hdd_cfg80211_add_station,
17236#ifdef FEATURE_WLAN_LFR
17237 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
17238 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
17239 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
17240#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017241#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
17242 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
17243#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017244#ifdef FEATURE_WLAN_TDLS
17245 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
17246 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
17247#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017248#ifdef WLAN_FEATURE_GTK_OFFLOAD
17249 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
17250#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017251#ifdef FEATURE_WLAN_SCAN_PNO
17252 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
17253 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
17254#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017255 .resume = wlan_hdd_cfg80211_resume_wlan,
17256 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017257 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070017258#ifdef WLAN_NL80211_TESTMODE
17259 .testmode_cmd = wlan_hdd_cfg80211_testmode,
17260#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017261 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070017262};
17263