blob: 62bf76f0408bc750f3b3d4936bdb1438dcd5b292 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098
99#define g_mode_rates_size (12)
100#define a_mode_rates_size (8)
101#define FREQ_BASE_80211G (2407)
102#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700103#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530104#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700105#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800106 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700107
108#define HDD2GHZCHAN(freq, chan, flag) { \
109 .band = IEEE80211_BAND_2GHZ, \
110 .center_freq = (freq), \
111 .hw_value = (chan),\
112 .flags = (flag), \
113 .max_antenna_gain = 0 ,\
114 .max_power = 30, \
115}
116
117#define HDD5GHZCHAN(freq, chan, flag) { \
118 .band = IEEE80211_BAND_5GHZ, \
119 .center_freq = (freq), \
120 .hw_value = (chan),\
121 .flags = (flag), \
122 .max_antenna_gain = 0 ,\
123 .max_power = 30, \
124}
125
126#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
127{\
128 .bitrate = rate, \
129 .hw_value = rate_id, \
130 .flags = flag, \
131}
132
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530133#ifdef WLAN_FEATURE_VOWIFI_11R
134#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
135#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
136#endif
137
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530138#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530139#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530140
Sunil Duttc69bccb2014-05-26 21:30:20 +0530141#ifdef WLAN_FEATURE_LINK_LAYER_STATS
142/*
143 * Used to allocate the size of 4096 for the link layer stats.
144 * The size of 4096 is considered assuming that all data per
145 * respective event fit with in the limit.Please take a call
146 * on the limit based on the data requirements on link layer
147 * statistics.
148 */
149#define LL_STATS_EVENT_BUF_SIZE 4096
150#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530151#ifdef WLAN_FEATURE_EXTSCAN
152/*
153 * Used to allocate the size of 4096 for the EXTScan NL data.
154 * The size of 4096 is considered assuming that all data per
155 * respective event fit with in the limit.Please take a call
156 * on the limit based on the data requirements.
157 */
158
159#define EXTSCAN_EVENT_BUF_SIZE 4096
160#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
161#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530162
Atul Mittal115287b2014-07-08 13:26:33 +0530163/*EXT TDLS*/
164/*
165 * Used to allocate the size of 4096 for the TDLS.
166 * The size of 4096 is considered assuming that all data per
167 * respective event fit with in the limit.Please take a call
168 * on the limit based on the data requirements on link layer
169 * statistics.
170 */
171#define EXTTDLS_EVENT_BUF_SIZE 4096
172
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530173static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700174{
175 WLAN_CIPHER_SUITE_WEP40,
176 WLAN_CIPHER_SUITE_WEP104,
177 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800178#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700179#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
180 WLAN_CIPHER_SUITE_KRK,
181 WLAN_CIPHER_SUITE_CCMP,
182#else
183 WLAN_CIPHER_SUITE_CCMP,
184#endif
185#ifdef FEATURE_WLAN_WAPI
186 WLAN_CIPHER_SUITE_SMS4,
187#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700188#ifdef WLAN_FEATURE_11W
189 WLAN_CIPHER_SUITE_AES_CMAC,
190#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700191};
192
193static inline int is_broadcast_ether_addr(const u8 *addr)
194{
195 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
196 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
197}
198
199static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530200{
Jeff Johnson295189b2012-06-20 16:38:30 -0700201 HDD2GHZCHAN(2412, 1, 0) ,
202 HDD2GHZCHAN(2417, 2, 0) ,
203 HDD2GHZCHAN(2422, 3, 0) ,
204 HDD2GHZCHAN(2427, 4, 0) ,
205 HDD2GHZCHAN(2432, 5, 0) ,
206 HDD2GHZCHAN(2437, 6, 0) ,
207 HDD2GHZCHAN(2442, 7, 0) ,
208 HDD2GHZCHAN(2447, 8, 0) ,
209 HDD2GHZCHAN(2452, 9, 0) ,
210 HDD2GHZCHAN(2457, 10, 0) ,
211 HDD2GHZCHAN(2462, 11, 0) ,
212 HDD2GHZCHAN(2467, 12, 0) ,
213 HDD2GHZCHAN(2472, 13, 0) ,
214 HDD2GHZCHAN(2484, 14, 0) ,
215};
216
Jeff Johnson295189b2012-06-20 16:38:30 -0700217static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
218{
219 HDD2GHZCHAN(2412, 1, 0) ,
220 HDD2GHZCHAN(2437, 6, 0) ,
221 HDD2GHZCHAN(2462, 11, 0) ,
222};
Jeff Johnson295189b2012-06-20 16:38:30 -0700223
224static struct ieee80211_channel hdd_channels_5_GHZ[] =
225{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700226 HDD5GHZCHAN(4920, 240, 0) ,
227 HDD5GHZCHAN(4940, 244, 0) ,
228 HDD5GHZCHAN(4960, 248, 0) ,
229 HDD5GHZCHAN(4980, 252, 0) ,
230 HDD5GHZCHAN(5040, 208, 0) ,
231 HDD5GHZCHAN(5060, 212, 0) ,
232 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700233 HDD5GHZCHAN(5180, 36, 0) ,
234 HDD5GHZCHAN(5200, 40, 0) ,
235 HDD5GHZCHAN(5220, 44, 0) ,
236 HDD5GHZCHAN(5240, 48, 0) ,
237 HDD5GHZCHAN(5260, 52, 0) ,
238 HDD5GHZCHAN(5280, 56, 0) ,
239 HDD5GHZCHAN(5300, 60, 0) ,
240 HDD5GHZCHAN(5320, 64, 0) ,
241 HDD5GHZCHAN(5500,100, 0) ,
242 HDD5GHZCHAN(5520,104, 0) ,
243 HDD5GHZCHAN(5540,108, 0) ,
244 HDD5GHZCHAN(5560,112, 0) ,
245 HDD5GHZCHAN(5580,116, 0) ,
246 HDD5GHZCHAN(5600,120, 0) ,
247 HDD5GHZCHAN(5620,124, 0) ,
248 HDD5GHZCHAN(5640,128, 0) ,
249 HDD5GHZCHAN(5660,132, 0) ,
250 HDD5GHZCHAN(5680,136, 0) ,
251 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800252#ifdef FEATURE_WLAN_CH144
253 HDD5GHZCHAN(5720,144, 0) ,
254#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700255 HDD5GHZCHAN(5745,149, 0) ,
256 HDD5GHZCHAN(5765,153, 0) ,
257 HDD5GHZCHAN(5785,157, 0) ,
258 HDD5GHZCHAN(5805,161, 0) ,
259 HDD5GHZCHAN(5825,165, 0) ,
260};
261
262static struct ieee80211_rate g_mode_rates[] =
263{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530264 HDD_G_MODE_RATETAB(10, 0x1, 0),
265 HDD_G_MODE_RATETAB(20, 0x2, 0),
266 HDD_G_MODE_RATETAB(55, 0x4, 0),
267 HDD_G_MODE_RATETAB(110, 0x8, 0),
268 HDD_G_MODE_RATETAB(60, 0x10, 0),
269 HDD_G_MODE_RATETAB(90, 0x20, 0),
270 HDD_G_MODE_RATETAB(120, 0x40, 0),
271 HDD_G_MODE_RATETAB(180, 0x80, 0),
272 HDD_G_MODE_RATETAB(240, 0x100, 0),
273 HDD_G_MODE_RATETAB(360, 0x200, 0),
274 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700275 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530276};
Jeff Johnson295189b2012-06-20 16:38:30 -0700277
278static struct ieee80211_rate a_mode_rates[] =
279{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530280 HDD_G_MODE_RATETAB(60, 0x10, 0),
281 HDD_G_MODE_RATETAB(90, 0x20, 0),
282 HDD_G_MODE_RATETAB(120, 0x40, 0),
283 HDD_G_MODE_RATETAB(180, 0x80, 0),
284 HDD_G_MODE_RATETAB(240, 0x100, 0),
285 HDD_G_MODE_RATETAB(360, 0x200, 0),
286 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700287 HDD_G_MODE_RATETAB(540, 0x800, 0),
288};
289
290static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
291{
292 .channels = hdd_channels_2_4_GHZ,
293 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
294 .band = IEEE80211_BAND_2GHZ,
295 .bitrates = g_mode_rates,
296 .n_bitrates = g_mode_rates_size,
297 .ht_cap.ht_supported = 1,
298 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
299 | IEEE80211_HT_CAP_GRN_FLD
300 | IEEE80211_HT_CAP_DSSSCCK40
301 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
302 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
303 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
304 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
305 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
306 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
307};
308
Jeff Johnson295189b2012-06-20 16:38:30 -0700309static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
310{
311 .channels = hdd_social_channels_2_4_GHZ,
312 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
313 .band = IEEE80211_BAND_2GHZ,
314 .bitrates = g_mode_rates,
315 .n_bitrates = g_mode_rates_size,
316 .ht_cap.ht_supported = 1,
317 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
318 | IEEE80211_HT_CAP_GRN_FLD
319 | IEEE80211_HT_CAP_DSSSCCK40
320 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
321 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
322 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
323 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
324 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
325 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
326};
Jeff Johnson295189b2012-06-20 16:38:30 -0700327
328static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
329{
330 .channels = hdd_channels_5_GHZ,
331 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
332 .band = IEEE80211_BAND_5GHZ,
333 .bitrates = a_mode_rates,
334 .n_bitrates = a_mode_rates_size,
335 .ht_cap.ht_supported = 1,
336 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
337 | IEEE80211_HT_CAP_GRN_FLD
338 | IEEE80211_HT_CAP_DSSSCCK40
339 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
340 | IEEE80211_HT_CAP_SGI_40
341 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
342 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
343 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
344 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
345 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
346 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
347};
348
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530349/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700350 TX/RX direction for each kind of interface */
351static const struct ieee80211_txrx_stypes
352wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
353 [NL80211_IFTYPE_STATION] = {
354 .tx = 0xffff,
355 .rx = BIT(SIR_MAC_MGMT_ACTION) |
356 BIT(SIR_MAC_MGMT_PROBE_REQ),
357 },
358 [NL80211_IFTYPE_AP] = {
359 .tx = 0xffff,
360 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
361 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
362 BIT(SIR_MAC_MGMT_PROBE_REQ) |
363 BIT(SIR_MAC_MGMT_DISASSOC) |
364 BIT(SIR_MAC_MGMT_AUTH) |
365 BIT(SIR_MAC_MGMT_DEAUTH) |
366 BIT(SIR_MAC_MGMT_ACTION),
367 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700368 [NL80211_IFTYPE_ADHOC] = {
369 .tx = 0xffff,
370 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
371 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
372 BIT(SIR_MAC_MGMT_PROBE_REQ) |
373 BIT(SIR_MAC_MGMT_DISASSOC) |
374 BIT(SIR_MAC_MGMT_AUTH) |
375 BIT(SIR_MAC_MGMT_DEAUTH) |
376 BIT(SIR_MAC_MGMT_ACTION),
377 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700378 [NL80211_IFTYPE_P2P_CLIENT] = {
379 .tx = 0xffff,
380 .rx = BIT(SIR_MAC_MGMT_ACTION) |
381 BIT(SIR_MAC_MGMT_PROBE_REQ),
382 },
383 [NL80211_IFTYPE_P2P_GO] = {
384 /* This is also same as for SoftAP */
385 .tx = 0xffff,
386 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
387 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
388 BIT(SIR_MAC_MGMT_PROBE_REQ) |
389 BIT(SIR_MAC_MGMT_DISASSOC) |
390 BIT(SIR_MAC_MGMT_AUTH) |
391 BIT(SIR_MAC_MGMT_DEAUTH) |
392 BIT(SIR_MAC_MGMT_ACTION),
393 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700394};
395
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800396#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800397static const struct ieee80211_iface_limit
398wlan_hdd_iface_limit[] = {
399 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800400 /* max = 3 ; Our driver create two interfaces during driver init
401 * wlan0 and p2p0 interfaces. p2p0 is considered as station
402 * interface until a group is formed. In JB architecture, once the
403 * group is formed, interface type of p2p0 is changed to P2P GO or
404 * Client.
405 * When supplicant remove the group, it first issue a set interface
406 * cmd to change the mode back to Station. In JB this works fine as
407 * we advertize two station type interface during driver init.
408 * Some vendors create separate interface for P2P GO/Client,
409 * after group formation(Third one). But while group remove
410 * supplicant first tries to change the mode(3rd interface) to STATION
411 * But as we advertized only two sta type interfaces nl80211 was
412 * returning error for the third one which was leading to failure in
413 * delete interface. Ideally while removing the group, supplicant
414 * should not try to change the 3rd interface mode to Station type.
415 * Till we get a fix in wpa_supplicant, we advertize max STA
416 * interface type to 3
417 */
418 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800419 .types = BIT(NL80211_IFTYPE_STATION),
420 },
421 {
422 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700423 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800424 },
425 {
426 .max = 1,
427 .types = BIT(NL80211_IFTYPE_P2P_GO) |
428 BIT(NL80211_IFTYPE_P2P_CLIENT),
429 },
430};
431
432/* By default, only single channel concurrency is allowed */
433static struct ieee80211_iface_combination
434wlan_hdd_iface_combination = {
435 .limits = wlan_hdd_iface_limit,
436 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800437 /*
438 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
439 * and p2p0 interfaces during driver init
440 * Some vendors create separate interface for P2P operations.
441 * wlan0: STA interface
442 * p2p0: P2P Device interface, action frames goes
443 * through this interface.
444 * p2p-xx: P2P interface, After GO negotiation this interface is
445 * created for p2p operations(GO/CLIENT interface).
446 */
447 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800448 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
449 .beacon_int_infra_match = false,
450};
451#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800452
Jeff Johnson295189b2012-06-20 16:38:30 -0700453static struct cfg80211_ops wlan_hdd_cfg80211_ops;
454
455/* Data rate 100KBPS based on IE Index */
456struct index_data_rate_type
457{
458 v_U8_t beacon_rate_index;
459 v_U16_t supported_rate[4];
460};
461
462/* 11B, 11G Rate table include Basic rate and Extended rate
463 The IDX field is the rate index
464 The HI field is the rate when RSSI is strong or being ignored
465 (in this case we report actual rate)
466 The MID field is the rate when RSSI is moderate
467 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
468 The LO field is the rate when RSSI is low
469 (in this case we don't report rates, actual current rate used)
470 */
471static const struct
472{
473 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700474 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700475} supported_data_rate[] =
476{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700477/* IDX HI HM LM LO (RSSI-based index */
478 {2, { 10, 10, 10, 0}},
479 {4, { 20, 20, 10, 0}},
480 {11, { 55, 20, 10, 0}},
481 {12, { 60, 55, 20, 0}},
482 {18, { 90, 55, 20, 0}},
483 {22, {110, 55, 20, 0}},
484 {24, {120, 90, 60, 0}},
485 {36, {180, 120, 60, 0}},
486 {44, {220, 180, 60, 0}},
487 {48, {240, 180, 90, 0}},
488 {66, {330, 180, 90, 0}},
489 {72, {360, 240, 90, 0}},
490 {96, {480, 240, 120, 0}},
491 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700492};
493
494/* MCS Based rate table */
495static struct index_data_rate_type supported_mcs_rate[] =
496{
497/* MCS L20 L40 S20 S40 */
498 {0, {65, 135, 72, 150}},
499 {1, {130, 270, 144, 300}},
500 {2, {195, 405, 217, 450}},
501 {3, {260, 540, 289, 600}},
502 {4, {390, 810, 433, 900}},
503 {5, {520, 1080, 578, 1200}},
504 {6, {585, 1215, 650, 1350}},
505 {7, {650, 1350, 722, 1500}}
506};
507
Leo Chang6f8870f2013-03-26 18:11:36 -0700508#ifdef WLAN_FEATURE_11AC
509
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530510#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700511
512struct index_vht_data_rate_type
513{
514 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530515 v_U16_t supported_VHT80_rate[2];
516 v_U16_t supported_VHT40_rate[2];
517 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700518};
519
520typedef enum
521{
522 DATA_RATE_11AC_MAX_MCS_7,
523 DATA_RATE_11AC_MAX_MCS_8,
524 DATA_RATE_11AC_MAX_MCS_9,
525 DATA_RATE_11AC_MAX_MCS_NA
526} eDataRate11ACMaxMcs;
527
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530528/* SSID broadcast type */
529typedef enum eSSIDBcastType
530{
531 eBCAST_UNKNOWN = 0,
532 eBCAST_NORMAL = 1,
533 eBCAST_HIDDEN = 2,
534} tSSIDBcastType;
535
Leo Chang6f8870f2013-03-26 18:11:36 -0700536/* MCS Based VHT rate table */
537static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
538{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530539/* MCS L80 S80 L40 S40 L20 S40*/
540 {0, {293, 325}, {135, 150}, {65, 72}},
541 {1, {585, 650}, {270, 300}, {130, 144}},
542 {2, {878, 975}, {405, 450}, {195, 217}},
543 {3, {1170, 1300}, {540, 600}, {260, 289}},
544 {4, {1755, 1950}, {810, 900}, {390, 433}},
545 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
546 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
547 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
548 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
549 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700550};
551#endif /* WLAN_FEATURE_11AC */
552
c_hpothu79aab322014-07-14 21:11:01 +0530553/*array index points to MCS and array value points respective rssi*/
554static int rssiMcsTbl[][10] =
555{
556/*MCS 0 1 2 3 4 5 6 7 8 9*/
557 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
558 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
559 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
560};
561
Jeff Johnson295189b2012-06-20 16:38:30 -0700562extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530563#ifdef FEATURE_WLAN_SCAN_PNO
564static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
565#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700566
Leo Chang9056f462013-08-01 19:21:11 -0700567#ifdef WLAN_NL80211_TESTMODE
568enum wlan_hdd_tm_attr
569{
570 WLAN_HDD_TM_ATTR_INVALID = 0,
571 WLAN_HDD_TM_ATTR_CMD = 1,
572 WLAN_HDD_TM_ATTR_DATA = 2,
573 WLAN_HDD_TM_ATTR_TYPE = 3,
574 /* keep last */
575 WLAN_HDD_TM_ATTR_AFTER_LAST,
576 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
577};
578
579enum wlan_hdd_tm_cmd
580{
581 WLAN_HDD_TM_CMD_WLAN_HB = 1,
582};
583
584#define WLAN_HDD_TM_DATA_MAX_LEN 5000
585
586static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
587{
588 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
589 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
590 .len = WLAN_HDD_TM_DATA_MAX_LEN },
591};
592#endif /* WLAN_NL80211_TESTMODE */
593
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800594#ifdef FEATURE_WLAN_CH_AVOID
595/*
596 * FUNCTION: wlan_hdd_send_avoid_freq_event
597 * This is called when wlan driver needs to send vendor specific
598 * avoid frequency range event to userspace
599 */
600int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
601 tHddAvoidFreqList *pAvoidFreqList)
602{
603 struct sk_buff *vendor_event;
604
605 ENTER();
606
607 if (!pHddCtx)
608 {
609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
610 "%s: HDD context is null", __func__);
611 return -1;
612 }
613
614 if (!pAvoidFreqList)
615 {
616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
617 "%s: pAvoidFreqList is null", __func__);
618 return -1;
619 }
620
621 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530622#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
623 NULL,
624#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800625 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530626 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800627 GFP_KERNEL);
628 if (!vendor_event)
629 {
630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
631 "%s: cfg80211_vendor_event_alloc failed", __func__);
632 return -1;
633 }
634
635 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
636 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
637
638 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
639
640 EXIT();
641 return 0;
642}
643#endif /* FEATURE_WLAN_CH_AVOID */
644
Srinivas Dasari030bad32015-02-18 23:23:54 +0530645/*
646 * FUNCTION: __wlan_hdd_cfg80211_nan_request
647 * This is called when wlan driver needs to send vendor specific
648 * nan request event.
649 */
650static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
651 struct wireless_dev *wdev,
652 const void *data, int data_len)
653{
654 tNanRequestReq nan_req;
655 VOS_STATUS status;
656 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530657 struct net_device *dev = wdev->netdev;
658 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
659 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530660 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
661
662 if (0 == data_len)
663 {
664 hddLog(VOS_TRACE_LEVEL_ERROR,
665 FL("NAN - Invalid Request, length = 0"));
666 return ret_val;
667 }
668
669 if (NULL == data)
670 {
671 hddLog(VOS_TRACE_LEVEL_ERROR,
672 FL("NAN - Invalid Request, data is NULL"));
673 return ret_val;
674 }
675
676 status = wlan_hdd_validate_context(pHddCtx);
677 if (0 != status)
678 {
679 hddLog(VOS_TRACE_LEVEL_ERROR,
680 FL("HDD context is not valid"));
681 return -EINVAL;
682 }
683
684 hddLog(LOG1, FL("Received NAN command"));
685 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
686 (tANI_U8 *)data, data_len);
687
688 /* check the NAN Capability */
689 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
690 {
691 hddLog(VOS_TRACE_LEVEL_ERROR,
692 FL("NAN is not supported by Firmware"));
693 return -EINVAL;
694 }
695
696 nan_req.request_data_len = data_len;
697 nan_req.request_data = data;
698
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530699 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530700 if (VOS_STATUS_SUCCESS == status)
701 {
702 ret_val = 0;
703 }
704 return ret_val;
705}
706
707/*
708 * FUNCTION: wlan_hdd_cfg80211_nan_request
709 * Wrapper to protect the nan vendor command from ssr
710 */
711static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
712 struct wireless_dev *wdev,
713 const void *data, int data_len)
714{
715 int ret;
716
717 vos_ssr_protect(__func__);
718 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
719 vos_ssr_unprotect(__func__);
720
721 return ret;
722}
723
724/*
725 * FUNCTION: wlan_hdd_cfg80211_nan_callback
726 * This is a callback function and it gets called
727 * when we need to report nan response event to
728 * upper layers.
729 */
730static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
731{
732 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
733 struct sk_buff *vendor_event;
734 int status;
735 tSirNanEvent *data;
736
737 ENTER();
738 if (NULL == msg)
739 {
740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
741 FL(" msg received here is null"));
742 return;
743 }
744 data = msg;
745
746 status = wlan_hdd_validate_context(pHddCtx);
747
748 if (0 != status)
749 {
750 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
751 FL("HDD context is not valid"));
752 return;
753 }
754
755 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530756#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
757 NULL,
758#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530759 data->event_data_len +
760 NLMSG_HDRLEN,
761 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
762 GFP_KERNEL);
763
764 if (!vendor_event)
765 {
766 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
767 FL("cfg80211_vendor_event_alloc failed"));
768 return;
769 }
770 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
771 data->event_data_len, data->event_data))
772 {
773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
774 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
775 kfree_skb(vendor_event);
776 return;
777 }
778 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
779 EXIT();
780}
781
782/*
783 * FUNCTION: wlan_hdd_cfg80211_nan_init
784 * This function is called to register the callback to sme layer
785 */
786inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
787{
788 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
789}
790
791
Sunil Duttc69bccb2014-05-26 21:30:20 +0530792#ifdef WLAN_FEATURE_LINK_LAYER_STATS
793
794static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
795 struct sk_buff *vendor_event)
796{
797 if (nla_put_u8(vendor_event,
798 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
799 stats->rate.preamble) ||
800 nla_put_u8(vendor_event,
801 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
802 stats->rate.nss) ||
803 nla_put_u8(vendor_event,
804 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
805 stats->rate.bw) ||
806 nla_put_u8(vendor_event,
807 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
808 stats->rate.rateMcsIdx) ||
809 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
810 stats->rate.bitrate ) ||
811 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
812 stats->txMpdu ) ||
813 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
814 stats->rxMpdu ) ||
815 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
816 stats->mpduLost ) ||
817 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
818 stats->retries) ||
819 nla_put_u32(vendor_event,
820 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
821 stats->retriesShort ) ||
822 nla_put_u32(vendor_event,
823 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
824 stats->retriesLong))
825 {
826 hddLog(VOS_TRACE_LEVEL_ERROR,
827 FL("QCA_WLAN_VENDOR_ATTR put fail"));
828 return FALSE;
829 }
830 return TRUE;
831}
832
833static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
834 struct sk_buff *vendor_event)
835{
836 u32 i = 0;
837 struct nlattr *rateInfo;
838 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
839 stats->type) ||
840 nla_put(vendor_event,
841 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
842 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
843 nla_put_u32(vendor_event,
844 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
845 stats->capabilities) ||
846 nla_put_u32(vendor_event,
847 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
848 stats->numRate))
849 {
850 hddLog(VOS_TRACE_LEVEL_ERROR,
851 FL("QCA_WLAN_VENDOR_ATTR put fail"));
852 goto error;
853 }
854
855 rateInfo = nla_nest_start(vendor_event,
856 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530857 if(!rateInfo)
858 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530859 for (i = 0; i < stats->numRate; i++)
860 {
861 struct nlattr *rates;
862 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
863 stats->rateStats +
864 (i * sizeof(tSirWifiRateStat)));
865 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530866 if(!rates)
867 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530868
869 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
870 {
871 hddLog(VOS_TRACE_LEVEL_ERROR,
872 FL("QCA_WLAN_VENDOR_ATTR put fail"));
873 return FALSE;
874 }
875 nla_nest_end(vendor_event, rates);
876 }
877 nla_nest_end(vendor_event, rateInfo);
878
879 return TRUE;
880error:
881 return FALSE;
882}
883
884static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
885 struct sk_buff *vendor_event)
886{
887 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
888 stats->ac ) ||
889 nla_put_u32(vendor_event,
890 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
891 stats->txMpdu ) ||
892 nla_put_u32(vendor_event,
893 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
894 stats->rxMpdu ) ||
895 nla_put_u32(vendor_event,
896 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
897 stats->txMcast ) ||
898 nla_put_u32(vendor_event,
899 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
900 stats->rxMcast ) ||
901 nla_put_u32(vendor_event,
902 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
903 stats->rxAmpdu ) ||
904 nla_put_u32(vendor_event,
905 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
906 stats->txAmpdu ) ||
907 nla_put_u32(vendor_event,
908 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
909 stats->mpduLost )||
910 nla_put_u32(vendor_event,
911 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
912 stats->retries ) ||
913 nla_put_u32(vendor_event,
914 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
915 stats->retriesShort ) ||
916 nla_put_u32(vendor_event,
917 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
918 stats->retriesLong ) ||
919 nla_put_u32(vendor_event,
920 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
921 stats->contentionTimeMin ) ||
922 nla_put_u32(vendor_event,
923 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
924 stats->contentionTimeMax ) ||
925 nla_put_u32(vendor_event,
926 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
927 stats->contentionTimeAvg ) ||
928 nla_put_u32(vendor_event,
929 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
930 stats->contentionNumSamples ))
931 {
932 hddLog(VOS_TRACE_LEVEL_ERROR,
933 FL("QCA_WLAN_VENDOR_ATTR put fail") );
934 return FALSE;
935 }
936 return TRUE;
937}
938
939static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
940 struct sk_buff *vendor_event)
941{
Dino Myclec8f3f332014-07-21 16:48:27 +0530942 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530943 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
944 nla_put(vendor_event,
945 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
946 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
947 nla_put_u32(vendor_event,
948 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
949 stats->state ) ||
950 nla_put_u32(vendor_event,
951 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
952 stats->roaming ) ||
953 nla_put_u32(vendor_event,
954 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
955 stats->capabilities ) ||
956 nla_put(vendor_event,
957 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
958 strlen(stats->ssid), stats->ssid) ||
959 nla_put(vendor_event,
960 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
961 WNI_CFG_BSSID_LEN, stats->bssid) ||
962 nla_put(vendor_event,
963 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
964 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
965 nla_put(vendor_event,
966 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
967 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
968 )
969 {
970 hddLog(VOS_TRACE_LEVEL_ERROR,
971 FL("QCA_WLAN_VENDOR_ATTR put fail") );
972 return FALSE;
973 }
974 return TRUE;
975}
976
Dino Mycle3b9536d2014-07-09 22:05:24 +0530977static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
978 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530979 struct sk_buff *vendor_event)
980{
981 int i = 0;
982 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530983 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
984 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530985 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530986
Sunil Duttc69bccb2014-05-26 21:30:20 +0530987 if (FALSE == put_wifi_interface_info(
988 &pWifiIfaceStat->info,
989 vendor_event))
990 {
991 hddLog(VOS_TRACE_LEVEL_ERROR,
992 FL("QCA_WLAN_VENDOR_ATTR put fail") );
993 return FALSE;
994
995 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530996 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
997 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
998 if (NULL == pWifiIfaceStatTL)
999 {
1000 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1001 return FALSE;
1002 }
1003
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301004 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1005 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1006 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1007 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1008
1009 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1010 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1011 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1012 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301013
1014 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1015 {
1016 if (VOS_STATUS_SUCCESS ==
1017 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1018 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1019 {
1020 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1021 * obtained from TL structure
1022 */
1023
1024 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1025 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301026 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1027
Srinivas Dasari98947432014-11-07 19:41:24 +05301028 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1029 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1030 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1031 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1032 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1033 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1034 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1035 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301036
Srinivas Dasari98947432014-11-07 19:41:24 +05301037 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1038 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1039 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1040 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1041 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1042 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1043 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1044 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301045
Srinivas Dasari98947432014-11-07 19:41:24 +05301046 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1047 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1048 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1049 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1050 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1051 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1052 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1053 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301054 }
1055 else
1056 {
1057 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1058 }
1059
Dino Mycle3b9536d2014-07-09 22:05:24 +05301060 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1061 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1062 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1063 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1064 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1065 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1066 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1067 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1068 }
1069 else
1070 {
1071 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1072 }
1073
1074
Sunil Duttc69bccb2014-05-26 21:30:20 +05301075
1076 if (nla_put_u32(vendor_event,
1077 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1078 pWifiIfaceStat->beaconRx) ||
1079 nla_put_u32(vendor_event,
1080 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1081 pWifiIfaceStat->mgmtRx) ||
1082 nla_put_u32(vendor_event,
1083 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1084 pWifiIfaceStat->mgmtActionRx) ||
1085 nla_put_u32(vendor_event,
1086 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1087 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301088 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301089 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1090 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301091 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301092 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1093 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301094 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301095 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1096 pWifiIfaceStat->rssiAck))
1097 {
1098 hddLog(VOS_TRACE_LEVEL_ERROR,
1099 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301100 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301101 return FALSE;
1102 }
1103
1104 wmmInfo = nla_nest_start(vendor_event,
1105 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301106 if(!wmmInfo)
1107 {
1108 vos_mem_free(pWifiIfaceStatTL);
1109 return FALSE;
1110 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301111 for (i = 0; i < WIFI_AC_MAX; i++)
1112 {
1113 struct nlattr *wmmStats;
1114 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301115 if(!wmmStats)
1116 {
1117 vos_mem_free(pWifiIfaceStatTL);
1118 return FALSE;
1119 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301120 if (FALSE == put_wifi_wmm_ac_stat(
1121 &pWifiIfaceStat->AccessclassStats[i],
1122 vendor_event))
1123 {
1124 hddLog(VOS_TRACE_LEVEL_ERROR,
1125 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301126 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301127 return FALSE;
1128 }
1129
1130 nla_nest_end(vendor_event, wmmStats);
1131 }
1132 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301133 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301134 return TRUE;
1135}
1136
1137static tSirWifiInterfaceMode
1138 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1139{
1140 switch (deviceMode)
1141 {
1142 case WLAN_HDD_INFRA_STATION:
1143 return WIFI_INTERFACE_STA;
1144 case WLAN_HDD_SOFTAP:
1145 return WIFI_INTERFACE_SOFTAP;
1146 case WLAN_HDD_P2P_CLIENT:
1147 return WIFI_INTERFACE_P2P_CLIENT;
1148 case WLAN_HDD_P2P_GO:
1149 return WIFI_INTERFACE_P2P_GO;
1150 case WLAN_HDD_IBSS:
1151 return WIFI_INTERFACE_IBSS;
1152 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301153 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301154 }
1155}
1156
1157static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1158 tpSirWifiInterfaceInfo pInfo)
1159{
1160 v_U8_t *staMac = NULL;
1161 hdd_station_ctx_t *pHddStaCtx;
1162 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1163 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1164
1165 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1166
1167 vos_mem_copy(pInfo->macAddr,
1168 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1169
1170 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1171 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1172 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1173 {
1174 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1175 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1176 {
1177 pInfo->state = WIFI_DISCONNECTED;
1178 }
1179 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1180 {
1181 hddLog(VOS_TRACE_LEVEL_ERROR,
1182 "%s: Session ID %d, Connection is in progress", __func__,
1183 pAdapter->sessionId);
1184 pInfo->state = WIFI_ASSOCIATING;
1185 }
1186 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1187 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1188 {
1189 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1190 hddLog(VOS_TRACE_LEVEL_ERROR,
1191 "%s: client " MAC_ADDRESS_STR
1192 " is in the middle of WPS/EAPOL exchange.", __func__,
1193 MAC_ADDR_ARRAY(staMac));
1194 pInfo->state = WIFI_AUTHENTICATING;
1195 }
1196 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1197 {
1198 pInfo->state = WIFI_ASSOCIATED;
1199 vos_mem_copy(pInfo->bssid,
1200 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1201 vos_mem_copy(pInfo->ssid,
1202 pHddStaCtx->conn_info.SSID.SSID.ssId,
1203 pHddStaCtx->conn_info.SSID.SSID.length);
1204 //NULL Terminate the string.
1205 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1206 }
1207 }
1208 vos_mem_copy(pInfo->countryStr,
1209 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1210
1211 vos_mem_copy(pInfo->apCountryStr,
1212 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1213
1214 return TRUE;
1215}
1216
1217/*
1218 * hdd_link_layer_process_peer_stats () - This function is called after
1219 * receiving Link Layer Peer statistics from FW.This function converts
1220 * the firmware data to the NL data and sends the same to the kernel/upper
1221 * layers.
1222 */
1223static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1224 v_VOID_t *pData)
1225{
1226 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1227 tpSirWifiRateStat pWifiRateStat;
1228 tpSirWifiPeerStat pWifiPeerStat;
1229 tpSirWifiPeerInfo pWifiPeerInfo;
1230 struct nlattr *peerInfo;
1231 struct sk_buff *vendor_event;
1232 int status, i;
1233
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301234 ENTER();
1235
Sunil Duttc69bccb2014-05-26 21:30:20 +05301236 status = wlan_hdd_validate_context(pHddCtx);
1237 if (0 != status)
1238 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301239 return;
1240 }
1241
1242 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1243
1244 hddLog(VOS_TRACE_LEVEL_INFO,
1245 "LL_STATS_PEER_ALL : numPeers %u",
1246 pWifiPeerStat->numPeers);
1247 {
1248 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1249 {
1250 pWifiPeerInfo = (tpSirWifiPeerInfo)
1251 ((uint8 *)pWifiPeerStat->peerInfo +
1252 ( i * sizeof(tSirWifiPeerInfo)));
1253
Dasari Srinivas1be0c4e2014-10-19 13:03:41 +05301254 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) {
1255 pWifiPeerInfo->type = WIFI_PEER_AP;
1256 }
1257 if (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) {
1258 pWifiPeerInfo->type = WIFI_PEER_P2P_GO;
1259 }
1260
Sunil Duttc69bccb2014-05-26 21:30:20 +05301261 hddLog(VOS_TRACE_LEVEL_INFO,
1262 " %d) LL_STATS Channel Stats "
1263 " Peer Type %u "
1264 " peerMacAddress %pM "
1265 " capabilities 0x%x "
1266 " numRate %u ",
1267 i,
1268 pWifiPeerInfo->type,
1269 pWifiPeerInfo->peerMacAddress,
1270 pWifiPeerInfo->capabilities,
1271 pWifiPeerInfo->numRate);
1272 {
1273 int j;
1274 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1275 {
1276 pWifiRateStat = (tpSirWifiRateStat)
1277 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1278 ( j * sizeof(tSirWifiRateStat)));
1279
1280 hddLog(VOS_TRACE_LEVEL_INFO,
1281 " peer Rate Stats "
1282 " preamble %u "
1283 " nss %u "
1284 " bw %u "
1285 " rateMcsIdx %u "
1286 " reserved %u "
1287 " bitrate %u "
1288 " txMpdu %u "
1289 " rxMpdu %u "
1290 " mpduLost %u "
1291 " retries %u "
1292 " retriesShort %u "
1293 " retriesLong %u",
1294 pWifiRateStat->rate.preamble,
1295 pWifiRateStat->rate.nss,
1296 pWifiRateStat->rate.bw,
1297 pWifiRateStat->rate.rateMcsIdx,
1298 pWifiRateStat->rate.reserved,
1299 pWifiRateStat->rate.bitrate,
1300 pWifiRateStat->txMpdu,
1301 pWifiRateStat->rxMpdu,
1302 pWifiRateStat->mpduLost,
1303 pWifiRateStat->retries,
1304 pWifiRateStat->retriesShort,
1305 pWifiRateStat->retriesLong);
1306 }
1307 }
1308 }
1309 }
1310
1311 /*
1312 * Allocate a size of 4096 for the peer stats comprising
1313 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1314 * sizeof (tSirWifiRateStat).Each field is put with an
1315 * NL attribute.The size of 4096 is considered assuming
1316 * that number of rates shall not exceed beyond 50 with
1317 * the sizeof (tSirWifiRateStat) being 32.
1318 */
1319 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05301320#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
1321 NULL,
1322#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301323 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1324 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1325 GFP_KERNEL);
1326 if (!vendor_event)
1327 {
1328 hddLog(VOS_TRACE_LEVEL_ERROR,
1329 "%s: cfg80211_vendor_event_alloc failed",
1330 __func__);
1331 return;
1332 }
1333 if (nla_put_u32(vendor_event,
1334 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1335 pWifiPeerStat->numPeers))
1336 {
1337 hddLog(VOS_TRACE_LEVEL_ERROR,
1338 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1339 kfree_skb(vendor_event);
1340 return;
1341 }
1342
1343 peerInfo = nla_nest_start(vendor_event,
1344 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301345 if(!peerInfo)
1346 {
1347 hddLog(VOS_TRACE_LEVEL_ERROR,
1348 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1349 __func__);
1350 kfree_skb(vendor_event);
1351 return;
1352 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301353
1354 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1355 pWifiPeerStat->peerInfo);
1356
1357 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1358 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301359 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301360 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301361
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301362 if(!peers)
1363 {
1364 hddLog(VOS_TRACE_LEVEL_ERROR,
1365 "%s: peer stats put fail",
1366 __func__);
1367 kfree_skb(vendor_event);
1368 return;
1369 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301370 if (FALSE == put_wifi_peer_info(
1371 pWifiPeerInfo, vendor_event))
1372 {
1373 hddLog(VOS_TRACE_LEVEL_ERROR,
1374 "%s: put_wifi_peer_info put fail", __func__);
1375 kfree_skb(vendor_event);
1376 return;
1377 }
1378
1379 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1380 pWifiPeerStat->peerInfo +
1381 (i * sizeof(tSirWifiPeerInfo)) +
1382 (numRate * sizeof (tSirWifiRateStat)));
1383 nla_nest_end(vendor_event, peers);
1384 }
1385 nla_nest_end(vendor_event, peerInfo);
1386 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301387
1388 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301389}
1390
1391/*
1392 * hdd_link_layer_process_iface_stats () - This function is called after
1393 * receiving Link Layer Interface statistics from FW.This function converts
1394 * the firmware data to the NL data and sends the same to the kernel/upper
1395 * layers.
1396 */
1397static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1398 v_VOID_t *pData)
1399{
1400 tpSirWifiIfaceStat pWifiIfaceStat;
1401 struct sk_buff *vendor_event;
1402 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1403 int status;
1404
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301405 ENTER();
1406
Sunil Duttc69bccb2014-05-26 21:30:20 +05301407 status = wlan_hdd_validate_context(pHddCtx);
1408 if (0 != status)
1409 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301410 return;
1411 }
1412 /*
1413 * Allocate a size of 4096 for the interface stats comprising
1414 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1415 * assuming that all these fit with in the limit.Please take
1416 * a call on the limit based on the data requirements on
1417 * interface statistics.
1418 */
1419 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05301420#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
1421 NULL,
1422#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301423 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1424 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1425 GFP_KERNEL);
1426 if (!vendor_event)
1427 {
1428 hddLog(VOS_TRACE_LEVEL_ERROR,
1429 FL("cfg80211_vendor_event_alloc failed") );
1430 return;
1431 }
1432
1433 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1434
Dino Mycle3b9536d2014-07-09 22:05:24 +05301435
1436 if (FALSE == hdd_get_interface_info( pAdapter,
1437 &pWifiIfaceStat->info))
1438 {
1439 hddLog(VOS_TRACE_LEVEL_ERROR,
1440 FL("hdd_get_interface_info get fail") );
1441 kfree_skb(vendor_event);
1442 return;
1443 }
1444
1445 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1446 vendor_event))
1447 {
1448 hddLog(VOS_TRACE_LEVEL_ERROR,
1449 FL("put_wifi_iface_stats fail") );
1450 kfree_skb(vendor_event);
1451 return;
1452 }
1453
Sunil Duttc69bccb2014-05-26 21:30:20 +05301454 hddLog(VOS_TRACE_LEVEL_INFO,
1455 "WMI_LINK_STATS_IFACE Data");
1456
1457 hddLog(VOS_TRACE_LEVEL_INFO,
1458 "LL_STATS_IFACE: "
1459 " Mode %u "
1460 " MAC %pM "
1461 " State %u "
1462 " Roaming %u "
1463 " capabilities 0x%x "
1464 " SSID %s "
1465 " BSSID %pM",
1466 pWifiIfaceStat->info.mode,
1467 pWifiIfaceStat->info.macAddr,
1468 pWifiIfaceStat->info.state,
1469 pWifiIfaceStat->info.roaming,
1470 pWifiIfaceStat->info.capabilities,
1471 pWifiIfaceStat->info.ssid,
1472 pWifiIfaceStat->info.bssid);
1473
1474 hddLog(VOS_TRACE_LEVEL_INFO,
1475 " AP country str: %c%c%c",
1476 pWifiIfaceStat->info.apCountryStr[0],
1477 pWifiIfaceStat->info.apCountryStr[1],
1478 pWifiIfaceStat->info.apCountryStr[2]);
1479
1480
1481 hddLog(VOS_TRACE_LEVEL_INFO,
1482 " Country Str Association: %c%c%c",
1483 pWifiIfaceStat->info.countryStr[0],
1484 pWifiIfaceStat->info.countryStr[1],
1485 pWifiIfaceStat->info.countryStr[2]);
1486
1487 hddLog(VOS_TRACE_LEVEL_INFO,
1488 " beaconRx %u "
1489 " mgmtRx %u "
1490 " mgmtActionRx %u "
1491 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301492 " rssiMgmt %d "
1493 " rssiData %d "
1494 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301495 pWifiIfaceStat->beaconRx,
1496 pWifiIfaceStat->mgmtRx,
1497 pWifiIfaceStat->mgmtActionRx,
1498 pWifiIfaceStat->mgmtActionTx,
1499 pWifiIfaceStat->rssiMgmt,
1500 pWifiIfaceStat->rssiData,
1501 pWifiIfaceStat->rssiAck );
1502
1503
1504 {
1505 int i;
1506 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1507 {
1508 hddLog(VOS_TRACE_LEVEL_INFO,
1509
1510 " %d) LL_STATS IFACE: "
1511 " ac: %u txMpdu: %u "
1512 " rxMpdu: %u txMcast: %u "
1513 " rxMcast: %u rxAmpdu: %u "
1514 " txAmpdu: %u mpduLost: %u "
1515 " retries: %u retriesShort: %u "
1516 " retriesLong: %u contentionTimeMin: %u "
1517 " contentionTimeMax: %u contentionTimeAvg: %u "
1518 " contentionNumSamples: %u",
1519 i,
1520 pWifiIfaceStat->AccessclassStats[i].ac,
1521 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1522 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1523 pWifiIfaceStat->AccessclassStats[i].txMcast,
1524 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1525 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1526 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1527 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1528 pWifiIfaceStat->AccessclassStats[i].retries,
1529 pWifiIfaceStat->
1530 AccessclassStats[i].retriesShort,
1531 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1532 pWifiIfaceStat->
1533 AccessclassStats[i].contentionTimeMin,
1534 pWifiIfaceStat->
1535 AccessclassStats[i].contentionTimeMax,
1536 pWifiIfaceStat->
1537 AccessclassStats[i].contentionTimeAvg,
1538 pWifiIfaceStat->
1539 AccessclassStats[i].contentionNumSamples);
1540
1541 }
1542 }
1543
Sunil Duttc69bccb2014-05-26 21:30:20 +05301544 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301545
1546 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301547}
1548
1549/*
1550 * hdd_link_layer_process_radio_stats () - This function is called after
1551 * receiving Link Layer Radio statistics from FW.This function converts
1552 * the firmware data to the NL data and sends the same to the kernel/upper
1553 * layers.
1554 */
1555static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1556 v_VOID_t *pData)
1557{
1558 int status, i;
1559 tpSirWifiRadioStat pWifiRadioStat;
1560 tpSirWifiChannelStats pWifiChannelStats;
1561 struct sk_buff *vendor_event;
1562 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1563 struct nlattr *chList;
1564
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301565 ENTER();
1566
Sunil Duttc69bccb2014-05-26 21:30:20 +05301567 status = wlan_hdd_validate_context(pHddCtx);
1568 if (0 != status)
1569 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301570 return;
1571 }
1572 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1573
1574 hddLog(VOS_TRACE_LEVEL_INFO,
1575 "LL_STATS_RADIO"
1576 " radio is %d onTime is %u "
1577 " txTime is %u rxTime is %u "
1578 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301579 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301580 " onTimePnoScan is %u onTimeHs20 is %u "
1581 " numChannels is %u",
1582 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1583 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1584 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301585 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301586 pWifiRadioStat->onTimeRoamScan,
1587 pWifiRadioStat->onTimePnoScan,
1588 pWifiRadioStat->onTimeHs20,
1589 pWifiRadioStat->numChannels);
1590 /*
1591 * Allocate a size of 4096 for the Radio stats comprising
1592 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1593 * (tSirWifiChannelStats).Each channel data is put with an
1594 * NL attribute.The size of 4096 is considered assuming that
1595 * number of channels shall not exceed beyond 60 with the
1596 * sizeof (tSirWifiChannelStats) being 24 bytes.
1597 */
1598
1599 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05301600#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
1601 NULL,
1602#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301603 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1604 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1605 GFP_KERNEL);
1606
1607 if (!vendor_event)
1608 {
1609 hddLog(VOS_TRACE_LEVEL_ERROR,
1610 FL("cfg80211_vendor_event_alloc failed") );
1611 return;
1612 }
1613
1614 if (nla_put_u32(vendor_event,
1615 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1616 pWifiRadioStat->radio) ||
1617 nla_put_u32(vendor_event,
1618 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1619 pWifiRadioStat->onTime) ||
1620 nla_put_u32(vendor_event,
1621 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1622 pWifiRadioStat->txTime) ||
1623 nla_put_u32(vendor_event,
1624 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1625 pWifiRadioStat->rxTime) ||
1626 nla_put_u32(vendor_event,
1627 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1628 pWifiRadioStat->onTimeScan) ||
1629 nla_put_u32(vendor_event,
1630 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1631 pWifiRadioStat->onTimeNbd) ||
1632 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301633 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1634 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301635 nla_put_u32(vendor_event,
1636 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1637 pWifiRadioStat->onTimeRoamScan) ||
1638 nla_put_u32(vendor_event,
1639 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1640 pWifiRadioStat->onTimePnoScan) ||
1641 nla_put_u32(vendor_event,
1642 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1643 pWifiRadioStat->onTimeHs20) ||
1644 nla_put_u32(vendor_event,
1645 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1646 pWifiRadioStat->numChannels))
1647 {
1648 hddLog(VOS_TRACE_LEVEL_ERROR,
1649 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1650 kfree_skb(vendor_event);
1651 return ;
1652 }
1653
1654 chList = nla_nest_start(vendor_event,
1655 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301656 if(!chList)
1657 {
1658 hddLog(VOS_TRACE_LEVEL_ERROR,
1659 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1660 __func__);
1661 kfree_skb(vendor_event);
1662 return;
1663 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301664 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1665 {
1666 struct nlattr *chInfo;
1667
1668 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1669 pWifiRadioStat->channels +
1670 (i * sizeof(tSirWifiChannelStats)));
1671
1672 hddLog(VOS_TRACE_LEVEL_INFO,
1673 " %d) Channel Info"
1674 " width is %u "
1675 " CenterFreq %u "
1676 " CenterFreq0 %u "
1677 " CenterFreq1 %u "
1678 " onTime %u "
1679 " ccaBusyTime %u",
1680 i,
1681 pWifiChannelStats->channel.width,
1682 pWifiChannelStats->channel.centerFreq,
1683 pWifiChannelStats->channel.centerFreq0,
1684 pWifiChannelStats->channel.centerFreq1,
1685 pWifiChannelStats->onTime,
1686 pWifiChannelStats->ccaBusyTime);
1687
1688
1689 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301690 if(!chInfo)
1691 {
1692 hddLog(VOS_TRACE_LEVEL_ERROR,
1693 "%s: failed to put chInfo",
1694 __func__);
1695 kfree_skb(vendor_event);
1696 return;
1697 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301698
1699 if (nla_put_u32(vendor_event,
1700 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1701 pWifiChannelStats->channel.width) ||
1702 nla_put_u32(vendor_event,
1703 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1704 pWifiChannelStats->channel.centerFreq) ||
1705 nla_put_u32(vendor_event,
1706 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1707 pWifiChannelStats->channel.centerFreq0) ||
1708 nla_put_u32(vendor_event,
1709 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1710 pWifiChannelStats->channel.centerFreq1) ||
1711 nla_put_u32(vendor_event,
1712 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1713 pWifiChannelStats->onTime) ||
1714 nla_put_u32(vendor_event,
1715 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1716 pWifiChannelStats->ccaBusyTime))
1717 {
1718 hddLog(VOS_TRACE_LEVEL_ERROR,
1719 FL("cfg80211_vendor_event_alloc failed") );
1720 kfree_skb(vendor_event);
1721 return ;
1722 }
1723 nla_nest_end(vendor_event, chInfo);
1724 }
1725 nla_nest_end(vendor_event, chList);
1726
1727 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301728
1729 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301730 return;
1731}
1732
1733/*
1734 * hdd_link_layer_stats_ind_callback () - This function is called after
1735 * receiving Link Layer indications from FW.This callback converts the firmware
1736 * data to the NL data and send the same to the kernel/upper layers.
1737 */
1738static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1739 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301740 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301741{
Dino Mycled3d50022014-07-07 12:58:25 +05301742 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1743 hdd_adapter_t *pAdapter = NULL;
1744 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301745 int status;
1746
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301747 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301748
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301749 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301750 if (0 != status)
1751 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301752 return;
1753 }
1754
Dino Mycled3d50022014-07-07 12:58:25 +05301755 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1756 if (NULL == pAdapter)
1757 {
1758 hddLog(VOS_TRACE_LEVEL_ERROR,
1759 FL(" MAC address %pM does not exist with host"),
1760 macAddr);
1761 return;
1762 }
1763
Sunil Duttc69bccb2014-05-26 21:30:20 +05301764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301765 "%s: Interface: %s LLStats indType: %d", __func__,
1766 pAdapter->dev->name, indType);
1767
Sunil Duttc69bccb2014-05-26 21:30:20 +05301768 switch (indType)
1769 {
1770 case SIR_HAL_LL_STATS_RESULTS_RSP:
1771 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301772 hddLog(VOS_TRACE_LEVEL_INFO,
1773 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1774 hddLog(VOS_TRACE_LEVEL_INFO,
1775 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1776 linkLayerStatsResults->paramId);
1777 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301778 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1779 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301780 hddLog(VOS_TRACE_LEVEL_INFO,
1781 "LL_STATS RESULTS RESPONSE respId = %u",
1782 linkLayerStatsResults->respId);
1783 hddLog(VOS_TRACE_LEVEL_INFO,
1784 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1785 linkLayerStatsResults->moreResultToFollow);
1786 hddLog(VOS_TRACE_LEVEL_INFO,
1787 "LL_STATS RESULTS RESPONSE result = %p",
1788 linkLayerStatsResults->result);
1789 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1790 {
1791 hdd_link_layer_process_radio_stats(pAdapter,
1792 (v_VOID_t *)linkLayerStatsResults->result);
1793 }
1794 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1795 {
1796 hdd_link_layer_process_iface_stats(pAdapter,
1797 (v_VOID_t *)linkLayerStatsResults->result);
1798 }
1799 else if ( linkLayerStatsResults->paramId &
1800 WMI_LINK_STATS_ALL_PEER )
1801 {
1802 hdd_link_layer_process_peer_stats(pAdapter,
1803 (v_VOID_t *)linkLayerStatsResults->result);
1804 } /* WMI_LINK_STATS_ALL_PEER */
1805 else
1806 {
1807 hddLog(VOS_TRACE_LEVEL_ERROR,
1808 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1809 }
1810
1811 break;
1812 }
1813 default:
1814 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1815 break;
1816 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301817
1818 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301819 return;
1820}
1821
1822const struct
1823nla_policy
1824qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1825{
1826 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1827 { .type = NLA_U32 },
1828 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1829 { .type = NLA_U32 },
1830};
1831
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301832static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1833 struct wireless_dev *wdev,
1834 const void *data,
1835 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301836{
1837 int status;
1838 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301839 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301840 struct net_device *dev = wdev->netdev;
1841 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1842 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Srinivas Dasari98947432014-11-07 19:41:24 +05301843 hdd_station_ctx_t *pHddStaCtx;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301844
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301845 ENTER();
1846
Sunil Duttc69bccb2014-05-26 21:30:20 +05301847 status = wlan_hdd_validate_context(pHddCtx);
1848 if (0 != status)
1849 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301850 return -EINVAL;
1851 }
1852
1853 if (NULL == pAdapter)
1854 {
1855 hddLog(VOS_TRACE_LEVEL_ERROR,
1856 FL("HDD adapter is Null"));
1857 return -ENODEV;
1858 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301859 /* check the LLStats Capability */
1860 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1861 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1862 {
1863 hddLog(VOS_TRACE_LEVEL_ERROR,
1864 FL("Link Layer Statistics not supported by Firmware"));
1865 return -EINVAL;
1866 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301867
1868 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1869 (struct nlattr *)data,
1870 data_len, qca_wlan_vendor_ll_set_policy))
1871 {
1872 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1873 return -EINVAL;
1874 }
1875 if (!tb_vendor
1876 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1877 {
1878 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1879 return -EINVAL;
1880 }
1881 if (!tb_vendor[
1882 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1883 {
1884 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1885 return -EINVAL;
1886 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301887 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301888 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301889
Dino Mycledf0a5d92014-07-04 09:41:55 +05301890 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301891 nla_get_u32(
1892 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1893
Dino Mycledf0a5d92014-07-04 09:41:55 +05301894 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301895 nla_get_u32(
1896 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1897
Dino Mycled3d50022014-07-07 12:58:25 +05301898 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1899 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301900
1901
1902 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301903 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301904 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301905 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301906 hddLog(VOS_TRACE_LEVEL_INFO,
1907 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301908 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301909 hddLog(VOS_TRACE_LEVEL_INFO,
1910 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301911 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301912
1913 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1914 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301915 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301916 {
1917 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1918 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301919 return -EINVAL;
1920
1921 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301922
1923 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1924 if (VOS_STATUS_SUCCESS !=
1925 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1926 pHddStaCtx->conn_info.staId[0], WIFI_STATS_IFACE))
1927 {
1928 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1929 "WLANTL_ClearInterfaceStats Failed", __func__);
1930 return -EINVAL;
1931 }
1932
Sunil Duttc69bccb2014-05-26 21:30:20 +05301933 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301934 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301935 {
1936 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1937 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301938 return -EINVAL;
1939 }
1940
1941 pAdapter->isLinkLayerStatsSet = 1;
1942
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301943 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301944 return 0;
1945}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301946static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1947 struct wireless_dev *wdev,
1948 const void *data,
1949 int data_len)
1950{
1951 int ret = 0;
1952
1953 vos_ssr_protect(__func__);
1954 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1955 vos_ssr_unprotect(__func__);
1956
1957 return ret;
1958}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301959
1960const struct
1961nla_policy
1962qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1963{
1964 /* Unsigned 32bit value provided by the caller issuing the GET stats
1965 * command. When reporting
1966 * the stats results, the driver uses the same value to indicate
1967 * which GET request the results
1968 * correspond to.
1969 */
1970 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1971
1972 /* Unsigned 32bit value . bit mask to identify what statistics are
1973 requested for retrieval */
1974 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1975};
1976
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301977static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1978 struct wireless_dev *wdev,
1979 const void *data,
1980 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301981{
1982 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1983 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301984 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301985 struct net_device *dev = wdev->netdev;
1986 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1987 int status;
1988
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301989 ENTER();
1990
Sunil Duttc69bccb2014-05-26 21:30:20 +05301991 status = wlan_hdd_validate_context(pHddCtx);
1992 if (0 != status)
1993 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301994 return -EINVAL ;
1995 }
1996
1997 if (NULL == pAdapter)
1998 {
1999 hddLog(VOS_TRACE_LEVEL_FATAL,
2000 "%s: HDD adapter is Null", __func__);
2001 return -ENODEV;
2002 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302003 /* check the LLStats Capability */
2004 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2005 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2006 {
2007 hddLog(VOS_TRACE_LEVEL_ERROR,
2008 FL("Link Layer Statistics not supported by Firmware"));
2009 return -EINVAL;
2010 }
2011
Sunil Duttc69bccb2014-05-26 21:30:20 +05302012
2013 if (!pAdapter->isLinkLayerStatsSet)
2014 {
2015 hddLog(VOS_TRACE_LEVEL_FATAL,
2016 "%s: isLinkLayerStatsSet : %d",
2017 __func__, pAdapter->isLinkLayerStatsSet);
2018 return -EINVAL;
2019 }
2020
2021 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2022 (struct nlattr *)data,
2023 data_len, qca_wlan_vendor_ll_get_policy))
2024 {
2025 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2026 return -EINVAL;
2027 }
2028
2029 if (!tb_vendor
2030 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2031 {
2032 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2033 return -EINVAL;
2034 }
2035
2036 if (!tb_vendor
2037 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2038 {
2039 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2040 return -EINVAL;
2041 }
2042
Sunil Duttc69bccb2014-05-26 21:30:20 +05302043
Dino Mycledf0a5d92014-07-04 09:41:55 +05302044 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302045 nla_get_u32( tb_vendor[
2046 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302047 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302048 nla_get_u32( tb_vendor[
2049 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2050
Dino Mycled3d50022014-07-07 12:58:25 +05302051 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2052 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302053
2054 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302055 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302056 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302057 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302058 hddLog(VOS_TRACE_LEVEL_INFO,
2059 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302060 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302061
2062 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302063 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302064 {
2065 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2066 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302067 return -EINVAL;
2068 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302069
2070 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302071 return 0;
2072}
2073
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302074static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2075 struct wireless_dev *wdev,
2076 const void *data,
2077 int data_len)
2078{
2079 int ret = 0;
2080
2081 vos_ssr_protect(__func__);
2082 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
2083 vos_ssr_unprotect(__func__);
2084
2085 return ret;
2086}
2087
Sunil Duttc69bccb2014-05-26 21:30:20 +05302088const struct
2089nla_policy
2090qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2091{
2092 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2093 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2094 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2095 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2096};
2097
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302098static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2099 struct wireless_dev *wdev,
2100 const void *data,
2101 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302102{
2103 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2104 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302105 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302106 struct net_device *dev = wdev->netdev;
2107 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2108 u32 statsClearReqMask;
2109 u8 stopReq;
2110 int status;
2111
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302112 ENTER();
2113
Sunil Duttc69bccb2014-05-26 21:30:20 +05302114 status = wlan_hdd_validate_context(pHddCtx);
2115 if (0 != status)
2116 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302117 return -EINVAL;
2118 }
2119
2120 if (NULL == pAdapter)
2121 {
2122 hddLog(VOS_TRACE_LEVEL_FATAL,
2123 "%s: HDD adapter is Null", __func__);
2124 return -ENODEV;
2125 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302126 /* check the LLStats Capability */
2127 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2128 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2129 {
2130 hddLog(VOS_TRACE_LEVEL_ERROR,
2131 FL("Enable LLStats Capability"));
2132 return -EINVAL;
2133 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302134
2135 if (!pAdapter->isLinkLayerStatsSet)
2136 {
2137 hddLog(VOS_TRACE_LEVEL_FATAL,
2138 "%s: isLinkLayerStatsSet : %d",
2139 __func__, pAdapter->isLinkLayerStatsSet);
2140 return -EINVAL;
2141 }
2142
2143 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2144 (struct nlattr *)data,
2145 data_len, qca_wlan_vendor_ll_clr_policy))
2146 {
2147 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2148 return -EINVAL;
2149 }
2150
2151 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2152
2153 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2154 {
2155 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2156 return -EINVAL;
2157
2158 }
2159
Sunil Duttc69bccb2014-05-26 21:30:20 +05302160
Dino Mycledf0a5d92014-07-04 09:41:55 +05302161 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302162 nla_get_u32(
2163 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2164
Dino Mycledf0a5d92014-07-04 09:41:55 +05302165 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302166 nla_get_u8(
2167 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2168
2169 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302170 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302171
Dino Mycled3d50022014-07-07 12:58:25 +05302172 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2173 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302174
2175 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302176 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302177 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302178 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302179 hddLog(VOS_TRACE_LEVEL_INFO,
2180 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302181 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302182 hddLog(VOS_TRACE_LEVEL_INFO,
2183 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302184 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302185
2186 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302187 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302188 {
2189 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302190 hdd_station_ctx_t *pHddStaCtx;
2191
2192 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2193 if (VOS_STATUS_SUCCESS !=
2194 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2195 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2196 {
2197 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2198 "WLANTL_ClearInterfaceStats Failed", __func__);
2199 return -EINVAL;
2200 }
2201 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2202 (statsClearReqMask & WIFI_STATS_IFACE)) {
2203 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2204 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2205 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2206 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2207 }
2208
Sunil Duttc69bccb2014-05-26 21:30:20 +05302209 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2210 2 * sizeof(u32) +
2211 NLMSG_HDRLEN);
2212
2213 if (temp_skbuff != NULL)
2214 {
2215
2216 if (nla_put_u32(temp_skbuff,
2217 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2218 statsClearReqMask) ||
2219 nla_put_u32(temp_skbuff,
2220 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2221 stopReq))
2222 {
2223 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2224 kfree_skb(temp_skbuff);
2225 return -EINVAL;
2226 }
2227 /* If the ask is to stop the stats collection as part of clear
2228 * (stopReq = 1) , ensure that no further requests of get
2229 * go to the firmware by having isLinkLayerStatsSet set to 0.
2230 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302231 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302232 * case the firmware is just asked to clear the statistics.
2233 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302234 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302235 pAdapter->isLinkLayerStatsSet = 0;
2236 return cfg80211_vendor_cmd_reply(temp_skbuff);
2237 }
2238 return -ENOMEM;
2239 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302240
2241 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302242 return -EINVAL;
2243}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302244static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2245 struct wireless_dev *wdev,
2246 const void *data,
2247 int data_len)
2248{
2249 int ret = 0;
2250
2251 vos_ssr_protect(__func__);
2252 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2253 vos_ssr_unprotect(__func__);
2254
2255 return ret;
2256
2257
2258}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302259#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2260
Dino Mycle6fb96c12014-06-10 11:52:40 +05302261#ifdef WLAN_FEATURE_EXTSCAN
2262static const struct nla_policy
2263wlan_hdd_extscan_config_policy
2264 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2265{
2266 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2267 { .type = NLA_U32 },
2268 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2269 { .type = NLA_U32 },
2270 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2271 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2272 { .type = NLA_U32 },
2273 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2274 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2275
2276 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2277 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2278 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2279 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2280 { .type = NLA_U8 },
2281 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2282 { .type = NLA_U32 },
2283 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2284 { .type = NLA_U32 },
2285 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2286 { .type = NLA_U32 },
2287 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
2288 { .type = NLA_U8 },
2289 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2290 { .type = NLA_U8 },
2291 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2292 { .type = NLA_U8 },
2293
2294 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2295 { .type = NLA_U32 },
2296 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2297 { .type = NLA_UNSPEC },
2298 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2299 { .type = NLA_S32 },
2300 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2301 { .type = NLA_S32 },
2302 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2303 { .type = NLA_U32 },
2304 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2305 { .type = NLA_U32 },
2306 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2307 { .type = NLA_U32 },
2308 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2309 = { .type = NLA_U32 },
2310 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2311 { .type = NLA_U32 },
2312 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2313 NLA_U32 },
2314};
2315
2316static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
2317{
2318 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2319 struct sk_buff *skb = NULL;
2320 tpSirEXTScanCapabilitiesEvent pData =
2321 (tpSirEXTScanCapabilitiesEvent) pMsg;
2322
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302323 ENTER();
2324
2325 if (wlan_hdd_validate_context(pHddCtx))
2326 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302327 return;
2328 }
2329
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302330 if (!pMsg)
2331 {
2332 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2333 return;
2334 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302335 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302336#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2337 NULL,
2338#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302339 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2340 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
2341 GFP_KERNEL);
2342
2343 if (!skb) {
2344 hddLog(VOS_TRACE_LEVEL_ERROR,
2345 FL("cfg80211_vendor_event_alloc failed"));
2346 return;
2347 }
2348
2349 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2350 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
2351 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
2352 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
2353 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
2354 pData->maxRssiSampleSize);
2355 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
2356 pData->maxScanReportingThreshold);
2357 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
2358 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
2359 pData->maxSignificantWifiChangeAPs);
2360 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
2361 pData->maxBsidHistoryEntries);
2362
2363 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2364 pData->requestId) ||
2365 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
2366 nla_put_u32(skb,
2367 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
2368 pData->scanCacheSize) ||
2369 nla_put_u32(skb,
2370 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
2371 pData->scanBuckets) ||
2372 nla_put_u32(skb,
2373 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
2374 pData->maxApPerScan) ||
2375 nla_put_u32(skb,
2376 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
2377 pData->maxRssiSampleSize) ||
2378 nla_put_u32(skb,
2379 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
2380 pData->maxScanReportingThreshold) ||
2381 nla_put_u32(skb,
2382 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
2383 pData->maxHotlistAPs) ||
2384 nla_put_u32(skb,
2385 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
2386 pData->maxSignificantWifiChangeAPs) ||
2387 nla_put_u32(skb,
2388 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2389 pData->maxBsidHistoryEntries)) {
2390 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2391 goto nla_put_failure;
2392 }
2393
2394 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302395 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302396 return;
2397
2398nla_put_failure:
2399 kfree_skb(skb);
2400 return;
2401}
2402
2403
2404static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2405{
2406 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2407 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2408 struct sk_buff *skb = NULL;
2409 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2410
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302411 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302412
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302413 if (wlan_hdd_validate_context(pHddCtx)){
2414 return;
2415 }
2416 if (!pMsg)
2417 {
2418 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302419 return;
2420 }
2421
2422 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302423#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2424 NULL,
2425#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302426 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2427 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2428 GFP_KERNEL);
2429
2430 if (!skb) {
2431 hddLog(VOS_TRACE_LEVEL_ERROR,
2432 FL("cfg80211_vendor_event_alloc failed"));
2433 return;
2434 }
2435 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2436 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2437 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2438
2439 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2440 pData->requestId) ||
2441 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2442 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2443 goto nla_put_failure;
2444 }
2445
2446 /*
2447 * Store the Request ID for comparing with the requestID obtained
2448 * in other requests.HDD shall return a failure is the extscan_stop
2449 * request is issued with a different requestId as that of the
2450 * extscan_start request. Also, This requestId shall be used while
2451 * indicating the full scan results to the upper layers.
2452 * The requestId is stored with the assumption that the firmware
2453 * shall return the ext scan start request's requestId in ext scan
2454 * start response.
2455 */
2456 if (pData->status == 0)
2457 pMac->sme.extScanStartReqId = pData->requestId;
2458
2459
2460 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302461 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302462 return;
2463
2464nla_put_failure:
2465 kfree_skb(skb);
2466 return;
2467}
2468
2469
2470static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2471{
2472 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2473 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2474 struct sk_buff *skb = NULL;
2475
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302476 ENTER();
2477
2478 if (wlan_hdd_validate_context(pHddCtx)){
2479 return;
2480 }
2481 if (!pMsg)
2482 {
2483 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302484 return;
2485 }
2486
2487 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302488#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2489 NULL,
2490#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302491 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2492 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2493 GFP_KERNEL);
2494
2495 if (!skb) {
2496 hddLog(VOS_TRACE_LEVEL_ERROR,
2497 FL("cfg80211_vendor_event_alloc failed"));
2498 return;
2499 }
2500 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2501 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2502
2503 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2504 pData->requestId) ||
2505 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2506 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2507 goto nla_put_failure;
2508 }
2509
2510 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302511 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302512 return;
2513
2514nla_put_failure:
2515 kfree_skb(skb);
2516 return;
2517}
2518
2519
2520static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2521 void *pMsg)
2522{
2523 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2524 struct sk_buff *skb = NULL;
2525 tpSirEXTScanSetBssidHotListRspParams pData =
2526 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2527
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302528 ENTER();
2529
2530 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302531 return;
2532 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302533 if (!pMsg)
2534 {
2535 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2536 return;
2537 }
2538
Dino Mycle6fb96c12014-06-10 11:52:40 +05302539 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302540#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2541 NULL,
2542#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302543 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2544 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2545 GFP_KERNEL);
2546
2547 if (!skb) {
2548 hddLog(VOS_TRACE_LEVEL_ERROR,
2549 FL("cfg80211_vendor_event_alloc failed"));
2550 return;
2551 }
2552 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2553 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2554 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2555
2556 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2557 pData->requestId) ||
2558 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2559 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2560 goto nla_put_failure;
2561 }
2562
2563 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302564 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302565 return;
2566
2567nla_put_failure:
2568 kfree_skb(skb);
2569 return;
2570}
2571
2572static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2573 void *pMsg)
2574{
2575 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2576 struct sk_buff *skb = NULL;
2577 tpSirEXTScanResetBssidHotlistRspParams pData =
2578 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2579
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302580 ENTER();
2581
2582 if (wlan_hdd_validate_context(pHddCtx)) {
2583 return;
2584 }
2585 if (!pMsg)
2586 {
2587 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302588 return;
2589 }
2590
2591 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302592#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2593 NULL,
2594#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302595 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2596 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2597 GFP_KERNEL);
2598
2599 if (!skb) {
2600 hddLog(VOS_TRACE_LEVEL_ERROR,
2601 FL("cfg80211_vendor_event_alloc failed"));
2602 return;
2603 }
2604 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2605 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2606
2607 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2608 pData->requestId) ||
2609 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2610 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2611 goto nla_put_failure;
2612 }
2613
2614 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302615 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302616 return;
2617
2618nla_put_failure:
2619 kfree_skb(skb);
2620 return;
2621}
2622
2623
2624static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2625 void *pMsg)
2626{
2627 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2628 struct sk_buff *skb = NULL;
2629 tpSirEXTScanSetSignificantChangeRspParams pData =
2630 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2631
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302632 ENTER();
2633
2634 if (wlan_hdd_validate_context(pHddCtx)) {
2635 return;
2636 }
2637 if (!pMsg)
2638 {
2639 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302640 return;
2641 }
2642
2643 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302644#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2645 NULL,
2646#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302647 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2648 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2649 GFP_KERNEL);
2650
2651 if (!skb) {
2652 hddLog(VOS_TRACE_LEVEL_ERROR,
2653 FL("cfg80211_vendor_event_alloc failed"));
2654 return;
2655 }
2656 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2657 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2658 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2659
2660 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2661 pData->requestId) ||
2662 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2663 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2664 goto nla_put_failure;
2665 }
2666
2667 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302668 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302669 return;
2670
2671nla_put_failure:
2672 kfree_skb(skb);
2673 return;
2674}
2675
2676
2677static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2678 void *pMsg)
2679{
2680 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2681 struct sk_buff *skb = NULL;
2682 tpSirEXTScanResetSignificantChangeRspParams pData =
2683 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2684
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302685 ENTER();
2686
2687 if (wlan_hdd_validate_context(pHddCtx)) {
2688 return;
2689 }
2690 if (!pMsg)
2691 {
2692 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302693 return;
2694 }
2695
2696 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302697#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2698 NULL,
2699#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302700 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2701 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2702 GFP_KERNEL);
2703
2704 if (!skb) {
2705 hddLog(VOS_TRACE_LEVEL_ERROR,
2706 FL("cfg80211_vendor_event_alloc failed"));
2707 return;
2708 }
2709 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2710 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2711 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2712
2713 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2714 pData->requestId) ||
2715 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2716 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2717 goto nla_put_failure;
2718 }
2719
2720 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302721 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302722 return;
2723
2724nla_put_failure:
2725 kfree_skb(skb);
2726 return;
2727}
2728
2729static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2730 void *pMsg)
2731{
2732 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2733 struct sk_buff *skb = NULL;
2734 tANI_U32 i = 0, j, resultsPerEvent;
2735 tANI_S32 totalResults;
2736 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2737 tpSirWifiScanResult pSirWifiScanResult;
2738
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302739 ENTER();
2740
2741 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302742 return;
2743 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302744 if (!pMsg)
2745 {
2746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2747 return;
2748 }
2749
Dino Mycle6fb96c12014-06-10 11:52:40 +05302750 totalResults = pData->numOfAps;
2751 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2752 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2753 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2754
2755 do{
2756 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2757 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2758 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2759
2760 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302761#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2762 NULL,
2763#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302764 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2765 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2766 GFP_KERNEL);
2767
2768 if (!skb) {
2769 hddLog(VOS_TRACE_LEVEL_ERROR,
2770 FL("cfg80211_vendor_event_alloc failed"));
2771 return;
2772 }
2773
2774 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2775
2776 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2777 pData->requestId) ||
2778 nla_put_u32(skb,
2779 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2780 resultsPerEvent)) {
2781 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2782 goto fail;
2783 }
2784 if (nla_put_u8(skb,
2785 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2786 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2787 {
2788 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2789 goto fail;
2790 }
2791
2792 if (resultsPerEvent) {
2793 struct nlattr *aps;
2794
2795 aps = nla_nest_start(skb,
2796 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2797 if (!aps)
2798 {
2799 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2800 goto fail;
2801 }
2802
2803 for (j = 0; j < resultsPerEvent; j++, i++) {
2804 struct nlattr *ap;
2805 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2806 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2807
2808 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2809 "Ssid (%s)"
2810 "Bssid: %pM "
2811 "Channel (%u)"
2812 "Rssi (%d)"
2813 "RTT (%u)"
2814 "RTT_SD (%u)",
2815 i,
2816 pSirWifiScanResult->ts,
2817 pSirWifiScanResult->ssid,
2818 pSirWifiScanResult->bssid,
2819 pSirWifiScanResult->channel,
2820 pSirWifiScanResult->rssi,
2821 pSirWifiScanResult->rtt,
2822 pSirWifiScanResult->rtt_sd);
2823
2824 ap = nla_nest_start(skb, j + 1);
2825 if (!ap)
2826 {
2827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2828 goto fail;
2829 }
2830
2831 if (nla_put_u64(skb,
2832 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2833 pSirWifiScanResult->ts) )
2834 {
2835 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2836 goto fail;
2837 }
2838 if (nla_put(skb,
2839 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2840 sizeof(pSirWifiScanResult->ssid),
2841 pSirWifiScanResult->ssid) )
2842 {
2843 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2844 goto fail;
2845 }
2846 if (nla_put(skb,
2847 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2848 sizeof(pSirWifiScanResult->bssid),
2849 pSirWifiScanResult->bssid) )
2850 {
2851 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2852 goto fail;
2853 }
2854 if (nla_put_u32(skb,
2855 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2856 pSirWifiScanResult->channel) )
2857 {
2858 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2859 goto fail;
2860 }
Dasari Srinivas90747d72014-10-08 12:16:15 +05302861 if (nla_put_s32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302862 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2863 pSirWifiScanResult->rssi) )
2864 {
2865 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2866 goto fail;
2867 }
2868 if (nla_put_u32(skb,
2869 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2870 pSirWifiScanResult->rtt) )
2871 {
2872 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2873 goto fail;
2874 }
2875 if (nla_put_u32(skb,
2876 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2877 pSirWifiScanResult->rtt_sd))
2878 {
2879 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2880 goto fail;
2881 }
2882
2883 nla_nest_end(skb, ap);
2884 }
2885 nla_nest_end(skb, aps);
2886
2887 }
2888 cfg80211_vendor_event(skb, GFP_KERNEL);
2889 } while (totalResults > 0);
2890
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302891 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302892 return;
2893fail:
2894 kfree_skb(skb);
2895 return;
2896}
2897
2898static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2899 void *pMsg)
2900{
2901 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2902 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2903 struct sk_buff *skb = NULL;
2904 tANI_U32 i;
2905
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302906 ENTER();
2907
2908 if (wlan_hdd_validate_context(pHddCtx)) {
2909 return;
2910 }
2911 if (!pMsg)
2912 {
2913 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302914 return;
2915 }
2916
2917 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302918#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2919 NULL,
2920#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302921 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2922 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2923 GFP_KERNEL);
2924
2925 if (!skb) {
2926 hddLog(VOS_TRACE_LEVEL_ERROR,
2927 FL("cfg80211_vendor_event_alloc failed"));
2928 return;
2929 }
2930 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2931 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2932 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2933 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2934
2935 for (i = 0; i < pData->numOfAps; i++) {
2936 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2937 "Ssid (%s) "
2938 "Bssid (" MAC_ADDRESS_STR ") "
2939 "Channel (%u) "
2940 "Rssi (%d) "
2941 "RTT (%u) "
2942 "RTT_SD (%u) ",
2943 i,
2944 pData->ap[i].ts,
2945 pData->ap[i].ssid,
2946 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2947 pData->ap[i].channel,
2948 pData->ap[i].rssi,
2949 pData->ap[i].rtt,
2950 pData->ap[i].rtt_sd);
2951 }
2952
2953 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2954 pData->requestId) ||
2955 nla_put_u32(skb,
2956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2957 pData->numOfAps)) {
2958 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2959 goto fail;
2960 }
2961 if (pData->numOfAps) {
2962 struct nlattr *aps;
2963
2964 aps = nla_nest_start(skb,
2965 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2966 if (!aps)
2967 goto fail;
2968
2969 for (i = 0; i < pData->numOfAps; i++) {
2970 struct nlattr *ap;
2971
2972 ap = nla_nest_start(skb, i + 1);
2973 if (!ap)
2974 goto fail;
2975
2976 if (nla_put_u64(skb,
2977 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2978 pData->ap[i].ts) ||
2979 nla_put(skb,
2980 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2981 sizeof(pData->ap[i].ssid),
2982 pData->ap[i].ssid) ||
2983 nla_put(skb,
2984 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2985 sizeof(pData->ap[i].bssid),
2986 pData->ap[i].bssid) ||
2987 nla_put_u32(skb,
2988 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2989 pData->ap[i].channel) ||
2990 nla_put_s32(skb,
2991 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2992 pData->ap[i].rssi) ||
2993 nla_put_u32(skb,
2994 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2995 pData->ap[i].rtt) ||
2996 nla_put_u32(skb,
2997 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2998 pData->ap[i].rtt_sd))
2999 goto fail;
3000
3001 nla_nest_end(skb, ap);
3002 }
3003 nla_nest_end(skb, aps);
3004
3005 if (nla_put_u8(skb,
3006 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3007 pData->moreData))
3008 goto fail;
3009 }
3010
3011 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303012 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303013 return;
3014
3015fail:
3016 kfree_skb(skb);
3017 return;
3018
3019}
3020static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
3021 void *pMsg)
3022{
3023 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3024 struct sk_buff *skb = NULL;
3025 tANI_U32 i, j;
3026 tpSirWifiSignificantChangeEvent pData =
3027 (tpSirWifiSignificantChangeEvent) pMsg;
3028
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303029 ENTER();
3030
3031 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303032 return;
3033 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303034 if (!pMsg)
3035 {
3036 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3037 return;
3038 }
3039
Dino Mycle6fb96c12014-06-10 11:52:40 +05303040 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303041#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3042 NULL,
3043#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303044 EXTSCAN_EVENT_BUF_SIZE,
3045 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
3046 GFP_KERNEL);
3047
3048 if (!skb) {
3049 hddLog(VOS_TRACE_LEVEL_ERROR,
3050 FL("cfg80211_vendor_event_alloc failed"));
3051 return;
3052 }
3053 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3054 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3055 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
3056 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
3057 pData->numSigRssiBss);
3058 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
3059
3060 for (i = 0; i < pData->numSigRssiBss; i++) {
3061 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
3062 " num RSSI %u ",
3063 i, pData->sigRssiResult[i].bssid,
3064 pData->sigRssiResult[i].channel,
3065 pData->sigRssiResult[i].numRssi);
3066
3067 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
3068
3069 hddLog(VOS_TRACE_LEVEL_INFO,
3070 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05303071 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303072
3073 }
3074 }
3075
3076
3077 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3078 pData->requestId) ||
3079 nla_put_u32(skb,
3080 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3081 pData->numSigRssiBss)) {
3082 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3083 goto fail;
3084 }
3085
3086 if (pData->numSigRssiBss) {
3087 struct nlattr *aps;
3088 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3089 if (!aps)
3090 goto fail;
3091 for (i = 0; i < pData->numSigRssiBss; i++) {
3092 struct nlattr *ap;
3093
3094 ap = nla_nest_start(skb, i);
3095 if (!ap)
3096 goto fail;
3097 if (nla_put(skb,
3098 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
3099 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
3100 nla_put_u32(skb,
3101 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
3102 pData->sigRssiResult[i].channel) ||
3103 nla_put_u32(skb,
3104 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
3105 pData->sigRssiResult[i].numRssi) ||
3106 nla_put(skb,
3107 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
3108 sizeof(s32) * pData->sigRssiResult[i].numRssi,
3109 pData->sigRssiResult[i].rssi))
3110 goto fail;
3111 nla_nest_end(skb, ap);
3112 }
3113 nla_nest_end(skb, aps);
3114 if (nla_put_u8(skb,
3115 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3116 pData->moreData))
3117 goto fail;
3118 }
3119 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303120 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303121 return;
3122fail:
3123 kfree_skb(skb);
3124 return;
3125}
3126
3127static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3128 void *pMsg)
3129{
3130 struct sk_buff *skb;
3131 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3132 tpSirWifiFullScanResultEvent pData =
3133 (tpSirWifiFullScanResultEvent) (pMsg);
3134
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303135 ENTER();
3136
3137 if (wlan_hdd_validate_context(pHddCtx)) {
3138 return;
3139 }
3140 if (!pMsg)
3141 {
3142 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303143 return;
3144 }
3145
3146 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303147#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3148 NULL,
3149#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303150 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3151 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3152 GFP_KERNEL);
3153
3154 if (!skb) {
3155 hddLog(VOS_TRACE_LEVEL_ERROR,
3156 FL("cfg80211_vendor_event_alloc failed"));
3157 return;
3158 }
3159
3160 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3161 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3162 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3163 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3164 "Ssid (%s)"
3165 "Bssid (" MAC_ADDRESS_STR ")"
3166 "Channel (%u)"
3167 "Rssi (%d)"
3168 "RTT (%u)"
3169 "RTT_SD (%u)"),
3170 pData->ap.ts,
3171 pData->ap.ssid,
3172 MAC_ADDR_ARRAY(pData->ap.bssid),
3173 pData->ap.channel,
3174 pData->ap.rssi,
3175 pData->ap.rtt,
3176 pData->ap.rtt_sd);
3177 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3178 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3179 pData->requestId) ||
3180 nla_put_u64(skb,
3181 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3182 pData->ap.ts) ||
3183 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3184 sizeof(pData->ap.ssid),
3185 pData->ap.ssid) ||
3186 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3187 WNI_CFG_BSSID_LEN,
3188 pData->ap.bssid) ||
3189 nla_put_u32(skb,
3190 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3191 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303192 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303193 pData->ap.rssi) ||
3194 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3195 pData->ap.rtt) ||
3196 nla_put_u32(skb,
3197 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3198 pData->ap.rtt_sd) ||
3199 nla_put_u16(skb,
3200 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3201 pData->ap.beaconPeriod) ||
3202 nla_put_u16(skb,
3203 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3204 pData->ap.capability) ||
3205 nla_put_u32(skb,
3206 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3207 pData->ieLength))
3208 {
3209 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3210 goto nla_put_failure;
3211 }
3212 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3213 pData->ieLength,
3214 pData->ie))
3215 {
3216 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3217 goto nla_put_failure;
3218 }
3219
3220 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303221 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303222 return;
3223
3224nla_put_failure:
3225 kfree_skb(skb);
3226 return;
3227}
3228
3229static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3230 void *pMsg)
3231{
3232 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3233 struct sk_buff *skb = NULL;
3234 tpSirEXTScanResultsAvailableIndParams pData =
3235 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3236
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303237 ENTER();
3238
3239 if (wlan_hdd_validate_context(pHddCtx)){
3240 return;
3241 }
3242 if (!pMsg)
3243 {
3244 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303245 return;
3246 }
3247
3248 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303249#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3250 NULL,
3251#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303252 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3253 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3254 GFP_KERNEL);
3255
3256 if (!skb) {
3257 hddLog(VOS_TRACE_LEVEL_ERROR,
3258 FL("cfg80211_vendor_event_alloc failed"));
3259 return;
3260 }
3261
3262 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3263 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3264 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3265 pData->numResultsAvailable);
3266 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3267 pData->requestId) ||
3268 nla_put_u32(skb,
3269 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3270 pData->numResultsAvailable)) {
3271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3272 goto nla_put_failure;
3273 }
3274
3275 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303276 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303277 return;
3278
3279nla_put_failure:
3280 kfree_skb(skb);
3281 return;
3282}
3283
3284static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3285{
3286 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3287 struct sk_buff *skb = NULL;
3288 tpSirEXTScanProgressIndParams pData =
3289 (tpSirEXTScanProgressIndParams) pMsg;
3290
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303291 ENTER();
3292
3293 if (wlan_hdd_validate_context(pHddCtx)){
3294 return;
3295 }
3296 if (!pMsg)
3297 {
3298 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303299 return;
3300 }
3301
3302 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303303#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3304 NULL,
3305#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303306 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3307 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3308 GFP_KERNEL);
3309
3310 if (!skb) {
3311 hddLog(VOS_TRACE_LEVEL_ERROR,
3312 FL("cfg80211_vendor_event_alloc failed"));
3313 return;
3314 }
3315 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3316 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3317 pData->extScanEventType);
3318 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3319 pData->status);
3320
3321 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3322 pData->extScanEventType) ||
3323 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303324 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3325 pData->requestId) ||
3326 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303327 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3328 pData->status)) {
3329 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3330 goto nla_put_failure;
3331 }
3332
3333 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303334 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303335 return;
3336
3337nla_put_failure:
3338 kfree_skb(skb);
3339 return;
3340}
3341
3342void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3343 void *pMsg)
3344{
3345 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3346
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303347 ENTER();
3348
Dino Mycle6fb96c12014-06-10 11:52:40 +05303349 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303350 return;
3351 }
3352
3353 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3354
3355
3356 switch(evType) {
3357 case SIR_HAL_EXTSCAN_START_RSP:
3358 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3359 break;
3360
3361 case SIR_HAL_EXTSCAN_STOP_RSP:
3362 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3363 break;
3364 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3365 /* There is no need to send this response to upper layer
3366 Just log the message */
3367 hddLog(VOS_TRACE_LEVEL_INFO,
3368 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3369 break;
3370 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3371 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3372 break;
3373
3374 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3375 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3376 break;
3377
3378 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
3379 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
3380 break;
3381
3382 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
3383 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
3384 break;
3385 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
3386 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
3387 break;
3388 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3389 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3390 break;
3391 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3392 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3393 break;
3394 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3395 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3396 break;
3397 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3398 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3399 break;
3400 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
3401 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
3402 break;
3403 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3404 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3405 break;
3406 default:
3407 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3408 break;
3409 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303410 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303411}
3412
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303413static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3414 struct wireless_dev *wdev,
3415 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303416{
Dino Myclee8843b32014-07-04 14:21:45 +05303417 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303418 struct net_device *dev = wdev->netdev;
3419 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3420 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3421 struct nlattr
3422 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3423 eHalStatus status;
3424
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303425 ENTER();
3426
Dino Mycle6fb96c12014-06-10 11:52:40 +05303427 status = wlan_hdd_validate_context(pHddCtx);
3428 if (0 != status)
3429 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303430 return -EINVAL;
3431 }
Dino Myclee8843b32014-07-04 14:21:45 +05303432 /* check the EXTScan Capability */
3433 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3434 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3435 {
3436 hddLog(VOS_TRACE_LEVEL_ERROR,
3437 FL("EXTScan not enabled/supported by Firmware"));
3438 return -EINVAL;
3439 }
3440
Dino Mycle6fb96c12014-06-10 11:52:40 +05303441 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3442 data, dataLen,
3443 wlan_hdd_extscan_config_policy)) {
3444 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3445 return -EINVAL;
3446 }
3447
3448 /* Parse and fetch request Id */
3449 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3450 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3451 return -EINVAL;
3452 }
3453
Dino Mycle6fb96c12014-06-10 11:52:40 +05303454
Dino Myclee8843b32014-07-04 14:21:45 +05303455 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303456 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303457 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303458
Dino Myclee8843b32014-07-04 14:21:45 +05303459 reqMsg.sessionId = pAdapter->sessionId;
3460 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303461
Dino Myclee8843b32014-07-04 14:21:45 +05303462 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303463 if (!HAL_STATUS_SUCCESS(status)) {
3464 hddLog(VOS_TRACE_LEVEL_ERROR,
3465 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303466 return -EINVAL;
3467 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303468 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303469 return 0;
3470}
3471
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303472static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3473 struct wireless_dev *wdev,
3474 const void *data, int dataLen)
3475{
3476 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303477
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303478 vos_ssr_protect(__func__);
3479 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3480 vos_ssr_unprotect(__func__);
3481
3482 return ret;
3483}
3484
3485static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3486 struct wireless_dev *wdev,
3487 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303488{
Dino Myclee8843b32014-07-04 14:21:45 +05303489 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303490 struct net_device *dev = wdev->netdev;
3491 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3492 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3493 struct nlattr
3494 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3495 eHalStatus status;
3496
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303497 ENTER();
3498
Dino Mycle6fb96c12014-06-10 11:52:40 +05303499 status = wlan_hdd_validate_context(pHddCtx);
3500 if (0 != status)
3501 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303502 return -EINVAL;
3503 }
Dino Myclee8843b32014-07-04 14:21:45 +05303504 /* check the EXTScan Capability */
3505 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3506 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3507 {
3508 hddLog(VOS_TRACE_LEVEL_ERROR,
3509 FL("EXTScan not enabled/supported by Firmware"));
3510 return -EINVAL;
3511 }
3512
Dino Mycle6fb96c12014-06-10 11:52:40 +05303513 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3514 data, dataLen,
3515 wlan_hdd_extscan_config_policy)) {
3516 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3517 return -EINVAL;
3518 }
3519 /* Parse and fetch request Id */
3520 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3521 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3522 return -EINVAL;
3523 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303524
Dino Myclee8843b32014-07-04 14:21:45 +05303525 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303526 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3527
Dino Myclee8843b32014-07-04 14:21:45 +05303528 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303529
Dino Myclee8843b32014-07-04 14:21:45 +05303530 reqMsg.sessionId = pAdapter->sessionId;
3531 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303532
3533 /* Parse and fetch flush parameter */
3534 if (!tb
3535 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3536 {
3537 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3538 goto failed;
3539 }
Dino Myclee8843b32014-07-04 14:21:45 +05303540 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303541 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3542
Dino Myclee8843b32014-07-04 14:21:45 +05303543 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303544
Dino Myclee8843b32014-07-04 14:21:45 +05303545 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303546 if (!HAL_STATUS_SUCCESS(status)) {
3547 hddLog(VOS_TRACE_LEVEL_ERROR,
3548 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303549 return -EINVAL;
3550 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303551 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303552 return 0;
3553
3554failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303555 return -EINVAL;
3556}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303557static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3558 struct wireless_dev *wdev,
3559 const void *data, int dataLen)
3560{
3561 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303562
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303563 vos_ssr_protect(__func__);
3564 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3565 vos_ssr_unprotect(__func__);
3566
3567 return ret;
3568}
3569
3570static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303571 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303572 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303573{
3574 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3575 struct net_device *dev = wdev->netdev;
3576 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3577 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3578 struct nlattr
3579 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3580 struct nlattr
3581 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3582 struct nlattr *apTh;
3583 eHalStatus status;
3584 tANI_U8 i = 0;
3585 int rem;
3586
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303587 ENTER();
3588
Dino Mycle6fb96c12014-06-10 11:52:40 +05303589 status = wlan_hdd_validate_context(pHddCtx);
3590 if (0 != status)
3591 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303592 return -EINVAL;
3593 }
Dino Myclee8843b32014-07-04 14:21:45 +05303594 /* check the EXTScan Capability */
3595 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3596 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3597 {
3598 hddLog(VOS_TRACE_LEVEL_ERROR,
3599 FL("EXTScan not enabled/supported by Firmware"));
3600 return -EINVAL;
3601 }
3602
Dino Mycle6fb96c12014-06-10 11:52:40 +05303603 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3604 data, dataLen,
3605 wlan_hdd_extscan_config_policy)) {
3606 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3607 return -EINVAL;
3608 }
3609
3610 /* Parse and fetch request Id */
3611 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3612 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3613 return -EINVAL;
3614 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303615 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3616 vos_mem_malloc(sizeof(*pReqMsg));
3617 if (!pReqMsg) {
3618 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3619 return -ENOMEM;
3620 }
3621
Dino Myclee8843b32014-07-04 14:21:45 +05303622
Dino Mycle6fb96c12014-06-10 11:52:40 +05303623 pReqMsg->requestId = nla_get_u32(
3624 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3625 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3626
3627 /* Parse and fetch number of APs */
3628 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3629 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3630 goto fail;
3631 }
3632
3633 pReqMsg->sessionId = pAdapter->sessionId;
3634 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3635
3636 pReqMsg->numAp = nla_get_u32(
3637 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3638 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3639
3640 nla_for_each_nested(apTh,
3641 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3642 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3643 nla_data(apTh), nla_len(apTh),
3644 NULL)) {
3645 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3646 goto fail;
3647 }
3648
3649 /* Parse and fetch MAC address */
3650 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3651 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3652 goto fail;
3653 }
3654 memcpy(pReqMsg->ap[i].bssid, nla_data(
3655 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3656 sizeof(tSirMacAddr));
3657 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3658
3659 /* Parse and fetch low RSSI */
3660 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3661 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3662 goto fail;
3663 }
3664 pReqMsg->ap[i].low = nla_get_s32(
3665 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3666 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3667
3668 /* Parse and fetch high RSSI */
3669 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3670 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3671 goto fail;
3672 }
3673 pReqMsg->ap[i].high = nla_get_s32(
3674 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3675 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3676 pReqMsg->ap[i].high);
3677
3678 /* Parse and fetch channel */
3679 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3680 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3681 goto fail;
3682 }
3683 pReqMsg->ap[i].channel = nla_get_u32(
3684 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3685 hddLog(VOS_TRACE_LEVEL_INFO,
3686 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3687 i++;
3688 }
3689 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3690 if (!HAL_STATUS_SUCCESS(status)) {
3691 hddLog(VOS_TRACE_LEVEL_ERROR,
3692 FL("sme_SetBssHotlist failed(err=%d)"), status);
3693 vos_mem_free(pReqMsg);
3694 return -EINVAL;
3695 }
3696
Dino Myclee8843b32014-07-04 14:21:45 +05303697 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303698 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303699 return 0;
3700
3701fail:
3702 vos_mem_free(pReqMsg);
3703 return -EINVAL;
3704}
3705
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303706static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3707 struct wireless_dev *wdev,
3708 const void *data, int dataLen)
3709{
3710 int ret = 0;
3711
3712 vos_ssr_protect(__func__);
3713 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3714 dataLen);
3715 vos_ssr_unprotect(__func__);
3716
3717 return ret;
3718}
3719
3720static int __wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303721 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303722 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303723{
3724 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3725 struct net_device *dev = wdev->netdev;
3726 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3727 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3728 struct nlattr
3729 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3730 struct nlattr
3731 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3732 struct nlattr *apTh;
3733 eHalStatus status;
3734 int i = 0;
3735 int rem;
3736
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303737 ENTER();
3738
Dino Mycle6fb96c12014-06-10 11:52:40 +05303739 status = wlan_hdd_validate_context(pHddCtx);
3740 if (0 != status)
3741 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303742 return -EINVAL;
3743 }
Dino Myclee8843b32014-07-04 14:21:45 +05303744 /* check the EXTScan Capability */
3745 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3746 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3747 {
3748 hddLog(VOS_TRACE_LEVEL_ERROR,
3749 FL("EXTScan not enabled/supported by Firmware"));
3750 return -EINVAL;
3751 }
3752
Dino Mycle6fb96c12014-06-10 11:52:40 +05303753 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3754 data, dataLen,
3755 wlan_hdd_extscan_config_policy)) {
3756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3757 return -EINVAL;
3758 }
3759
3760 /* Parse and fetch request Id */
3761 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3762 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3763 return -EINVAL;
3764 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303765 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303766 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303767 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3769 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303770 }
3771
Dino Myclee8843b32014-07-04 14:21:45 +05303772
3773
Dino Mycle6fb96c12014-06-10 11:52:40 +05303774 pReqMsg->requestId = nla_get_u32(
3775 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3776 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3777
3778 /* Parse and fetch RSSI sample size */
3779 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3780 {
3781 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3782 goto fail;
3783 }
3784 pReqMsg->rssiSampleSize = nla_get_u32(
3785 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3786 hddLog(VOS_TRACE_LEVEL_INFO,
3787 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3788
3789 /* Parse and fetch lost AP sample size */
3790 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3791 {
3792 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3793 goto fail;
3794 }
3795 pReqMsg->lostApSampleSize = nla_get_u32(
3796 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3797 hddLog(VOS_TRACE_LEVEL_INFO,
3798 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3799 /* Parse and fetch minimum Breaching */
3800 if (!tb
3801 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3802 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3803 goto fail;
3804 }
3805 pReqMsg->minBreaching = nla_get_u32(
3806 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3807 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3808
3809 /* Parse and fetch number of APs */
3810 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3812 goto fail;
3813 }
3814 pReqMsg->numAp = nla_get_u32(
3815 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3816 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3817
3818 pReqMsg->sessionId = pAdapter->sessionId;
3819 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3820
3821 nla_for_each_nested(apTh,
3822 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3823 if(nla_parse(tb2,
3824 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3825 nla_data(apTh), nla_len(apTh),
3826 NULL)) {
3827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3828 goto fail;
3829 }
3830
3831 /* Parse and fetch MAC address */
3832 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3833 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3834 goto fail;
3835 }
3836 memcpy(pReqMsg->ap[i].bssid, nla_data(
3837 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3838 sizeof(tSirMacAddr));
3839
3840 /* Parse and fetch low RSSI */
3841 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3842 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3843 goto fail;
3844 }
3845 pReqMsg->ap[i].low = nla_get_s32(
3846 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3847 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3848
3849 /* Parse and fetch high RSSI */
3850 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3851 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3852 goto fail;
3853 }
3854 pReqMsg->ap[i].high = nla_get_s32(
3855 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3856 hddLog(VOS_TRACE_LEVEL_INFO,
3857 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3858
3859 /* Parse and fetch channel */
3860 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3861 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3862 goto fail;
3863 }
3864 pReqMsg->ap[i].channel = nla_get_u32(
3865 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3866 hddLog(VOS_TRACE_LEVEL_INFO,
3867 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3868 i++;
3869 }
3870
3871 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3872 if (!HAL_STATUS_SUCCESS(status)) {
3873 hddLog(VOS_TRACE_LEVEL_ERROR,
3874 FL("sme_SetSignificantChange failed(err=%d)"), status);
3875 vos_mem_free(pReqMsg);
3876 return -EINVAL;
3877 }
Dino Myclee8843b32014-07-04 14:21:45 +05303878 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303879 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303880 return 0;
3881
3882fail:
3883 vos_mem_free(pReqMsg);
3884 return -EINVAL;
3885}
3886
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303887static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3888 struct wireless_dev *wdev,
3889 const void *data, int dataLen)
3890{
3891 int ret = 0;
3892
3893 vos_ssr_protect(__func__);
3894 ret = __wlan_hdd_cfg80211_extscan_set_significant_change(wiphy, wdev, data,
3895 dataLen);
3896 vos_ssr_unprotect(__func__);
3897
3898 return ret;
3899}
3900
3901static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303902 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303903 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303904{
3905 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3906 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3907 tANI_U8 numChannels = 0;
3908 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3909 tANI_U32 requestId;
3910 tWifiBand wifiBand;
3911 eHalStatus status;
3912 struct sk_buff *replySkb;
3913 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303914 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303915
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303916 ENTER();
3917
Dino Mycle6fb96c12014-06-10 11:52:40 +05303918 status = wlan_hdd_validate_context(pHddCtx);
3919 if (0 != status)
3920 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303921 return -EINVAL;
3922 }
Dino Myclee8843b32014-07-04 14:21:45 +05303923
Dino Mycle6fb96c12014-06-10 11:52:40 +05303924 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3925 data, dataLen,
3926 wlan_hdd_extscan_config_policy)) {
3927 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3928 return -EINVAL;
3929 }
3930
3931 /* Parse and fetch request Id */
3932 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3933 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3934 return -EINVAL;
3935 }
3936 requestId = nla_get_u32(
3937 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3938 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3939
3940 /* Parse and fetch wifi band */
3941 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3942 {
3943 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3944 return -EINVAL;
3945 }
3946 wifiBand = nla_get_u32(
3947 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3948 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3949
3950 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3951 wifiBand, ChannelList,
3952 &numChannels);
3953 if (eHAL_STATUS_SUCCESS != status) {
3954 hddLog(VOS_TRACE_LEVEL_ERROR,
3955 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3956 return -EINVAL;
3957 }
3958 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3959 for (i = 0; i < numChannels; i++)
3960 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3961
3962 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3963 sizeof(u32) * numChannels +
3964 NLMSG_HDRLEN);
3965
3966 if (!replySkb) {
3967 hddLog(VOS_TRACE_LEVEL_ERROR,
3968 FL("valid channels: buffer alloc fail"));
3969 return -EINVAL;
3970 }
3971 if (nla_put_u32(replySkb,
3972 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3973 numChannels) ||
3974 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3975 sizeof(u32) * numChannels, ChannelList)) {
3976
3977 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3978 kfree_skb(replySkb);
3979 return -EINVAL;
3980 }
3981
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303982 ret = cfg80211_vendor_cmd_reply(replySkb);
3983
3984 EXIT();
3985 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303986}
3987
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303988static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3989 struct wireless_dev *wdev,
3990 const void *data, int dataLen)
3991{
3992 int ret = 0;
3993
3994 vos_ssr_protect(__func__);
3995 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
3996 dataLen);
3997 vos_ssr_unprotect(__func__);
3998
3999 return ret;
4000}
4001
4002static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304003 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304004 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304005{
Dino Myclee8843b32014-07-04 14:21:45 +05304006 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304007 struct net_device *dev = wdev->netdev;
4008 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4009 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4010 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4011 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4012 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4013 struct nlattr *buckets;
4014 struct nlattr *channels;
4015 int rem1;
4016 int rem2;
4017 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304018 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304019
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304020 ENTER();
4021
Dino Mycle6fb96c12014-06-10 11:52:40 +05304022 status = wlan_hdd_validate_context(pHddCtx);
4023 if (0 != status)
4024 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304025 return -EINVAL;
4026 }
Dino Myclee8843b32014-07-04 14:21:45 +05304027 /* check the EXTScan Capability */
4028 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4029 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4030 {
4031 hddLog(VOS_TRACE_LEVEL_ERROR,
4032 FL("EXTScan not enabled/supported by Firmware"));
4033 return -EINVAL;
4034 }
4035
Dino Mycle6fb96c12014-06-10 11:52:40 +05304036 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4037 data, dataLen,
4038 wlan_hdd_extscan_config_policy)) {
4039 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4040 return -EINVAL;
4041 }
4042
4043 /* Parse and fetch request Id */
4044 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4045 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4046 return -EINVAL;
4047 }
4048
Dino Myclee8843b32014-07-04 14:21:45 +05304049 pReqMsg = (tpSirEXTScanStartReqParams)
4050 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304051 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304052 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4053 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304054 }
4055
4056 pReqMsg->requestId = nla_get_u32(
4057 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4058 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4059
4060 pReqMsg->sessionId = pAdapter->sessionId;
4061 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4062
4063 /* Parse and fetch base period */
4064 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
4065 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4066 goto fail;
4067 }
4068 pReqMsg->basePeriod = nla_get_u32(
4069 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
4070 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4071 pReqMsg->basePeriod);
4072
4073 /* Parse and fetch max AP per scan */
4074 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
4075 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4076 goto fail;
4077 }
4078 pReqMsg->maxAPperScan = nla_get_u32(
4079 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
4080 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4081 pReqMsg->maxAPperScan);
4082
4083 /* Parse and fetch report threshold */
4084 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
4085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4086 goto fail;
4087 }
4088 pReqMsg->reportThreshold = nla_get_u8(
4089 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
4090 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
4091 pReqMsg->reportThreshold);
4092
4093 /* Parse and fetch number of buckets */
4094 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
4095 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4096 goto fail;
4097 }
4098 pReqMsg->numBuckets = nla_get_u8(
4099 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
4100 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4101 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4102 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4103 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4104 }
4105 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4106 pReqMsg->numBuckets);
4107 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4108 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4109 goto fail;
4110 }
4111
4112 nla_for_each_nested(buckets,
4113 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4114 if(nla_parse(bucket,
4115 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4116 nla_data(buckets), nla_len(buckets), NULL)) { //policy
4117 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4118 goto fail;
4119 }
4120
4121 /* Parse and fetch bucket spec */
4122 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4123 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
4124 goto fail;
4125 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304126
4127 pReqMsg->buckets[index].bucket = nla_get_u8(
4128 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4129
4130 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
4131 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304132
4133 /* Parse and fetch wifi band */
4134 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4135 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4136 goto fail;
4137 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304138 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304139 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4140 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304141 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304142
4143 /* Parse and fetch period */
4144 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4145 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
4146 goto fail;
4147 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304148 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304149 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4150 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304151 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304152
4153 /* Parse and fetch report events */
4154 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4155 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
4156 goto fail;
4157 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304158 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304159 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4160 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304161 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304162
4163 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304164 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
4165 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304166 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
4167 goto fail;
4168 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304169 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304170 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4171 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304172 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304173
4174 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4175 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
4176 goto fail;
4177 }
4178
4179 j = 0;
4180 nla_for_each_nested(channels,
4181 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4182 if(nla_parse(channel,
4183 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4184 nla_data(channels), nla_len(channels),
4185 NULL)) { //wlan_hdd_extscan_config_policy here
4186 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4187 goto fail;
4188 }
4189
4190 /* Parse and fetch channel */
4191 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4192 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4193 goto fail;
4194 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304195 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304196 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4197 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304198 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304199
4200 /* Parse and fetch dwell time */
4201 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4202 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
4203 goto fail;
4204 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304205 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304206 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4207 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304208 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304209
4210 /* Parse and fetch channel spec passive */
4211 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4212 hddLog(VOS_TRACE_LEVEL_ERROR,
4213 FL("attr channel spec passive failed"));
4214 goto fail;
4215 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304216 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304217 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4218 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304219 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304220 j++;
4221 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304222 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304223 }
4224 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4225 if (!HAL_STATUS_SUCCESS(status)) {
4226 hddLog(VOS_TRACE_LEVEL_ERROR,
4227 FL("sme_EXTScanStart failed(err=%d)"), status);
4228 vos_mem_free(pReqMsg);
4229 return -EINVAL;
4230 }
4231
Dino Myclee8843b32014-07-04 14:21:45 +05304232 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304233 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304234 return 0;
4235
4236fail:
4237 vos_mem_free(pReqMsg);
4238 return -EINVAL;
4239}
4240
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304241static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4242 struct wireless_dev *wdev,
4243 const void *data, int dataLen)
4244{
4245 int ret = 0;
4246
4247 vos_ssr_protect(__func__);
4248 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4249 vos_ssr_unprotect(__func__);
4250
4251 return ret;
4252}
4253
4254static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304255 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304256 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304257{
Dino Myclee8843b32014-07-04 14:21:45 +05304258 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304259 struct net_device *dev = wdev->netdev;
4260 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4261 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4262 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4263 eHalStatus status;
4264
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304265 ENTER();
4266
Dino Mycle6fb96c12014-06-10 11:52:40 +05304267 status = wlan_hdd_validate_context(pHddCtx);
4268 if (0 != status)
4269 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304270 return -EINVAL;
4271 }
Dino Myclee8843b32014-07-04 14:21:45 +05304272 /* check the EXTScan Capability */
4273 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4274 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4275 {
4276 hddLog(VOS_TRACE_LEVEL_ERROR,
4277 FL("EXTScan not enabled/supported by Firmware"));
4278 return -EINVAL;
4279 }
4280
Dino Mycle6fb96c12014-06-10 11:52:40 +05304281 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4282 data, dataLen,
4283 wlan_hdd_extscan_config_policy)) {
4284 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4285 return -EINVAL;
4286 }
4287
4288 /* Parse and fetch request Id */
4289 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4290 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4291 return -EINVAL;
4292 }
4293
Dino Myclee8843b32014-07-04 14:21:45 +05304294 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304295 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304296 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304297
Dino Myclee8843b32014-07-04 14:21:45 +05304298 reqMsg.sessionId = pAdapter->sessionId;
4299 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304300
Dino Myclee8843b32014-07-04 14:21:45 +05304301 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304302 if (!HAL_STATUS_SUCCESS(status)) {
4303 hddLog(VOS_TRACE_LEVEL_ERROR,
4304 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304305 return -EINVAL;
4306 }
4307
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304308 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304309 return 0;
4310}
4311
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304312static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4313 struct wireless_dev *wdev,
4314 const void *data, int dataLen)
4315{
4316 int ret = 0;
4317
4318 vos_ssr_protect(__func__);
4319 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4320 vos_ssr_unprotect(__func__);
4321
4322 return ret;
4323}
4324
4325static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304326 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304327 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304328{
Dino Myclee8843b32014-07-04 14:21:45 +05304329 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304330 struct net_device *dev = wdev->netdev;
4331 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4332 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4333 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4334 eHalStatus status;
4335
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304336 ENTER();
4337
Dino Mycle6fb96c12014-06-10 11:52:40 +05304338 status = wlan_hdd_validate_context(pHddCtx);
4339 if (0 != status)
4340 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304341 return -EINVAL;
4342 }
Dino Myclee8843b32014-07-04 14:21:45 +05304343 /* check the EXTScan Capability */
4344 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4345 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4346 {
4347 hddLog(VOS_TRACE_LEVEL_ERROR,
4348 FL("EXTScan not enabled/supported by Firmware"));
4349 return -EINVAL;
4350 }
4351
Dino Mycle6fb96c12014-06-10 11:52:40 +05304352 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4353 data, dataLen,
4354 wlan_hdd_extscan_config_policy)) {
4355 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4356 return -EINVAL;
4357 }
4358
4359 /* Parse and fetch request Id */
4360 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4361 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4362 return -EINVAL;
4363 }
4364
Dino Myclee8843b32014-07-04 14:21:45 +05304365 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304366 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304367 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304368
Dino Myclee8843b32014-07-04 14:21:45 +05304369 reqMsg.sessionId = pAdapter->sessionId;
4370 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304371
Dino Myclee8843b32014-07-04 14:21:45 +05304372 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304373 if (!HAL_STATUS_SUCCESS(status)) {
4374 hddLog(VOS_TRACE_LEVEL_ERROR,
4375 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304376 return -EINVAL;
4377 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304378 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304379 return 0;
4380}
4381
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304382static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4383 struct wireless_dev *wdev,
4384 const void *data, int dataLen)
4385{
4386 int ret = 0;
4387
4388 vos_ssr_protect(__func__);
4389 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4390 vos_ssr_unprotect(__func__);
4391
4392 return ret;
4393}
4394
4395static int __wlan_hdd_cfg80211_extscan_reset_significant_change(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304396 struct wiphy *wiphy,
4397 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304398 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304399{
Dino Myclee8843b32014-07-04 14:21:45 +05304400 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304401 struct net_device *dev = wdev->netdev;
4402 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4403 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4404 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4405 eHalStatus status;
4406
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304407 ENTER();
4408
Dino Mycle6fb96c12014-06-10 11:52:40 +05304409 status = wlan_hdd_validate_context(pHddCtx);
4410 if (0 != status)
4411 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304412 return -EINVAL;
4413 }
Dino Myclee8843b32014-07-04 14:21:45 +05304414 /* check the EXTScan Capability */
4415 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4416 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4417 {
4418 hddLog(VOS_TRACE_LEVEL_ERROR,
4419 FL("EXTScan not enabled/supported by Firmware"));
4420 return -EINVAL;
4421 }
4422
Dino Mycle6fb96c12014-06-10 11:52:40 +05304423 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4424 data, dataLen,
4425 wlan_hdd_extscan_config_policy)) {
4426 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4427 return -EINVAL;
4428 }
4429
4430 /* Parse and fetch request Id */
4431 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4432 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4433 return -EINVAL;
4434 }
4435
Dino Mycle6fb96c12014-06-10 11:52:40 +05304436
Dino Myclee8843b32014-07-04 14:21:45 +05304437 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304438 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304439 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304440
Dino Myclee8843b32014-07-04 14:21:45 +05304441 reqMsg.sessionId = pAdapter->sessionId;
4442 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304443
Dino Myclee8843b32014-07-04 14:21:45 +05304444 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304445 if (!HAL_STATUS_SUCCESS(status)) {
4446 hddLog(VOS_TRACE_LEVEL_ERROR,
4447 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304448 return -EINVAL;
4449 }
4450
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304451 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304452 return 0;
4453}
4454
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304455static int wlan_hdd_cfg80211_extscan_reset_significant_change(
4456 struct wiphy *wiphy,
4457 struct wireless_dev *wdev,
4458 const void *data, int dataLen)
4459{
4460 int ret = 0;
4461
4462 vos_ssr_protect(__func__);
4463 ret = __wlan_hdd_cfg80211_extscan_reset_significant_change(wiphy,
4464 wdev, data,
4465 dataLen);
4466 vos_ssr_unprotect(__func__);
4467
4468 return ret;
4469}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304470#endif /* WLAN_FEATURE_EXTSCAN */
4471
Atul Mittal115287b2014-07-08 13:26:33 +05304472/*EXT TDLS*/
4473static const struct nla_policy
4474wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4475{
4476 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4477 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4478 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4479 {.type = NLA_S32 },
4480 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4481 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4482
4483};
4484
4485static const struct nla_policy
4486wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4487{
4488 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4489
4490};
4491
4492static const struct nla_policy
4493wlan_hdd_tdls_config_state_change_policy[
4494 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4495{
4496 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4497 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4498 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304499 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4500 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4501 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304502
4503};
4504
4505static const struct nla_policy
4506wlan_hdd_tdls_config_get_status_policy[
4507 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4508{
4509 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4510 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4511 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304512 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4513 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4514 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304515
4516};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304517
4518static const struct nla_policy
4519wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4520{
4521 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4522};
4523
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304524static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304525 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304526 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304527 int data_len)
4528{
4529
4530 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4531 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4532
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304533 ENTER();
4534
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304535 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304536 return -EINVAL;
4537 }
4538 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
4539 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN disabled in ini"));
4540 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304541 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304542 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
4543 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN not supported by FW"));
4544 return -ENOTSUPP;
4545 }
4546
4547 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4548 data, data_len, wlan_hdd_mac_config)) {
4549 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4550 return -EINVAL;
4551 }
4552
4553 /* Parse and fetch mac address */
4554 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4555 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4556 return -EINVAL;
4557 }
4558
4559 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4560 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4561 VOS_MAC_ADDR_LAST_3_BYTES);
4562
Siddharth Bhal76972212014-10-15 16:22:51 +05304563 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4564
4565 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304566 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4567 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304568 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4569 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4570 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4571 {
4572 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4573 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4574 VOS_MAC_ADDRESS_LEN);
4575 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304576 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304577
Siddharth Bhal76972212014-10-15 16:22:51 +05304578 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
4579 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304580 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4581 }
4582
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304583 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304584 return 0;
4585}
4586
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304587static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
4588 struct wireless_dev *wdev,
4589 const void *data,
4590 int data_len)
4591{
4592 int ret = 0;
4593
4594 vos_ssr_protect(__func__);
4595 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
4596 vos_ssr_unprotect(__func__);
4597
4598 return ret;
4599}
4600
4601static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304602 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304603 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304604 int data_len)
4605{
4606 u8 peer[6] = {0};
4607 struct net_device *dev = wdev->netdev;
4608 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4609 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4610 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4611 eHalStatus ret;
4612 tANI_S32 state;
4613 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304614 tANI_S32 global_operating_class = 0;
4615 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304616 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304617 int retVal;
4618
4619 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304620
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304621 if (!pAdapter) {
4622 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4623 return -EINVAL;
4624 }
4625
Atul Mittal115287b2014-07-08 13:26:33 +05304626 ret = wlan_hdd_validate_context(pHddCtx);
4627 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304628 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304629 return -EINVAL;
4630 }
4631 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304632 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304633 return -ENOTSUPP;
4634 }
4635 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4636 data, data_len,
4637 wlan_hdd_tdls_config_get_status_policy)) {
4638 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4639 return -EINVAL;
4640 }
4641
4642 /* Parse and fetch mac address */
4643 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4644 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4645 return -EINVAL;
4646 }
4647
4648 memcpy(peer, nla_data(
4649 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4650 sizeof(peer));
4651 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4652
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05304653 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05304654
Atul Mittal115287b2014-07-08 13:26:33 +05304655 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304656 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304657 NLMSG_HDRLEN);
4658
4659 if (!skb) {
4660 hddLog(VOS_TRACE_LEVEL_ERROR,
4661 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4662 return -EINVAL;
4663 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304664 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05304665 reason,
4666 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304667 global_operating_class,
4668 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304669 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304670 if (nla_put_s32(skb,
4671 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4672 state) ||
4673 nla_put_s32(skb,
4674 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4675 reason) ||
4676 nla_put_s32(skb,
4677 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4678 global_operating_class) ||
4679 nla_put_s32(skb,
4680 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4681 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304682
4683 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4684 goto nla_put_failure;
4685 }
4686
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304687 retVal = cfg80211_vendor_cmd_reply(skb);
4688 EXIT();
4689 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05304690
4691nla_put_failure:
4692 kfree_skb(skb);
4693 return -EINVAL;
4694}
4695
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304696static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4697 struct wireless_dev *wdev,
4698 const void *data,
4699 int data_len)
4700{
4701 int ret = 0;
4702
4703 vos_ssr_protect(__func__);
4704 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
4705 vos_ssr_unprotect(__func__);
4706
4707 return ret;
4708}
4709
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05304710static int wlan_hdd_cfg80211_exttdls_callback(
4711#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
4712 const tANI_U8* mac,
4713#else
4714 tANI_U8* mac,
4715#endif
Atul Mittal115287b2014-07-08 13:26:33 +05304716 tANI_S32 state,
4717 tANI_S32 reason,
4718 void *ctx)
4719{
4720 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05304721 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304722 tANI_S32 global_operating_class = 0;
4723 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304724 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05304725
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304726 ENTER();
4727
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304728 if (!pAdapter) {
4729 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4730 return -EINVAL;
4731 }
4732
4733 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05304734 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304735 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304736 return -EINVAL;
4737 }
4738
4739 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304740 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304741 return -ENOTSUPP;
4742 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304743 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
4744#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4745 NULL,
4746#endif
Atul Mittal115287b2014-07-08 13:26:33 +05304747 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4748 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4749 GFP_KERNEL);
4750
4751 if (!skb) {
4752 hddLog(VOS_TRACE_LEVEL_ERROR,
4753 FL("cfg80211_vendor_event_alloc failed"));
4754 return -EINVAL;
4755 }
4756 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304757 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4758 reason,
4759 state,
4760 global_operating_class,
4761 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304762 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4763 MAC_ADDR_ARRAY(mac));
4764
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304765 if (nla_put(skb,
4766 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4767 VOS_MAC_ADDR_SIZE, mac) ||
4768 nla_put_s32(skb,
4769 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4770 state) ||
4771 nla_put_s32(skb,
4772 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4773 reason) ||
4774 nla_put_s32(skb,
4775 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4776 channel) ||
4777 nla_put_s32(skb,
4778 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4779 global_operating_class)
4780 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304781 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4782 goto nla_put_failure;
4783 }
4784
4785 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304786 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05304787 return (0);
4788
4789nla_put_failure:
4790 kfree_skb(skb);
4791 return -EINVAL;
4792}
4793
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304794static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304795 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304796 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304797 int data_len)
4798{
4799 u8 peer[6] = {0};
4800 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304801 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4802 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4803 eHalStatus status;
4804 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304805 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304806 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304807
4808 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304809
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304810 if (!dev) {
4811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4812 return -EINVAL;
4813 }
4814
4815 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4816 if (!pAdapter) {
4817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4818 return -EINVAL;
4819 }
4820
Atul Mittal115287b2014-07-08 13:26:33 +05304821 status = wlan_hdd_validate_context(pHddCtx);
4822 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304823 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304824 return -EINVAL;
4825 }
4826 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304828 return -ENOTSUPP;
4829 }
4830 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4831 data, data_len,
4832 wlan_hdd_tdls_config_enable_policy)) {
4833 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4834 return -EINVAL;
4835 }
4836
4837 /* Parse and fetch mac address */
4838 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4839 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4840 return -EINVAL;
4841 }
4842
4843 memcpy(peer, nla_data(
4844 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4845 sizeof(peer));
4846 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4847
4848 /* Parse and fetch channel */
4849 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4850 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4851 return -EINVAL;
4852 }
4853 pReqMsg.channel = nla_get_s32(
4854 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4855 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4856
4857 /* Parse and fetch global operating class */
4858 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4859 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4860 return -EINVAL;
4861 }
4862 pReqMsg.global_operating_class = nla_get_s32(
4863 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4864 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4865 pReqMsg.global_operating_class);
4866
4867 /* Parse and fetch latency ms */
4868 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4869 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4870 return -EINVAL;
4871 }
4872 pReqMsg.max_latency_ms = nla_get_s32(
4873 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4874 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4875 pReqMsg.max_latency_ms);
4876
4877 /* Parse and fetch required bandwidth kbps */
4878 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4879 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4880 return -EINVAL;
4881 }
4882
4883 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4884 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4885 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4886 pReqMsg.min_bandwidth_kbps);
4887
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304888 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05304889 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05304890 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304891 wlan_hdd_cfg80211_exttdls_callback);
4892
4893 EXIT();
4894 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304895}
4896
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304897static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4898 struct wireless_dev *wdev,
4899 const void *data,
4900 int data_len)
4901{
4902 int ret = 0;
4903
4904 vos_ssr_protect(__func__);
4905 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
4906 vos_ssr_unprotect(__func__);
4907
4908 return ret;
4909}
4910
4911static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304912 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304913 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304914 int data_len)
4915{
4916 u8 peer[6] = {0};
4917 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304918 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4919 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4920 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304921 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304922 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304923
4924 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304925
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304926 if (!dev) {
4927 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4928 return -EINVAL;
4929 }
4930
4931 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4932 if (!pAdapter) {
4933 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
4934 return -EINVAL;
4935 }
4936
Atul Mittal115287b2014-07-08 13:26:33 +05304937 status = wlan_hdd_validate_context(pHddCtx);
4938 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304939 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304940 return -EINVAL;
4941 }
4942 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304943 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304944 return -ENOTSUPP;
4945 }
4946 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4947 data, data_len,
4948 wlan_hdd_tdls_config_disable_policy)) {
4949 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4950 return -EINVAL;
4951 }
4952 /* Parse and fetch mac address */
4953 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4954 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4955 return -EINVAL;
4956 }
4957
4958 memcpy(peer, nla_data(
4959 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4960 sizeof(peer));
4961 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4962
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304963 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
4964
4965 EXIT();
4966 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304967}
4968
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304969static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4970 struct wireless_dev *wdev,
4971 const void *data,
4972 int data_len)
4973{
4974 int ret = 0;
4975
4976 vos_ssr_protect(__func__);
4977 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
4978 vos_ssr_unprotect(__func__);
4979
4980 return ret;
4981}
4982
Dasari Srinivas7875a302014-09-26 17:50:57 +05304983static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304984__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05304985 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304986 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05304987{
4988 struct net_device *dev = wdev->netdev;
4989 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4990 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4991 struct sk_buff *skb = NULL;
4992 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304993 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05304994
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304995 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304996
4997 ret = wlan_hdd_validate_context(pHddCtx);
4998 if (0 != ret)
4999 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305000 return ret;
5001 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305002 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5003 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5004 fset |= WIFI_FEATURE_INFRA;
5005 }
5006
5007 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5008 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5009 fset |= WIFI_FEATURE_INFRA_5G;
5010 }
5011
5012#ifdef WLAN_FEATURE_P2P
5013 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5014 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5015 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5016 fset |= WIFI_FEATURE_P2P;
5017 }
5018#endif
5019
5020 /* Soft-AP is supported currently by default */
5021 fset |= WIFI_FEATURE_SOFT_AP;
5022
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305023 /* HOTSPOT is a supplicant feature, enable it by default */
5024 fset |= WIFI_FEATURE_HOTSPOT;
5025
Dasari Srinivas7875a302014-09-26 17:50:57 +05305026#ifdef WLAN_FEATURE_EXTSCAN
5027 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
5028 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
5029 hddLog(LOG1, FL("EXTScan is supported by firmware"));
5030 fset |= WIFI_FEATURE_EXTSCAN;
5031 }
5032#endif
5033
Dasari Srinivas7875a302014-09-26 17:50:57 +05305034 if (sme_IsFeatureSupportedByFW(NAN)) {
5035 hddLog(LOG1, FL("NAN is supported by firmware"));
5036 fset |= WIFI_FEATURE_NAN;
5037 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305038
5039 /* D2D RTT is not supported currently by default */
5040 if (sme_IsFeatureSupportedByFW(RTT)) {
5041 hddLog(LOG1, FL("RTT is supported by firmware"));
5042 fset |= WIFI_FEATURE_D2AP_RTT;
5043 }
5044
5045#ifdef FEATURE_WLAN_BATCH_SCAN
5046 if (fset & WIFI_FEATURE_EXTSCAN) {
5047 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5048 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5049 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5050 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5051 fset |= WIFI_FEATURE_BATCH_SCAN;
5052 }
5053#endif
5054
5055#ifdef FEATURE_WLAN_SCAN_PNO
5056 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5057 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5058 hddLog(LOG1, FL("PNO is supported by firmware"));
5059 fset |= WIFI_FEATURE_PNO;
5060 }
5061#endif
5062
5063 /* STA+STA is supported currently by default */
5064 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5065
5066#ifdef FEATURE_WLAN_TDLS
5067 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5068 sme_IsFeatureSupportedByFW(TDLS)) {
5069 hddLog(LOG1, FL("TDLS is supported by firmware"));
5070 fset |= WIFI_FEATURE_TDLS;
5071 }
5072
5073 /* TDLS_OFFCHANNEL is not supported currently by default */
5074#endif
5075
5076#ifdef WLAN_AP_STA_CONCURRENCY
5077 /* AP+STA concurrency is supported currently by default */
5078 fset |= WIFI_FEATURE_AP_STA;
5079#endif
5080
5081 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5082 NLMSG_HDRLEN);
5083
5084 if (!skb) {
5085 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5086 return -EINVAL;
5087 }
5088 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5089
5090 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5091 hddLog(LOGE, FL("nla put fail"));
5092 goto nla_put_failure;
5093 }
5094
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305095 ret = cfg80211_vendor_cmd_reply(skb);
5096 EXIT();
5097 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305098
5099nla_put_failure:
5100 kfree_skb(skb);
5101 return -EINVAL;
5102}
5103
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305104static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305105wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5106 struct wireless_dev *wdev,
5107 const void *data, int data_len)
5108{
5109 int ret = 0;
5110
5111 vos_ssr_protect(__func__);
5112 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5113 vos_ssr_unprotect(__func__);
5114
5115 return ret;
5116}
5117
5118static int
5119__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305120 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305121 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305122{
5123 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5124 uint8_t i, feature_sets, max_feature_sets;
5125 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5126 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305127 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5128 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305129
5130 ENTER();
5131
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305132 ret = wlan_hdd_validate_context(pHddCtx);
5133 if (0 != ret)
5134 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305135 return ret;
5136 }
5137
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305138 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5139 data, data_len, NULL)) {
5140 hddLog(LOGE, FL("Invalid ATTR"));
5141 return -EINVAL;
5142 }
5143
5144 /* Parse and fetch max feature set */
5145 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5146 hddLog(LOGE, FL("Attr max feature set size failed"));
5147 return -EINVAL;
5148 }
5149 max_feature_sets = nla_get_u32(
5150 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5151 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5152
5153 /* Fill feature combination matrix */
5154 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305155 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5156 WIFI_FEATURE_P2P;
5157
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305158 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5159 WIFI_FEATURE_SOFT_AP;
5160
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305161 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5162 WIFI_FEATURE_SOFT_AP;
5163
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305164 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5165 WIFI_FEATURE_SOFT_AP |
5166 WIFI_FEATURE_P2P;
5167
5168 /* Add more feature combinations here */
5169
5170 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5171 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5172 hddLog(LOG1, "Feature set matrix");
5173 for (i = 0; i < feature_sets; i++)
5174 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5175
5176 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5177 sizeof(u32) * feature_sets +
5178 NLMSG_HDRLEN);
5179
5180 if (reply_skb) {
5181 if (nla_put_u32(reply_skb,
5182 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5183 feature_sets) ||
5184 nla_put(reply_skb,
5185 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5186 sizeof(u32) * feature_sets, feature_set_matrix)) {
5187 hddLog(LOGE, FL("nla put fail"));
5188 kfree_skb(reply_skb);
5189 return -EINVAL;
5190 }
5191
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305192 ret = cfg80211_vendor_cmd_reply(reply_skb);
5193 EXIT();
5194 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305195 }
5196 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5197 return -ENOMEM;
5198
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305199}
5200
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305201static int
5202wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5203 struct wireless_dev *wdev,
5204 const void *data, int data_len)
5205{
5206 int ret = 0;
5207
5208 vos_ssr_protect(__func__);
5209 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5210 data_len);
5211 vos_ssr_unprotect(__func__);
5212
5213 return ret;
5214}
5215
Agarwal Ashish738843c2014-09-25 12:27:56 +05305216static const struct nla_policy
5217wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5218 +1] =
5219{
5220 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5221};
5222
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305223static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305224 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305225 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305226 int data_len)
5227{
5228 struct net_device *dev = wdev->netdev;
5229 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5230 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5231 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5232 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5233 eHalStatus status;
5234 u32 dfsFlag = 0;
5235
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305236 ENTER();
5237
Agarwal Ashish738843c2014-09-25 12:27:56 +05305238 status = wlan_hdd_validate_context(pHddCtx);
5239 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305240 return -EINVAL;
5241 }
5242 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5243 data, data_len,
5244 wlan_hdd_set_no_dfs_flag_config_policy)) {
5245 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5246 return -EINVAL;
5247 }
5248
5249 /* Parse and fetch required bandwidth kbps */
5250 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5251 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5252 return -EINVAL;
5253 }
5254
5255 dfsFlag = nla_get_u32(
5256 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5257 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5258 dfsFlag);
5259
5260 pHddCtx->disable_dfs_flag = dfsFlag;
5261
5262 sme_disable_dfs_channel(hHal, dfsFlag);
5263 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305264
5265 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305266 return 0;
5267}
Atul Mittal115287b2014-07-08 13:26:33 +05305268
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305269static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5270 struct wireless_dev *wdev,
5271 const void *data,
5272 int data_len)
5273{
5274 int ret = 0;
5275
5276 vos_ssr_protect(__func__);
5277 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5278 vos_ssr_unprotect(__func__);
5279
5280 return ret;
5281
5282}
5283
Mukul Sharma2a271632014-10-13 14:59:01 +05305284const struct
5285nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5286{
5287 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5288 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5289};
5290
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305291static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305292 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305293{
5294
5295 u8 bssid[6] = {0};
5296 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5297 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5298 eHalStatus status = eHAL_STATUS_SUCCESS;
5299 v_U32_t isFwrRoamEnabled = FALSE;
5300 int ret;
5301
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305302 ENTER();
5303
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305304 ret = wlan_hdd_validate_context(pHddCtx);
5305 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305306 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305307 }
5308
5309 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5310 data, data_len,
5311 qca_wlan_vendor_attr);
5312 if (ret){
5313 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5314 return -EINVAL;
5315 }
5316
5317 /* Parse and fetch Enable flag */
5318 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5319 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5320 return -EINVAL;
5321 }
5322
5323 isFwrRoamEnabled = nla_get_u32(
5324 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5325
5326 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5327
5328 /* Parse and fetch bssid */
5329 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5330 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5331 return -EINVAL;
5332 }
5333
5334 memcpy(bssid, nla_data(
5335 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5336 sizeof(bssid));
5337 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5338
5339 //Update roaming
5340 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305341 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305342 return status;
5343}
5344
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305345static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5346 struct wireless_dev *wdev, const void *data, int data_len)
5347{
5348 int ret = 0;
5349
5350 vos_ssr_protect(__func__);
5351 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5352 vos_ssr_unprotect(__func__);
5353
5354 return ret;
5355}
5356
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305357/**
5358 * __wlan_hdd_cfg80211_setband() - set band
5359 * @wiphy: Pointer to wireless phy
5360 * @wdev: Pointer to wireless device
5361 * @data: Pointer to data
5362 * @data_len: Data length
5363 *
5364 * Return: 0 on success, negative errno on failure
5365 */
5366static int
5367__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5368 struct wireless_dev *wdev,
5369 const void *data,
5370 int data_len)
5371{
5372 struct net_device *dev = wdev->netdev;
5373 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5374 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5375 int ret;
5376 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
5377 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
5378
5379 ENTER();
5380
5381 ret = wlan_hdd_validate_context(hdd_ctx);
5382 if (0 != ret) {
5383 hddLog(LOGE, FL("HDD context is not valid"));
5384 return ret;
5385 }
5386
5387 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
5388 policy)) {
5389 hddLog(LOGE, FL("Invalid ATTR"));
5390 return -EINVAL;
5391 }
5392
5393 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
5394 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
5395 return -EINVAL;
5396 }
5397
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305398 hdd_ctx->isSetBandByNL = TRUE;
5399 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305400 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305401 hdd_ctx->isSetBandByNL = FALSE;
5402
5403 EXIT();
5404 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305405}
5406
5407/**
5408 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
5409 * @wiphy: wiphy structure pointer
5410 * @wdev: Wireless device structure pointer
5411 * @data: Pointer to the data received
5412 * @data_len: Length of @data
5413 *
5414 * Return: 0 on success; errno on failure
5415 */
5416static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5417 struct wireless_dev *wdev,
5418 const void *data,
5419 int data_len)
5420{
5421 int ret = 0;
5422
5423 vos_ssr_protect(__func__);
5424 ret = __wlan_hdd_cfg80211_setband(wiphy,
5425 wdev, data, data_len);
5426 vos_ssr_unprotect(__func__);
5427
5428 return ret;
5429}
5430
Sunil Duttc69bccb2014-05-26 21:30:20 +05305431const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
5432{
Mukul Sharma2a271632014-10-13 14:59:01 +05305433 {
5434 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5435 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
5436 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5437 WIPHY_VENDOR_CMD_NEED_NETDEV |
5438 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305439 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05305440 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305441
5442 {
5443 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5444 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
5445 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5446 WIPHY_VENDOR_CMD_NEED_NETDEV |
5447 WIPHY_VENDOR_CMD_NEED_RUNNING,
5448 .doit = wlan_hdd_cfg80211_nan_request
5449 },
5450
Sunil Duttc69bccb2014-05-26 21:30:20 +05305451#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5452 {
5453 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5454 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
5455 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5456 WIPHY_VENDOR_CMD_NEED_NETDEV |
5457 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305458 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05305459 },
5460
5461 {
5462 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5463 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
5464 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5465 WIPHY_VENDOR_CMD_NEED_NETDEV |
5466 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305467 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05305468 },
5469
5470 {
5471 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5472 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
5473 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5474 WIPHY_VENDOR_CMD_NEED_NETDEV |
5475 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305476 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05305477 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305478#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305479#ifdef WLAN_FEATURE_EXTSCAN
5480 {
5481 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5482 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
5483 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5484 WIPHY_VENDOR_CMD_NEED_NETDEV |
5485 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305486 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05305487 },
5488 {
5489 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5490 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
5491 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5492 WIPHY_VENDOR_CMD_NEED_NETDEV |
5493 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305494 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05305495 },
5496 {
5497 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5498 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
5499 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5500 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305501 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05305502 },
5503 {
5504 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5505 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
5506 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5507 WIPHY_VENDOR_CMD_NEED_NETDEV |
5508 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305509 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05305510 },
5511 {
5512 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5513 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
5514 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5515 WIPHY_VENDOR_CMD_NEED_NETDEV |
5516 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305517 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05305518 },
5519 {
5520 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5521 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
5522 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5523 WIPHY_VENDOR_CMD_NEED_NETDEV |
5524 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305525 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305526 },
5527 {
5528 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5529 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
5530 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5531 WIPHY_VENDOR_CMD_NEED_NETDEV |
5532 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305533 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305534 },
5535 {
5536 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5537 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
5538 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5539 WIPHY_VENDOR_CMD_NEED_NETDEV |
5540 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305541 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305542 },
5543 {
5544 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5545 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
5546 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5547 WIPHY_VENDOR_CMD_NEED_NETDEV |
5548 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305549 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305550 },
5551#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305552/*EXT TDLS*/
5553 {
5554 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5555 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
5556 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5557 WIPHY_VENDOR_CMD_NEED_NETDEV |
5558 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305559 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05305560 },
5561 {
5562 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5563 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
5564 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5565 WIPHY_VENDOR_CMD_NEED_NETDEV |
5566 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305567 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05305568 },
5569 {
5570 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5571 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
5572 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5573 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305574 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05305575 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05305576 {
5577 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5578 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
5579 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5580 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305581 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05305582 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05305583 {
5584 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5585 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
5586 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5587 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305588 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05305589 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305590 {
5591 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5592 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
5593 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5594 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305595 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305596 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305597 {
5598 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5599 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
5600 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5601 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305602 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305603 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305604 {
5605 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5606 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
5607 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5608 WIPHY_VENDOR_CMD_NEED_NETDEV |
5609 WIPHY_VENDOR_CMD_NEED_RUNNING,
5610 .doit = wlan_hdd_cfg80211_setband
5611 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05305612};
5613
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005614/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05305615static const
5616struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005617{
5618#ifdef FEATURE_WLAN_CH_AVOID
5619 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05305620 .vendor_id = QCA_NL80211_VENDOR_ID,
5621 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005622 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305623#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
5624#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5625 {
5626 /* Index = 1*/
5627 .vendor_id = QCA_NL80211_VENDOR_ID,
5628 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
5629 },
5630 {
5631 /* Index = 2*/
5632 .vendor_id = QCA_NL80211_VENDOR_ID,
5633 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
5634 },
5635 {
5636 /* Index = 3*/
5637 .vendor_id = QCA_NL80211_VENDOR_ID,
5638 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
5639 },
5640 {
5641 /* Index = 4*/
5642 .vendor_id = QCA_NL80211_VENDOR_ID,
5643 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
5644 },
5645 {
5646 /* Index = 5*/
5647 .vendor_id = QCA_NL80211_VENDOR_ID,
5648 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
5649 },
5650 {
5651 /* Index = 6*/
5652 .vendor_id = QCA_NL80211_VENDOR_ID,
5653 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
5654 },
5655#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305656#ifdef WLAN_FEATURE_EXTSCAN
5657 {
5658 .vendor_id = QCA_NL80211_VENDOR_ID,
5659 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
5660 },
5661 {
5662 .vendor_id = QCA_NL80211_VENDOR_ID,
5663 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
5664 },
5665 {
5666 .vendor_id = QCA_NL80211_VENDOR_ID,
5667 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
5668 },
5669 {
5670 .vendor_id = QCA_NL80211_VENDOR_ID,
5671 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
5672 },
5673 {
5674 .vendor_id = QCA_NL80211_VENDOR_ID,
5675 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
5676 },
5677 {
5678 .vendor_id = QCA_NL80211_VENDOR_ID,
5679 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
5680 },
5681 {
5682 .vendor_id = QCA_NL80211_VENDOR_ID,
5683 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
5684 },
5685 {
5686 .vendor_id = QCA_NL80211_VENDOR_ID,
5687 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
5688 },
5689 {
5690 .vendor_id = QCA_NL80211_VENDOR_ID,
5691 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
5692 },
5693 {
5694 .vendor_id = QCA_NL80211_VENDOR_ID,
5695 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
5696 },
5697 {
5698 .vendor_id = QCA_NL80211_VENDOR_ID,
5699 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
5700 },
5701 {
5702 .vendor_id = QCA_NL80211_VENDOR_ID,
5703 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
5704 },
5705 {
5706 .vendor_id = QCA_NL80211_VENDOR_ID,
5707 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
5708 },
5709#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305710/*EXT TDLS*/
5711 {
5712 .vendor_id = QCA_NL80211_VENDOR_ID,
5713 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
5714 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305715
5716 {
5717 .vendor_id = QCA_NL80211_VENDOR_ID,
5718 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
5719 },
5720
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005721};
5722
Jeff Johnson295189b2012-06-20 16:38:30 -07005723/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305724 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305725 * This function is called by hdd_wlan_startup()
5726 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305727 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07005728 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305729struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07005730{
5731 struct wiphy *wiphy;
5732 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305733 /*
5734 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07005735 */
5736 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
5737
5738 if (!wiphy)
5739 {
5740 /* Print error and jump into err label and free the memory */
5741 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
5742 return NULL;
5743 }
5744
Sunil Duttc69bccb2014-05-26 21:30:20 +05305745
Jeff Johnson295189b2012-06-20 16:38:30 -07005746 return wiphy;
5747}
5748
5749/*
5750 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305751 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07005752 * private ioctl to change the band value
5753 */
5754int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
5755{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305756 int i, j;
5757 eNVChannelEnabledType channelEnabledState;
5758
Jeff Johnsone7245742012-09-05 17:12:55 -07005759 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305760
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305761 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005762 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305763
5764 if (NULL == wiphy->bands[i])
5765 {
5766 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5767 __func__, i);
5768 continue;
5769 }
5770
5771 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5772 {
5773 struct ieee80211_supported_band *band = wiphy->bands[i];
5774
5775 channelEnabledState = vos_nv_getChannelEnabledState(
5776 band->channels[j].hw_value);
5777
5778 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
5779 {
Abhishek Singh678227a2014-11-04 10:52:38 +05305780 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305781 continue;
5782 }
5783 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
5784 {
5785 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5786 continue;
5787 }
5788
5789 if (NV_CHANNEL_DISABLE == channelEnabledState ||
5790 NV_CHANNEL_INVALID == channelEnabledState)
5791 {
5792 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5793 }
5794 else if (NV_CHANNEL_DFS == channelEnabledState)
5795 {
5796 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5797 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
5798 }
5799 else
5800 {
5801 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
5802 |IEEE80211_CHAN_RADAR);
5803 }
5804 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005805 }
5806 return 0;
5807}
5808/*
5809 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305810 * This function is called by hdd_wlan_startup()
5811 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005812 * This function is used to initialize and register wiphy structure.
5813 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305814int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005815 struct wiphy *wiphy,
5816 hdd_config_t *pCfg
5817 )
5818{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305819 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305820 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5821
Jeff Johnsone7245742012-09-05 17:12:55 -07005822 ENTER();
5823
Jeff Johnson295189b2012-06-20 16:38:30 -07005824 /* Now bind the underlying wlan device with wiphy */
5825 set_wiphy_dev(wiphy, dev);
5826
5827 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005828
Kiet Lam6c583332013-10-14 05:37:09 +05305829#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005830 /* the flag for the other case would be initialzed in
5831 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005832 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305833#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005834
Amar Singhalfddc28c2013-09-05 13:03:40 -07005835 /* This will disable updating of NL channels from passive to
5836 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05305837#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
5838 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
5839#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07005840 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05305841#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07005842
Amar Singhala49cbc52013-10-08 18:37:44 -07005843
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005844#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005845 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5846 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5847 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005848 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05305849#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
5850 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
5851#else
5852 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
5853#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005854#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005855
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005856#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005857 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005858#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005859 || pCfg->isFastRoamIniFeatureEnabled
5860#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005861#ifdef FEATURE_WLAN_ESE
5862 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005863#endif
5864 )
5865 {
5866 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5867 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005868#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005869#ifdef FEATURE_WLAN_TDLS
5870 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5871 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5872#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305873#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305874 if (pCfg->configPNOScanSupport)
5875 {
5876 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5877 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5878 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5879 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5880 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305881#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005882
Abhishek Singh10d85972015-04-17 10:27:23 +05305883#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5884 wiphy->features |= NL80211_FEATURE_HT_IBSS;
5885#endif
5886
Amar Singhalfddc28c2013-09-05 13:03:40 -07005887#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005888 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5889 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005890 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005891 driver need to determine what to do with both
5892 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005893
5894 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005895#else
5896 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005897#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005898
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305899 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5900
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05305901 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005902
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305903 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5904
Jeff Johnson295189b2012-06-20 16:38:30 -07005905 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05305906 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
5907 | BIT(NL80211_IFTYPE_ADHOC)
5908 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5909 | BIT(NL80211_IFTYPE_P2P_GO)
5910 | BIT(NL80211_IFTYPE_AP);
5911
5912 if (VOS_MONITOR_MODE == hdd_get_conparam())
5913 {
5914 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
5915 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005916
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305917 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005918 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305919#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5920 if( pCfg->enableMCC )
5921 {
5922 /* Currently, supports up to two channels */
5923 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005924
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305925 if( !pCfg->allowMCCGODiffBI )
5926 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005927
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305928 }
5929 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5930 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005931#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305932 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005933
Jeff Johnson295189b2012-06-20 16:38:30 -07005934 /* Before registering we need to update the ht capabilitied based
5935 * on ini values*/
5936 if( !pCfg->ShortGI20MhzEnable )
5937 {
5938 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5939 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5940 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5941 }
5942
5943 if( !pCfg->ShortGI40MhzEnable )
5944 {
5945 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5946 }
5947
5948 if( !pCfg->nChannelBondingMode5GHz )
5949 {
5950 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5951 }
5952
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305953 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305954 if (true == hdd_is_5g_supported(pHddCtx))
5955 {
5956 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5957 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305958
5959 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5960 {
5961
5962 if (NULL == wiphy->bands[i])
5963 {
5964 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5965 __func__, i);
5966 continue;
5967 }
5968
5969 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5970 {
5971 struct ieee80211_supported_band *band = wiphy->bands[i];
5972
5973 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5974 {
5975 // Enable social channels for P2P
5976 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5977 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5978 else
5979 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5980 continue;
5981 }
5982 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5983 {
5984 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5985 continue;
5986 }
5987 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005988 }
5989 /*Initialise the supported cipher suite details*/
5990 wiphy->cipher_suites = hdd_cipher_suites;
5991 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5992
5993 /*signal strength in mBm (100*dBm) */
5994 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5995
5996#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305997 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005998#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005999
Sunil Duttc69bccb2014-05-26 21:30:20 +05306000 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
6001 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006002 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
6003 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
6004
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306005 EXIT();
6006 return 0;
6007}
6008
6009/* In this function we are registering wiphy. */
6010int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
6011{
6012 ENTER();
6013 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006014 if (0 > wiphy_register(wiphy))
6015 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306016 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07006017 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
6018 return -EIO;
6019 }
6020
6021 EXIT();
6022 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306023}
Jeff Johnson295189b2012-06-20 16:38:30 -07006024
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306025/* In this function we are updating channel list when,
6026 regulatory domain is FCC and country code is US.
6027 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
6028 As per FCC smart phone is not a indoor device.
6029 GO should not opeate on indoor channels */
6030void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
6031{
6032 int j;
6033 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6034 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
6035 //Default counrtycode from NV at the time of wiphy initialization.
6036 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
6037 &defaultCountryCode[0]))
6038 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006039 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306040 }
6041 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
6042 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306043 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
6044 {
6045 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
6046 return;
6047 }
6048 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
6049 {
6050 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
6051 // Mark UNII -1 band channel as passive
6052 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
6053 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
6054 }
6055 }
6056}
6057
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306058/* This function registers for all frame which supplicant is interested in */
6059void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006060{
Jeff Johnson295189b2012-06-20 16:38:30 -07006061 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6062 /* Register for all P2P action, public action etc frames */
6063 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6064
Jeff Johnsone7245742012-09-05 17:12:55 -07006065 ENTER();
6066
Jeff Johnson295189b2012-06-20 16:38:30 -07006067 /* Right now we are registering these frame when driver is getting
6068 initialized. Once we will move to 2.6.37 kernel, in which we have
6069 frame register ops, we will move this code as a part of that */
6070 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306071 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006072 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6073
6074 /* GAS Initial Response */
6075 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6076 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306077
Jeff Johnson295189b2012-06-20 16:38:30 -07006078 /* GAS Comeback Request */
6079 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6080 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6081
6082 /* GAS Comeback Response */
6083 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6084 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6085
6086 /* P2P Public Action */
6087 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306088 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006089 P2P_PUBLIC_ACTION_FRAME_SIZE );
6090
6091 /* P2P Action */
6092 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6093 (v_U8_t*)P2P_ACTION_FRAME,
6094 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07006095
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05306096 /* WNM BSS Transition Request frame */
6097 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6098 (v_U8_t*)WNM_BSS_ACTION_FRAME,
6099 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006100
6101 /* WNM-Notification */
6102 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6103 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6104 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006105}
6106
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306107void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006108{
Jeff Johnson295189b2012-06-20 16:38:30 -07006109 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6110 /* Register for all P2P action, public action etc frames */
6111 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6112
Jeff Johnsone7245742012-09-05 17:12:55 -07006113 ENTER();
6114
Jeff Johnson295189b2012-06-20 16:38:30 -07006115 /* Right now we are registering these frame when driver is getting
6116 initialized. Once we will move to 2.6.37 kernel, in which we have
6117 frame register ops, we will move this code as a part of that */
6118 /* GAS Initial Request */
6119
6120 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6121 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6122
6123 /* GAS Initial Response */
6124 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6125 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306126
Jeff Johnson295189b2012-06-20 16:38:30 -07006127 /* GAS Comeback Request */
6128 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6129 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6130
6131 /* GAS Comeback Response */
6132 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6133 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6134
6135 /* P2P Public Action */
6136 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306137 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006138 P2P_PUBLIC_ACTION_FRAME_SIZE );
6139
6140 /* P2P Action */
6141 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6142 (v_U8_t*)P2P_ACTION_FRAME,
6143 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006144 /* WNM-Notification */
6145 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6146 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6147 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006148}
6149
6150#ifdef FEATURE_WLAN_WAPI
6151void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05306152 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006153{
6154 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6155 tCsrRoamSetKey setKey;
6156 v_BOOL_t isConnected = TRUE;
6157 int status = 0;
6158 v_U32_t roamId= 0xFF;
6159 tANI_U8 *pKeyPtr = NULL;
6160 int n = 0;
6161
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306162 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6163 __func__, hdd_device_modetoString(pAdapter->device_mode),
6164 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006165
Gopichand Nakkalae7480202013-02-11 15:24:22 +05306166 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006167 setKey.keyId = key_index; // Store Key ID
6168 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
6169 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
6170 setKey.paeRole = 0 ; // the PAE role
6171 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
6172 {
6173 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
6174 }
6175 else
6176 {
6177 isConnected = hdd_connIsConnected(pHddStaCtx);
6178 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
6179 }
6180 setKey.keyLength = key_Len;
6181 pKeyPtr = setKey.Key;
6182 memcpy( pKeyPtr, key, key_Len);
6183
Arif Hussain6d2a3322013-11-17 19:50:10 -08006184 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07006185 __func__, key_Len);
6186 for (n = 0 ; n < key_Len; n++)
6187 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
6188 __func__,n,setKey.Key[n]);
6189
6190 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
6191 if ( isConnected )
6192 {
6193 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
6194 pAdapter->sessionId, &setKey, &roamId );
6195 }
6196 if ( status != 0 )
6197 {
6198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6199 "[%4d] sme_RoamSetKey returned ERROR status= %d",
6200 __LINE__, status );
6201 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
6202 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05306203 /* Need to clear any trace of key value in the memory.
6204 * Thus zero out the memory even though it is local
6205 * variable.
6206 */
6207 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006208}
6209#endif /* FEATURE_WLAN_WAPI*/
6210
6211#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306212int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006213 beacon_data_t **ppBeacon,
6214 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006215#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306216int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006217 beacon_data_t **ppBeacon,
6218 struct cfg80211_beacon_data *params,
6219 int dtim_period)
6220#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306221{
Jeff Johnson295189b2012-06-20 16:38:30 -07006222 int size;
6223 beacon_data_t *beacon = NULL;
6224 beacon_data_t *old = NULL;
6225 int head_len,tail_len;
6226
Jeff Johnsone7245742012-09-05 17:12:55 -07006227 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006228 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306229 {
6230 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6231 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006232 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306233 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006234
6235 old = pAdapter->sessionCtx.ap.beacon;
6236
6237 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306238 {
6239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6240 FL("session(%d) old and new heads points to NULL"),
6241 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006242 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306243 }
6244
6245 if (params->tail && !params->tail_len)
6246 {
6247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6248 FL("tail_len is zero but tail is not NULL"));
6249 return -EINVAL;
6250 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006251
Jeff Johnson295189b2012-06-20 16:38:30 -07006252#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
6253 /* Kernel 3.0 is not updating dtim_period for set beacon */
6254 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306255 {
6256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6257 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006258 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306259 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006260#endif
6261
6262 if(params->head)
6263 head_len = params->head_len;
6264 else
6265 head_len = old->head_len;
6266
6267 if(params->tail || !old)
6268 tail_len = params->tail_len;
6269 else
6270 tail_len = old->tail_len;
6271
6272 size = sizeof(beacon_data_t) + head_len + tail_len;
6273
6274 beacon = kzalloc(size, GFP_KERNEL);
6275
6276 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306277 {
6278 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6279 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006280 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306281 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006282
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006283#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006284 if(params->dtim_period || !old )
6285 beacon->dtim_period = params->dtim_period;
6286 else
6287 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006288#else
6289 if(dtim_period || !old )
6290 beacon->dtim_period = dtim_period;
6291 else
6292 beacon->dtim_period = old->dtim_period;
6293#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306294
Jeff Johnson295189b2012-06-20 16:38:30 -07006295 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6296 beacon->tail = beacon->head + head_len;
6297 beacon->head_len = head_len;
6298 beacon->tail_len = tail_len;
6299
6300 if(params->head) {
6301 memcpy (beacon->head,params->head,beacon->head_len);
6302 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306303 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07006304 if(old)
6305 memcpy (beacon->head,old->head,beacon->head_len);
6306 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306307
Jeff Johnson295189b2012-06-20 16:38:30 -07006308 if(params->tail) {
6309 memcpy (beacon->tail,params->tail,beacon->tail_len);
6310 }
6311 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306312 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07006313 memcpy (beacon->tail,old->tail,beacon->tail_len);
6314 }
6315
6316 *ppBeacon = beacon;
6317
6318 kfree(old);
6319
6320 return 0;
6321
6322}
Jeff Johnson295189b2012-06-20 16:38:30 -07006323
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306324v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
6325#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6326 const v_U8_t *pIes,
6327#else
6328 v_U8_t *pIes,
6329#endif
6330 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006331{
6332 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306333 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07006334 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306335
Jeff Johnson295189b2012-06-20 16:38:30 -07006336 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306337 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006338 elem_id = ptr[0];
6339 elem_len = ptr[1];
6340 left -= 2;
6341 if(elem_len > left)
6342 {
6343 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006344 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006345 eid,elem_len,left);
6346 return NULL;
6347 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306348 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006349 {
6350 return ptr;
6351 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306352
Jeff Johnson295189b2012-06-20 16:38:30 -07006353 left -= elem_len;
6354 ptr += (elem_len + 2);
6355 }
6356 return NULL;
6357}
6358
Jeff Johnson295189b2012-06-20 16:38:30 -07006359/* Check if rate is 11g rate or not */
6360static int wlan_hdd_rate_is_11g(u8 rate)
6361{
Sanjay Devnani28322e22013-06-21 16:13:40 -07006362 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006363 u8 i;
6364 for (i = 0; i < 8; i++)
6365 {
6366 if(rate == gRateArray[i])
6367 return TRUE;
6368 }
6369 return FALSE;
6370}
6371
6372/* Check for 11g rate and set proper 11g only mode */
6373static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
6374 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
6375{
6376 u8 i, num_rates = pIe[0];
6377
6378 pIe += 1;
6379 for ( i = 0; i < num_rates; i++)
6380 {
6381 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
6382 {
6383 /* If rate set have 11g rate than change the mode to 11G */
6384 *pSapHw_mode = eSAP_DOT11_MODE_11g;
6385 if (pIe[i] & BASIC_RATE_MASK)
6386 {
6387 /* If we have 11g rate as basic rate, it means mode
6388 is 11g only mode.
6389 */
6390 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
6391 *pCheckRatesfor11g = FALSE;
6392 }
6393 }
6394 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6395 {
6396 *require_ht = TRUE;
6397 }
6398 }
6399 return;
6400}
6401
6402static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
6403{
6404 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6405 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6406 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6407 u8 checkRatesfor11g = TRUE;
6408 u8 require_ht = FALSE;
6409 u8 *pIe=NULL;
6410
6411 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
6412
6413 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6414 pBeacon->head_len, WLAN_EID_SUPP_RATES);
6415 if (pIe != NULL)
6416 {
6417 pIe += 1;
6418 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6419 &pConfig->SapHw_mode);
6420 }
6421
6422 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6423 WLAN_EID_EXT_SUPP_RATES);
6424 if (pIe != NULL)
6425 {
6426
6427 pIe += 1;
6428 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6429 &pConfig->SapHw_mode);
6430 }
6431
6432 if( pConfig->channel > 14 )
6433 {
6434 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
6435 }
6436
6437 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6438 WLAN_EID_HT_CAPABILITY);
6439
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306440 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006441 {
6442 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
6443 if(require_ht)
6444 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
6445 }
6446}
6447
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306448static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
6449 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
6450{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006451 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306452 v_U8_t *pIe = NULL;
6453 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6454
6455 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6456 pBeacon->tail, pBeacon->tail_len);
6457
6458 if (pIe)
6459 {
6460 ielen = pIe[1] + 2;
6461 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6462 {
6463 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
6464 }
6465 else
6466 {
6467 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
6468 return -EINVAL;
6469 }
6470 *total_ielen += ielen;
6471 }
6472 return 0;
6473}
6474
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006475static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
6476 v_U8_t *genie, v_U8_t *total_ielen)
6477{
6478 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6479 int left = pBeacon->tail_len;
6480 v_U8_t *ptr = pBeacon->tail;
6481 v_U8_t elem_id, elem_len;
6482 v_U16_t ielen = 0;
6483
6484 if ( NULL == ptr || 0 == left )
6485 return;
6486
6487 while (left >= 2)
6488 {
6489 elem_id = ptr[0];
6490 elem_len = ptr[1];
6491 left -= 2;
6492 if (elem_len > left)
6493 {
6494 hddLog( VOS_TRACE_LEVEL_ERROR,
6495 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
6496 elem_id, elem_len, left);
6497 return;
6498 }
6499 if (IE_EID_VENDOR == elem_id)
6500 {
6501 /* skipping the VSIE's which we don't want to include or
6502 * it will be included by existing code
6503 */
6504 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
6505#ifdef WLAN_FEATURE_WFD
6506 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
6507#endif
6508 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6509 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6510 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
6511 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6512 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
6513 {
6514 ielen = ptr[1] + 2;
6515 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6516 {
6517 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
6518 *total_ielen += ielen;
6519 }
6520 else
6521 {
6522 hddLog( VOS_TRACE_LEVEL_ERROR,
6523 "IE Length is too big "
6524 "IEs eid=%d elem_len=%d total_ie_lent=%d",
6525 elem_id, elem_len, *total_ielen);
6526 }
6527 }
6528 }
6529
6530 left -= elem_len;
6531 ptr += (elem_len + 2);
6532 }
6533 return;
6534}
6535
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006536#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006537static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6538 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006539#else
6540static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6541 struct cfg80211_beacon_data *params)
6542#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006543{
6544 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306545 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006546 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07006547 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006548
6549 genie = vos_mem_malloc(MAX_GENIE_LEN);
6550
6551 if(genie == NULL) {
6552
6553 return -ENOMEM;
6554 }
6555
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306556 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6557 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006558 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306559 hddLog(LOGE,
6560 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306561 ret = -EINVAL;
6562 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006563 }
6564
6565#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306566 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6567 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
6568 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306569 hddLog(LOGE,
6570 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306571 ret = -EINVAL;
6572 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006573 }
6574#endif
6575
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306576 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6577 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006578 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306579 hddLog(LOGE,
6580 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306581 ret = -EINVAL;
6582 goto done;
6583 }
6584
6585 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
6586 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006587 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07006588 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006589
6590 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6591 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
6592 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6593 {
6594 hddLog(LOGE,
6595 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006596 ret = -EINVAL;
6597 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006598 }
6599
6600 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6601 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6602 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6603 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6604 ==eHAL_STATUS_FAILURE)
6605 {
6606 hddLog(LOGE,
6607 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006608 ret = -EINVAL;
6609 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006610 }
6611
6612 // Added for ProResp IE
6613 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
6614 {
6615 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
6616 u8 probe_rsp_ie_len[3] = {0};
6617 u8 counter = 0;
6618 /* Check Probe Resp Length if it is greater then 255 then Store
6619 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
6620 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
6621 Store More then 255 bytes into One Variable.
6622 */
6623 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6624 {
6625 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6626 {
6627 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6628 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6629 }
6630 else
6631 {
6632 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6633 rem_probe_resp_ie_len = 0;
6634 }
6635 }
6636
6637 rem_probe_resp_ie_len = 0;
6638
6639 if (probe_rsp_ie_len[0] > 0)
6640 {
6641 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6642 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6643 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6644 probe_rsp_ie_len[0], NULL,
6645 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6646 {
6647 hddLog(LOGE,
6648 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006649 ret = -EINVAL;
6650 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006651 }
6652 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6653 }
6654
6655 if (probe_rsp_ie_len[1] > 0)
6656 {
6657 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6658 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6659 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6660 probe_rsp_ie_len[1], NULL,
6661 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6662 {
6663 hddLog(LOGE,
6664 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006665 ret = -EINVAL;
6666 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006667 }
6668 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6669 }
6670
6671 if (probe_rsp_ie_len[2] > 0)
6672 {
6673 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6674 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6675 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6676 probe_rsp_ie_len[2], NULL,
6677 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6678 {
6679 hddLog(LOGE,
6680 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006681 ret = -EINVAL;
6682 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006683 }
6684 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6685 }
6686
6687 if (probe_rsp_ie_len[1] == 0 )
6688 {
6689 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6690 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6691 eANI_BOOLEAN_FALSE) )
6692 {
6693 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006694 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006695 }
6696 }
6697
6698 if (probe_rsp_ie_len[2] == 0 )
6699 {
6700 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6701 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6702 eANI_BOOLEAN_FALSE) )
6703 {
6704 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006705 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006706 }
6707 }
6708
6709 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6710 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6711 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6712 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6713 == eHAL_STATUS_FAILURE)
6714 {
6715 hddLog(LOGE,
6716 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006717 ret = -EINVAL;
6718 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006719 }
6720 }
6721 else
6722 {
6723 // Reset WNI_CFG_PROBE_RSP Flags
6724 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
6725
6726 hddLog(VOS_TRACE_LEVEL_INFO,
6727 "%s: No Probe Response IE received in set beacon",
6728 __func__);
6729 }
6730
6731 // Added for AssocResp IE
6732 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
6733 {
6734 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6735 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
6736 params->assocresp_ies_len, NULL,
6737 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6738 {
6739 hddLog(LOGE,
6740 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006741 ret = -EINVAL;
6742 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006743 }
6744
6745 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6746 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
6747 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6748 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6749 == eHAL_STATUS_FAILURE)
6750 {
6751 hddLog(LOGE,
6752 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006753 ret = -EINVAL;
6754 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006755 }
6756 }
6757 else
6758 {
6759 hddLog(VOS_TRACE_LEVEL_INFO,
6760 "%s: No Assoc Response IE received in set beacon",
6761 __func__);
6762
6763 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6764 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6765 eANI_BOOLEAN_FALSE) )
6766 {
6767 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006768 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006769 }
6770 }
6771
Jeff Johnsone7245742012-09-05 17:12:55 -07006772done:
Jeff Johnson295189b2012-06-20 16:38:30 -07006773 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306774 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006775}
Jeff Johnson295189b2012-06-20 16:38:30 -07006776
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306777/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006778 * FUNCTION: wlan_hdd_validate_operation_channel
6779 * called by wlan_hdd_cfg80211_start_bss() and
6780 * wlan_hdd_cfg80211_set_channel()
6781 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306782 * channel list.
6783 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006784VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006785{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306786
Jeff Johnson295189b2012-06-20 16:38:30 -07006787 v_U32_t num_ch = 0;
6788 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6789 u32 indx = 0;
6790 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306791 v_U8_t fValidChannel = FALSE, count = 0;
6792 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306793
Jeff Johnson295189b2012-06-20 16:38:30 -07006794 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6795
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306796 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006797 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306798 /* Validate the channel */
6799 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006800 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306801 if ( channel == rfChannels[count].channelNum )
6802 {
6803 fValidChannel = TRUE;
6804 break;
6805 }
6806 }
6807 if (fValidChannel != TRUE)
6808 {
6809 hddLog(VOS_TRACE_LEVEL_ERROR,
6810 "%s: Invalid Channel [%d]", __func__, channel);
6811 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006812 }
6813 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306814 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006815 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306816 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6817 valid_ch, &num_ch))
6818 {
6819 hddLog(VOS_TRACE_LEVEL_ERROR,
6820 "%s: failed to get valid channel list", __func__);
6821 return VOS_STATUS_E_FAILURE;
6822 }
6823 for (indx = 0; indx < num_ch; indx++)
6824 {
6825 if (channel == valid_ch[indx])
6826 {
6827 break;
6828 }
6829 }
6830
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306831 if (indx >= num_ch)
6832 {
6833 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6834 {
6835 eCsrBand band;
6836 unsigned int freq;
6837
6838 sme_GetFreqBand(hHal, &band);
6839
6840 if (eCSR_BAND_5G == band)
6841 {
6842#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6843 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6844 {
6845 freq = ieee80211_channel_to_frequency(channel,
6846 IEEE80211_BAND_2GHZ);
6847 }
6848 else
6849 {
6850 freq = ieee80211_channel_to_frequency(channel,
6851 IEEE80211_BAND_5GHZ);
6852 }
6853#else
6854 freq = ieee80211_channel_to_frequency(channel);
6855#endif
6856 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6857 return VOS_STATUS_SUCCESS;
6858 }
6859 }
6860
6861 hddLog(VOS_TRACE_LEVEL_ERROR,
6862 "%s: Invalid Channel [%d]", __func__, channel);
6863 return VOS_STATUS_E_FAILURE;
6864 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006865 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306866
Jeff Johnson295189b2012-06-20 16:38:30 -07006867 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306868
Jeff Johnson295189b2012-06-20 16:38:30 -07006869}
6870
Viral Modi3a32cc52013-02-08 11:14:52 -08006871/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306872 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08006873 * This function is used to set the channel number
6874 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306875static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08006876 struct ieee80211_channel *chan,
6877 enum nl80211_channel_type channel_type
6878 )
6879{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306880 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006881 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006882 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006883 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306884 hdd_context_t *pHddCtx;
6885 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006886
6887 ENTER();
6888
6889 if( NULL == dev )
6890 {
6891 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006892 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006893 return -ENODEV;
6894 }
6895 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306896
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306897 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6898 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6899 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006900 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306901 "%s: device_mode = %s (%d) freq = %d", __func__,
6902 hdd_device_modetoString(pAdapter->device_mode),
6903 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306904
6905 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6906 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306907 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006908 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306909 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006910 }
6911
6912 /*
6913 * Do freq to chan conversion
6914 * TODO: for 11a
6915 */
6916
6917 channel = ieee80211_frequency_to_channel(freq);
6918
6919 /* Check freq range */
6920 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6921 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6922 {
6923 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006924 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006925 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6926 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6927 return -EINVAL;
6928 }
6929
6930 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6931
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306932 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6933 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006934 {
6935 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6936 {
6937 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006938 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006939 return -EINVAL;
6940 }
6941 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6942 "%s: set channel to [%d] for device mode =%d",
6943 __func__, channel,pAdapter->device_mode);
6944 }
6945 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006946 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006947 )
6948 {
6949 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6950 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6951 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6952
6953 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6954 {
6955 /* Link is up then return cant set channel*/
6956 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006957 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006958 return -EINVAL;
6959 }
6960
6961 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6962 pHddStaCtx->conn_info.operationChannel = channel;
6963 pRoamProfile->ChannelInfo.ChannelList =
6964 &pHddStaCtx->conn_info.operationChannel;
6965 }
6966 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006967 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006968 )
6969 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306970 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6971 {
6972 if(VOS_STATUS_SUCCESS !=
6973 wlan_hdd_validate_operation_channel(pAdapter,channel))
6974 {
6975 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006976 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306977 return -EINVAL;
6978 }
6979 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6980 }
6981 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006982 {
6983 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6984
6985 /* If auto channel selection is configured as enable/ 1 then ignore
6986 channel set by supplicant
6987 */
6988 if ( cfg_param->apAutoChannelSelection )
6989 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306990 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6991 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006992 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306993 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6994 __func__, hdd_device_modetoString(pAdapter->device_mode),
6995 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006996 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306997 else
6998 {
6999 if(VOS_STATUS_SUCCESS !=
7000 wlan_hdd_validate_operation_channel(pAdapter,channel))
7001 {
7002 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007003 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307004 return -EINVAL;
7005 }
7006 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7007 }
Viral Modi3a32cc52013-02-08 11:14:52 -08007008 }
7009 }
7010 else
7011 {
7012 hddLog(VOS_TRACE_LEVEL_FATAL,
7013 "%s: Invalid device mode failed to set valid channel", __func__);
7014 return -EINVAL;
7015 }
7016 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307017 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007018}
7019
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307020static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
7021 struct net_device *dev,
7022 struct ieee80211_channel *chan,
7023 enum nl80211_channel_type channel_type
7024 )
7025{
7026 int ret;
7027
7028 vos_ssr_protect(__func__);
7029 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
7030 vos_ssr_unprotect(__func__);
7031
7032 return ret;
7033}
7034
Jeff Johnson295189b2012-06-20 16:38:30 -07007035#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7036static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7037 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007038#else
7039static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7040 struct cfg80211_beacon_data *params,
7041 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307042 enum nl80211_hidden_ssid hidden_ssid,
7043 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007044#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007045{
7046 tsap_Config_t *pConfig;
7047 beacon_data_t *pBeacon = NULL;
7048 struct ieee80211_mgmt *pMgmt_frame;
7049 v_U8_t *pIe=NULL;
7050 v_U16_t capab_info;
7051 eCsrAuthType RSNAuthType;
7052 eCsrEncryptionType RSNEncryptType;
7053 eCsrEncryptionType mcRSNEncryptType;
7054 int status = VOS_STATUS_SUCCESS;
7055 tpWLAN_SAPEventCB pSapEventCallback;
7056 hdd_hostapd_state_t *pHostapdState;
7057 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
7058 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307059 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007060 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307061 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07007062 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08007063 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05307064 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07007065 v_BOOL_t MFPCapable = VOS_FALSE;
7066 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307067 v_BOOL_t sapEnable11AC =
7068 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07007069 ENTER();
7070
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307071 iniConfig = pHddCtx->cfg_ini;
7072
Jeff Johnson295189b2012-06-20 16:38:30 -07007073 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7074
7075 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7076
7077 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7078
7079 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7080
7081 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7082
7083 //channel is already set in the set_channel Call back
7084 //pConfig->channel = pCommitConfig->channel;
7085
7086 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307087 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07007088 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
7089
7090 pConfig->dtim_period = pBeacon->dtim_period;
7091
Arif Hussain6d2a3322013-11-17 19:50:10 -08007092 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07007093 pConfig->dtim_period);
7094
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08007095 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07007096 {
7097 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007098 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05307099 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
7100 {
7101 tANI_BOOLEAN restartNeeded;
7102 pConfig->ieee80211d = 1;
7103 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
7104 sme_setRegInfo(hHal, pConfig->countryCode);
7105 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
7106 }
7107 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007108 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07007109 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07007110 pConfig->ieee80211d = 1;
7111 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
7112 sme_setRegInfo(hHal, pConfig->countryCode);
7113 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07007114 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007115 else
7116 {
7117 pConfig->ieee80211d = 0;
7118 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307119 /*
7120 * If auto channel is configured i.e. channel is 0,
7121 * so skip channel validation.
7122 */
7123 if( AUTO_CHANNEL_SELECT != pConfig->channel )
7124 {
7125 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
7126 {
7127 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007128 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307129 return -EINVAL;
7130 }
7131 }
7132 else
7133 {
7134 if(1 != pHddCtx->is_dynamic_channel_range_set)
7135 {
7136 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
7137 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
7138 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
7139 }
7140 pHddCtx->is_dynamic_channel_range_set = 0;
7141 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007142 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007143 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007144 {
7145 pConfig->ieee80211d = 0;
7146 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307147
7148#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7149 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7150 pConfig->authType = eSAP_OPEN_SYSTEM;
7151 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7152 pConfig->authType = eSAP_SHARED_KEY;
7153 else
7154 pConfig->authType = eSAP_AUTO_SWITCH;
7155#else
7156 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7157 pConfig->authType = eSAP_OPEN_SYSTEM;
7158 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7159 pConfig->authType = eSAP_SHARED_KEY;
7160 else
7161 pConfig->authType = eSAP_AUTO_SWITCH;
7162#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007163
7164 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307165
7166 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07007167 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
7168
7169 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7170
7171 /*Set wps station to configured*/
7172 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7173
7174 if(pIe)
7175 {
7176 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
7177 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007178 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07007179 return -EINVAL;
7180 }
7181 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
7182 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007183 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07007184 /* Check 15 bit of WPS IE as it contain information for wps state
7185 * WPS state
7186 */
7187 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
7188 {
7189 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
7190 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
7191 {
7192 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7193 }
7194 }
7195 }
7196 else
7197 {
7198 pConfig->wps_state = SAP_WPS_DISABLED;
7199 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307200 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07007201
c_hpothufe599e92014-06-16 11:38:55 +05307202 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7203 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7204 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7205 eCSR_ENCRYPT_TYPE_NONE;
7206
Jeff Johnson295189b2012-06-20 16:38:30 -07007207 pConfig->RSNWPAReqIELength = 0;
7208 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307209 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007210 WLAN_EID_RSN);
7211 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307212 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007213 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7214 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7215 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307216 /* The actual processing may eventually be more extensive than
7217 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07007218 * by the app.
7219 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307220 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007221 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7222 &RSNEncryptType,
7223 &mcRSNEncryptType,
7224 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007225 &MFPCapable,
7226 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007227 pConfig->pRSNWPAReqIE[1]+2,
7228 pConfig->pRSNWPAReqIE );
7229
7230 if( VOS_STATUS_SUCCESS == status )
7231 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307232 /* Now copy over all the security attributes you have
7233 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007234 * */
7235 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7236 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7237 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7238 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307239 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007240 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007241 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7242 }
7243 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307244
Jeff Johnson295189b2012-06-20 16:38:30 -07007245 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7246 pBeacon->tail, pBeacon->tail_len);
7247
7248 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
7249 {
7250 if (pConfig->pRSNWPAReqIE)
7251 {
7252 /*Mixed mode WPA/WPA2*/
7253 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
7254 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7255 }
7256 else
7257 {
7258 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7259 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7260 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307261 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007262 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7263 &RSNEncryptType,
7264 &mcRSNEncryptType,
7265 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007266 &MFPCapable,
7267 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007268 pConfig->pRSNWPAReqIE[1]+2,
7269 pConfig->pRSNWPAReqIE );
7270
7271 if( VOS_STATUS_SUCCESS == status )
7272 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307273 /* Now copy over all the security attributes you have
7274 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007275 * */
7276 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7277 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7278 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7279 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307280 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007281 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007282 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7283 }
7284 }
7285 }
7286
Jeff Johnson4416a782013-03-25 14:17:50 -07007287 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
7288 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
7289 return -EINVAL;
7290 }
7291
Jeff Johnson295189b2012-06-20 16:38:30 -07007292 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
7293
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007294#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007295 if (params->ssid != NULL)
7296 {
7297 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
7298 pConfig->SSIDinfo.ssid.length = params->ssid_len;
7299 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7300 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7301 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007302#else
7303 if (ssid != NULL)
7304 {
7305 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
7306 pConfig->SSIDinfo.ssid.length = ssid_len;
7307 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7308 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7309 }
7310#endif
7311
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307312 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07007313 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307314
Jeff Johnson295189b2012-06-20 16:38:30 -07007315 /* default value */
7316 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7317 pConfig->num_accept_mac = 0;
7318 pConfig->num_deny_mac = 0;
7319
7320 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7321 pBeacon->tail, pBeacon->tail_len);
7322
7323 /* pIe for black list is following form:
7324 type : 1 byte
7325 length : 1 byte
7326 OUI : 4 bytes
7327 acl type : 1 byte
7328 no of mac addr in black list: 1 byte
7329 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307330 */
7331 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007332 {
7333 pConfig->SapMacaddr_acl = pIe[6];
7334 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007335 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007336 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307337 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7338 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007339 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7340 for (i = 0; i < pConfig->num_deny_mac; i++)
7341 {
7342 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7343 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307344 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007345 }
7346 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7347 pBeacon->tail, pBeacon->tail_len);
7348
7349 /* pIe for white list is following form:
7350 type : 1 byte
7351 length : 1 byte
7352 OUI : 4 bytes
7353 acl type : 1 byte
7354 no of mac addr in white list: 1 byte
7355 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307356 */
7357 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007358 {
7359 pConfig->SapMacaddr_acl = pIe[6];
7360 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007361 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007362 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307363 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7364 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007365 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7366 for (i = 0; i < pConfig->num_accept_mac; i++)
7367 {
7368 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7369 acl_entry++;
7370 }
7371 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307372
Jeff Johnson295189b2012-06-20 16:38:30 -07007373 wlan_hdd_set_sapHwmode(pHostapdAdapter);
7374
Jeff Johnsone7245742012-09-05 17:12:55 -07007375#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007376 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307377 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
7378 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05307379 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
7380 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007381 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
7382 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307383 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
7384 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07007385 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307386 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07007387 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307388 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007389
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307390 /* If ACS disable and selected channel <= 14
7391 * OR
7392 * ACS enabled and ACS operating band is choosen as 2.4
7393 * AND
7394 * VHT in 2.4G Disabled
7395 * THEN
7396 * Fallback to 11N mode
7397 */
7398 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
7399 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05307400 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307401 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007402 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307403 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
7404 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007405 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
7406 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007407 }
7408#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307409
Jeff Johnson295189b2012-06-20 16:38:30 -07007410 // ht_capab is not what the name conveys,this is used for protection bitmap
7411 pConfig->ht_capab =
7412 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
7413
7414 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
7415 {
7416 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7417 return -EINVAL;
7418 }
7419
7420 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307421 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07007422 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
7423 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307424 pConfig->obssProtEnabled =
7425 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07007426
Chet Lanctot8cecea22014-02-11 19:09:36 -08007427#ifdef WLAN_FEATURE_11W
7428 pConfig->mfpCapable = MFPCapable;
7429 pConfig->mfpRequired = MFPRequired;
7430 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
7431 pConfig->mfpCapable, pConfig->mfpRequired);
7432#endif
7433
Arif Hussain6d2a3322013-11-17 19:50:10 -08007434 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07007435 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007436 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
7437 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7438 (int)pConfig->channel);
7439 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
7440 pConfig->SapHw_mode, pConfig->privacy,
7441 pConfig->authType);
7442 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
7443 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7444 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7445 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07007446
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307447 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007448 {
7449 //Bss already started. just return.
7450 //TODO Probably it should update some beacon params.
7451 hddLog( LOGE, "Bss Already started...Ignore the request");
7452 EXIT();
7453 return 0;
7454 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307455
Agarwal Ashish51325b52014-06-16 16:50:49 +05307456 if (vos_max_concurrent_connections_reached()) {
7457 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7458 return -EINVAL;
7459 }
7460
Jeff Johnson295189b2012-06-20 16:38:30 -07007461 pConfig->persona = pHostapdAdapter->device_mode;
7462
Peng Xu2446a892014-09-05 17:21:18 +05307463 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
7464 if ( NULL != psmeConfig)
7465 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307466 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05307467 sme_GetConfigParam(hHal, psmeConfig);
7468 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307469#ifdef WLAN_FEATURE_AP_HT40_24G
7470 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7471 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
7472 && pHddCtx->cfg_ini->apHT40_24GEnabled)
7473 {
7474 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
7475 sme_UpdateConfig (hHal, psmeConfig);
7476 }
7477#endif
Peng Xu2446a892014-09-05 17:21:18 +05307478 vos_mem_free(psmeConfig);
7479 }
Peng Xuafc34e32014-09-25 13:23:55 +05307480 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05307481
Jeff Johnson295189b2012-06-20 16:38:30 -07007482 pSapEventCallback = hdd_hostapd_SAPEventCB;
7483 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
7484 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
7485 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007486 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007487 return -EINVAL;
7488 }
7489
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307490 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07007491 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7492
7493 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307494
Jeff Johnson295189b2012-06-20 16:38:30 -07007495 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307496 {
7497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007498 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07007499 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07007500 VOS_ASSERT(0);
7501 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307502
Jeff Johnson295189b2012-06-20 16:38:30 -07007503 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05307504 /* Initialize WMM configuation */
7505 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307506 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007507
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007508#ifdef WLAN_FEATURE_P2P_DEBUG
7509 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
7510 {
7511 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
7512 {
7513 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7514 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007515 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007516 }
7517 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
7518 {
7519 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7520 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007521 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007522 }
7523 }
7524#endif
7525
Jeff Johnson295189b2012-06-20 16:38:30 -07007526 pHostapdState->bCommit = TRUE;
7527 EXIT();
7528
7529 return 0;
7530}
7531
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007532#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307533static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307534 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007535 struct beacon_parameters *params)
7536{
7537 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307538 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307539 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007540
7541 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307542
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307543 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7544 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
7545 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307546 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
7547 hdd_device_modetoString(pAdapter->device_mode),
7548 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007549
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307550 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7551 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307552 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007553 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307554 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007555 }
7556
Agarwal Ashish51325b52014-06-16 16:50:49 +05307557 if (vos_max_concurrent_connections_reached()) {
7558 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7559 return -EINVAL;
7560 }
7561
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307562 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007563 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007564 )
7565 {
7566 beacon_data_t *old,*new;
7567
7568 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307569
Jeff Johnson295189b2012-06-20 16:38:30 -07007570 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307571 {
7572 hddLog(VOS_TRACE_LEVEL_WARN,
7573 FL("already beacon info added to session(%d)"),
7574 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007575 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307576 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007577
7578 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7579
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307580 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07007581 {
7582 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007583 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007584 return -EINVAL;
7585 }
7586
7587 pAdapter->sessionCtx.ap.beacon = new;
7588
7589 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7590 }
7591
7592 EXIT();
7593 return status;
7594}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307595
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307596static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
7597 struct net_device *dev,
7598 struct beacon_parameters *params)
7599{
7600 int ret;
7601
7602 vos_ssr_protect(__func__);
7603 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
7604 vos_ssr_unprotect(__func__);
7605
7606 return ret;
7607}
7608
7609static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007610 struct net_device *dev,
7611 struct beacon_parameters *params)
7612{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307613 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307614 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7615 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307616 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007617
7618 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307619
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307620 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7621 TRACE_CODE_HDD_CFG80211_SET_BEACON,
7622 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
7623 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7624 __func__, hdd_device_modetoString(pAdapter->device_mode),
7625 pAdapter->device_mode);
7626
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307627 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7628 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307629 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007630 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307631 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007632 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307633
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307634 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007635 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307636 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007637 {
7638 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307639
Jeff Johnson295189b2012-06-20 16:38:30 -07007640 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307641
Jeff Johnson295189b2012-06-20 16:38:30 -07007642 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307643 {
7644 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7645 FL("session(%d) old and new heads points to NULL"),
7646 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007647 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307648 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007649
7650 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7651
7652 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307653 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007654 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007655 return -EINVAL;
7656 }
7657
7658 pAdapter->sessionCtx.ap.beacon = new;
7659
7660 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7661 }
7662
7663 EXIT();
7664 return status;
7665}
7666
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307667static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
7668 struct net_device *dev,
7669 struct beacon_parameters *params)
7670{
7671 int ret;
7672
7673 vos_ssr_protect(__func__);
7674 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
7675 vos_ssr_unprotect(__func__);
7676
7677 return ret;
7678}
7679
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007680#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7681
7682#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307683static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007684 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007685#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307686static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007687 struct net_device *dev)
7688#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007689{
7690 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07007691 hdd_context_t *pHddCtx = NULL;
7692 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307693 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307694 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007695
7696 ENTER();
7697
7698 if (NULL == pAdapter)
7699 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007701 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007702 return -ENODEV;
7703 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007704
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307705 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7706 TRACE_CODE_HDD_CFG80211_STOP_AP,
7707 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307708 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7709 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307710 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007711 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307712 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07007713 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007714
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007715 pScanInfo = &pHddCtx->scan_info;
7716
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307717 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7718 __func__, hdd_device_modetoString(pAdapter->device_mode),
7719 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007720
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307721 ret = wlan_hdd_scan_abort(pAdapter);
7722
Girish Gowli4bf7a632014-06-12 13:42:11 +05307723 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07007724 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7726 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307727
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307728 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07007729 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7731 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08007732
Jeff Johnsone7245742012-09-05 17:12:55 -07007733 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307734 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07007735 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307736 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07007737 }
7738
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05307739 /* Delete all associated STAs before stopping AP/P2P GO */
7740 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05307741 hdd_hostapd_stop(dev);
7742
Jeff Johnson295189b2012-06-20 16:38:30 -07007743 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007744 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007745 )
7746 {
7747 beacon_data_t *old;
7748
7749 old = pAdapter->sessionCtx.ap.beacon;
7750
7751 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307752 {
7753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7754 FL("session(%d) beacon data points to NULL"),
7755 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007756 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307757 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007758
Jeff Johnson295189b2012-06-20 16:38:30 -07007759 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007760
7761 mutex_lock(&pHddCtx->sap_lock);
7762 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7763 {
Jeff Johnson4416a782013-03-25 14:17:50 -07007764 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007765 {
7766 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7767
7768 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7769
7770 if (!VOS_IS_STATUS_SUCCESS(status))
7771 {
7772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007773 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007774 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307775 }
7776 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007777 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307778 /* BSS stopped, clear the active sessions for this device mode */
7779 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007780 }
7781 mutex_unlock(&pHddCtx->sap_lock);
7782
7783 if(status != VOS_STATUS_SUCCESS)
7784 {
7785 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007786 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007787 return -EINVAL;
7788 }
7789
Jeff Johnson4416a782013-03-25 14:17:50 -07007790 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007791 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
7792 ==eHAL_STATUS_FAILURE)
7793 {
7794 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007795 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007796 }
7797
Jeff Johnson4416a782013-03-25 14:17:50 -07007798 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007799 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7800 eANI_BOOLEAN_FALSE) )
7801 {
7802 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007803 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007804 }
7805
7806 // Reset WNI_CFG_PROBE_RSP Flags
7807 wlan_hdd_reset_prob_rspies(pAdapter);
7808
7809 pAdapter->sessionCtx.ap.beacon = NULL;
7810 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007811#ifdef WLAN_FEATURE_P2P_DEBUG
7812 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7813 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
7814 {
7815 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
7816 "GO got removed");
7817 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
7818 }
7819#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007820 }
7821 EXIT();
7822 return status;
7823}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007824
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307825#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7826static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
7827 struct net_device *dev)
7828{
7829 int ret;
7830
7831 vos_ssr_protect(__func__);
7832 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
7833 vos_ssr_unprotect(__func__);
7834
7835 return ret;
7836}
7837#else
7838static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7839 struct net_device *dev)
7840{
7841 int ret;
7842
7843 vos_ssr_protect(__func__);
7844 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7845 vos_ssr_unprotect(__func__);
7846
7847 return ret;
7848}
7849#endif
7850
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007851#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7852
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307853static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307854 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007855 struct cfg80211_ap_settings *params)
7856{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307857 hdd_adapter_t *pAdapter;
7858 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307859 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007860
7861 ENTER();
7862
Girish Gowlib143d7a2015-02-18 19:39:55 +05307863 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007864 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05307866 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307867 return -ENODEV;
7868 }
7869
7870 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7871 if (NULL == pAdapter)
7872 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307874 "%s: HDD adapter is Null", __func__);
7875 return -ENODEV;
7876 }
7877
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307878 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7879 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
7880 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307881 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7882 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307884 "%s: HDD adapter magic is invalid", __func__);
7885 return -ENODEV;
7886 }
7887
7888 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307889 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307890 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307891 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307892 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307893 }
7894
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307895 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7896 __func__, hdd_device_modetoString(pAdapter->device_mode),
7897 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307898
7899 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007900 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007901 )
7902 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307903 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007904
7905 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307906
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007907 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307908 {
7909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7910 FL("already beacon info added to session(%d)"),
7911 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007912 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307913 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007914
Girish Gowlib143d7a2015-02-18 19:39:55 +05307915#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7916 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7917 &new,
7918 &params->beacon);
7919#else
7920 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7921 &new,
7922 &params->beacon,
7923 params->dtim_period);
7924#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007925
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307926 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007927 {
7928 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307929 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007930 return -EINVAL;
7931 }
7932 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007933#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007934 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7935#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7936 params->channel, params->channel_type);
7937#else
7938 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7939#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007940#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007941 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307942 params->ssid_len, params->hidden_ssid,
7943 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007944 }
7945
7946 EXIT();
7947 return status;
7948}
7949
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307950static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7951 struct net_device *dev,
7952 struct cfg80211_ap_settings *params)
7953{
7954 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007955
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307956 vos_ssr_protect(__func__);
7957 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
7958 vos_ssr_unprotect(__func__);
7959
7960 return ret;
7961}
7962
7963static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007964 struct net_device *dev,
7965 struct cfg80211_beacon_data *params)
7966{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307967 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307968 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307969 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007970
7971 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307972
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307973 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7974 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7975 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007976 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007977 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307978
7979 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7980 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307981 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007982 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307983 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007984 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007985
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307986 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007987 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307988 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007989 {
7990 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307991
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007992 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307993
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007994 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307995 {
7996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7997 FL("session(%d) beacon data points to NULL"),
7998 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007999 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308000 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008001
8002 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
8003
8004 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308005 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008006 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008007 return -EINVAL;
8008 }
8009
8010 pAdapter->sessionCtx.ap.beacon = new;
8011
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308012 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
8013 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008014 }
8015
8016 EXIT();
8017 return status;
8018}
8019
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308020static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8021 struct net_device *dev,
8022 struct cfg80211_beacon_data *params)
8023{
8024 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008025
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308026 vos_ssr_protect(__func__);
8027 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8028 vos_ssr_unprotect(__func__);
8029
8030 return ret;
8031}
8032
8033#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008034
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308035static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008036 struct net_device *dev,
8037 struct bss_parameters *params)
8038{
8039 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308040 hdd_context_t *pHddCtx;
8041 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008042
8043 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308044
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308045 if (NULL == pAdapter)
8046 {
8047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8048 "%s: HDD adapter is Null", __func__);
8049 return -ENODEV;
8050 }
8051 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308052 ret = wlan_hdd_validate_context(pHddCtx);
8053 if (0 != ret)
8054 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308055 return ret;
8056 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308057 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8058 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
8059 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308060 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8061 __func__, hdd_device_modetoString(pAdapter->device_mode),
8062 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008063
8064 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008065 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308066 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008067 {
8068 /* ap_isolate == -1 means that in change bss, upper layer doesn't
8069 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308070 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07008071 {
8072 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308073 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008074 }
8075
8076 EXIT();
8077 return 0;
8078}
8079
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308080static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
8081 struct net_device *dev,
8082 struct bss_parameters *params)
8083{
8084 int ret;
8085
8086 vos_ssr_protect(__func__);
8087 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
8088 vos_ssr_unprotect(__func__);
8089
8090 return ret;
8091}
Kiet Lam10841362013-11-01 11:36:50 +05308092/* FUNCTION: wlan_hdd_change_country_code_cd
8093* to wait for contry code completion
8094*/
8095void* wlan_hdd_change_country_code_cb(void *pAdapter)
8096{
8097 hdd_adapter_t *call_back_pAdapter = pAdapter;
8098 complete(&call_back_pAdapter->change_country_code);
8099 return NULL;
8100}
8101
Jeff Johnson295189b2012-06-20 16:38:30 -07008102/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308103 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07008104 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
8105 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308106int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008107 struct net_device *ndev,
8108 enum nl80211_iftype type,
8109 u32 *flags,
8110 struct vif_params *params
8111 )
8112{
8113 struct wireless_dev *wdev;
8114 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008115 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07008116 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008117 tCsrRoamProfile *pRoamProfile = NULL;
8118 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308119 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008120 eMib_dot11DesiredBssType connectedBssType;
8121 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308122 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008123
8124 ENTER();
8125
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308126 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008127 {
8128 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8129 "%s: Adapter context is null", __func__);
8130 return VOS_STATUS_E_FAILURE;
8131 }
8132
8133 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8134 if (!pHddCtx)
8135 {
8136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8137 "%s: HDD context is null", __func__);
8138 return VOS_STATUS_E_FAILURE;
8139 }
8140
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308141 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8142 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
8143 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308144 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308145 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07008146 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308147 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008148 }
8149
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308150 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8151 __func__, hdd_device_modetoString(pAdapter->device_mode),
8152 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008153
Agarwal Ashish51325b52014-06-16 16:50:49 +05308154 if (vos_max_concurrent_connections_reached()) {
8155 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8156 return -EINVAL;
8157 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308158 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07008159 wdev = ndev->ieee80211_ptr;
8160
8161#ifdef WLAN_BTAMP_FEATURE
8162 if((NL80211_IFTYPE_P2P_CLIENT == type)||
8163 (NL80211_IFTYPE_ADHOC == type)||
8164 (NL80211_IFTYPE_AP == type)||
8165 (NL80211_IFTYPE_P2P_GO == type))
8166 {
8167 pHddCtx->isAmpAllowed = VOS_FALSE;
8168 // stop AMP traffic
8169 status = WLANBAP_StopAmp();
8170 if(VOS_STATUS_SUCCESS != status )
8171 {
8172 pHddCtx->isAmpAllowed = VOS_TRUE;
8173 hddLog(VOS_TRACE_LEVEL_FATAL,
8174 "%s: Failed to stop AMP", __func__);
8175 return -EINVAL;
8176 }
8177 }
8178#endif //WLAN_BTAMP_FEATURE
8179 /* Reset the current device mode bit mask*/
8180 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8181
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +05308182 /* Notify Mode change in case of concurrency.
8183 * Below function invokes TDLS teardown Functionality Since TDLS is
8184 * not Supported in case of concurrency i.e Once P2P session
8185 * is detected disable offchannel and teardown TDLS links
8186 */
8187 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
8188
Jeff Johnson295189b2012-06-20 16:38:30 -07008189 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008190 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07008191 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008192 )
8193 {
8194 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008195 if (!pWextState)
8196 {
8197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8198 "%s: pWextState is null", __func__);
8199 return VOS_STATUS_E_FAILURE;
8200 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008201 pRoamProfile = &pWextState->roamProfile;
8202 LastBSSType = pRoamProfile->BSSType;
8203
8204 switch (type)
8205 {
8206 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008207 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008208 hddLog(VOS_TRACE_LEVEL_INFO,
8209 "%s: setting interface Type to INFRASTRUCTURE", __func__);
8210 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008211#ifdef WLAN_FEATURE_11AC
8212 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
8213 {
8214 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
8215 }
8216#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308217 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07008218 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008219 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008220 //Check for sub-string p2p to confirm its a p2p interface
8221 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308222 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008223 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8224 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8225 }
8226 else
8227 {
8228 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008229 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008230 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008231 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05308232
Jeff Johnson295189b2012-06-20 16:38:30 -07008233 case NL80211_IFTYPE_ADHOC:
8234 hddLog(VOS_TRACE_LEVEL_INFO,
8235 "%s: setting interface Type to ADHOC", __func__);
8236 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
8237 pRoamProfile->phyMode =
8238 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07008239 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008240 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05308241 hdd_set_ibss_ops( pAdapter );
8242 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +05308243
8244 status = hdd_sta_id_hash_attach(pAdapter);
8245 if (VOS_STATUS_SUCCESS != status) {
8246 hddLog(VOS_TRACE_LEVEL_ERROR,
8247 FL("Failed to initialize hash for IBSS"));
8248 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008249 break;
8250
8251 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008252 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008253 {
8254 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8255 "%s: setting interface Type to %s", __func__,
8256 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
8257
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008258 //Cancel any remain on channel for GO mode
8259 if (NL80211_IFTYPE_P2P_GO == type)
8260 {
8261 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
8262 }
Mohit Khanna0f232092012-09-11 14:46:08 -07008263 if (NL80211_IFTYPE_AP == type)
8264 {
8265 /* As Loading WLAN Driver one interface being created for p2p device
8266 * address. This will take one HW STA and the max number of clients
8267 * that can connect to softAP will be reduced by one. so while changing
8268 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
8269 * interface as it is not required in SoftAP mode.
8270 */
8271
8272 // Get P2P Adapter
8273 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
8274
8275 if (pP2pAdapter)
8276 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308277 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05308278 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07008279 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
8280 }
8281 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05308282 //Disable IMPS & BMPS for SAP/GO
8283 if(VOS_STATUS_E_FAILURE ==
8284 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
8285 {
8286 //Fail to Exit BMPS
8287 VOS_ASSERT(0);
8288 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05308289
8290 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
8291
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308292#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07008293
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308294 /* A Mutex Lock is introduced while changing the mode to
8295 * protect the concurrent access for the Adapters by TDLS
8296 * module.
8297 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308298 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308299#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008300 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05308301 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008302 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07008303 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8304 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308305#ifdef FEATURE_WLAN_TDLS
8306 mutex_unlock(&pHddCtx->tdls_lock);
8307#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008308 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
8309 (pConfig->apRandomBssidEnabled))
8310 {
8311 /* To meet Android requirements create a randomized
8312 MAC address of the form 02:1A:11:Fx:xx:xx */
8313 get_random_bytes(&ndev->dev_addr[3], 3);
8314 ndev->dev_addr[0] = 0x02;
8315 ndev->dev_addr[1] = 0x1A;
8316 ndev->dev_addr[2] = 0x11;
8317 ndev->dev_addr[3] |= 0xF0;
8318 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
8319 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08008320 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
8321 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008322 }
8323
Jeff Johnson295189b2012-06-20 16:38:30 -07008324 hdd_set_ap_ops( pAdapter->dev );
8325
Kiet Lam10841362013-11-01 11:36:50 +05308326 /* This is for only SAP mode where users can
8327 * control country through ini.
8328 * P2P GO follows station country code
8329 * acquired during the STA scanning. */
8330 if((NL80211_IFTYPE_AP == type) &&
8331 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
8332 {
8333 int status = 0;
8334 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
8335 "%s: setting country code from INI ", __func__);
8336 init_completion(&pAdapter->change_country_code);
8337 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
8338 (void *)(tSmeChangeCountryCallback)
8339 wlan_hdd_change_country_code_cb,
8340 pConfig->apCntryCode, pAdapter,
8341 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308342 eSIR_FALSE,
8343 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05308344 if (eHAL_STATUS_SUCCESS == status)
8345 {
8346 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308347 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05308348 &pAdapter->change_country_code,
8349 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308350 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05308351 {
8352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308353 FL("SME Timed out while setting country code %ld"),
8354 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08008355
8356 if (pHddCtx->isLogpInProgress)
8357 {
8358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8359 "%s: LOGP in Progress. Ignore!!!", __func__);
8360 return -EAGAIN;
8361 }
Kiet Lam10841362013-11-01 11:36:50 +05308362 }
8363 }
8364 else
8365 {
8366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008367 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05308368 return -EINVAL;
8369 }
8370 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008371 status = hdd_init_ap_mode(pAdapter);
8372 if(status != VOS_STATUS_SUCCESS)
8373 {
8374 hddLog(VOS_TRACE_LEVEL_FATAL,
8375 "%s: Error initializing the ap mode", __func__);
8376 return -EINVAL;
8377 }
8378 hdd_set_conparam(1);
8379
Nirav Shah7e3c8132015-06-22 23:51:42 +05308380 status = hdd_sta_id_hash_attach(pAdapter);
8381 if (VOS_STATUS_SUCCESS != status)
8382 {
8383 hddLog(VOS_TRACE_LEVEL_ERROR,
8384 FL("Failed to initialize hash for AP"));
8385 return -EINVAL;
8386 }
8387
Jeff Johnson295189b2012-06-20 16:38:30 -07008388 /*interface type changed update in wiphy structure*/
8389 if(wdev)
8390 {
8391 wdev->iftype = type;
8392 pHddCtx->change_iface = type;
8393 }
8394 else
8395 {
8396 hddLog(VOS_TRACE_LEVEL_ERROR,
8397 "%s: ERROR !!!! Wireless dev is NULL", __func__);
8398 return -EINVAL;
8399 }
8400 goto done;
8401 }
8402
8403 default:
8404 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8405 __func__);
8406 return -EOPNOTSUPP;
8407 }
8408 }
8409 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008410 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008411 )
8412 {
8413 switch(type)
8414 {
8415 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008416 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008417 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05308418
8419 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308420#ifdef FEATURE_WLAN_TDLS
8421
8422 /* A Mutex Lock is introduced while changing the mode to
8423 * protect the concurrent access for the Adapters by TDLS
8424 * module.
8425 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308426 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308427#endif
c_hpothu002231a2015-02-05 14:58:51 +05308428 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008429 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008430 //Check for sub-string p2p to confirm its a p2p interface
8431 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008432 {
8433 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8434 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8435 }
8436 else
8437 {
8438 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008439 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008440 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008441 hdd_set_conparam(0);
8442 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008443 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
8444 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308445#ifdef FEATURE_WLAN_TDLS
8446 mutex_unlock(&pHddCtx->tdls_lock);
8447#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308448 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008449 if( VOS_STATUS_SUCCESS != status )
8450 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07008451 /* In case of JB, for P2P-GO, only change interface will be called,
8452 * This is the right place to enable back bmps_imps()
8453 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308454 if (pHddCtx->hdd_wlan_suspended)
8455 {
8456 hdd_set_pwrparams(pHddCtx);
8457 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008458 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008459 goto done;
8460 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008461 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008462 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008463 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8464 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008465 goto done;
8466 default:
8467 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8468 __func__);
8469 return -EOPNOTSUPP;
8470
8471 }
8472
8473 }
8474 else
8475 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308476 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
8477 __func__, hdd_device_modetoString(pAdapter->device_mode),
8478 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008479 return -EOPNOTSUPP;
8480 }
8481
8482
8483 if(pRoamProfile)
8484 {
8485 if ( LastBSSType != pRoamProfile->BSSType )
8486 {
8487 /*interface type changed update in wiphy structure*/
8488 wdev->iftype = type;
8489
8490 /*the BSS mode changed, We need to issue disconnect
8491 if connected or in IBSS disconnect state*/
8492 if ( hdd_connGetConnectedBssType(
8493 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
8494 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
8495 {
8496 /*need to issue a disconnect to CSR.*/
8497 INIT_COMPLETION(pAdapter->disconnect_comp_var);
8498 if( eHAL_STATUS_SUCCESS ==
8499 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
8500 pAdapter->sessionId,
8501 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
8502 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308503 ret = wait_for_completion_interruptible_timeout(
8504 &pAdapter->disconnect_comp_var,
8505 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
8506 if (ret <= 0)
8507 {
8508 hddLog(VOS_TRACE_LEVEL_ERROR,
8509 FL("wait on disconnect_comp_var failed %ld"), ret);
8510 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008511 }
8512 }
8513 }
8514 }
8515
8516done:
8517 /*set bitmask based on updated value*/
8518 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07008519
8520 /* Only STA mode support TM now
8521 * all other mode, TM feature should be disabled */
8522 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
8523 (~VOS_STA & pHddCtx->concurrency_mode) )
8524 {
8525 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
8526 }
8527
Jeff Johnson295189b2012-06-20 16:38:30 -07008528#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308529 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05308530 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07008531 {
8532 //we are ok to do AMP
8533 pHddCtx->isAmpAllowed = VOS_TRUE;
8534 }
8535#endif //WLAN_BTAMP_FEATURE
8536 EXIT();
8537 return 0;
8538}
8539
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308540/*
8541 * FUNCTION: wlan_hdd_cfg80211_change_iface
8542 * wrapper function to protect the actual implementation from SSR.
8543 */
8544int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
8545 struct net_device *ndev,
8546 enum nl80211_iftype type,
8547 u32 *flags,
8548 struct vif_params *params
8549 )
8550{
8551 int ret;
8552
8553 vos_ssr_protect(__func__);
8554 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
8555 vos_ssr_unprotect(__func__);
8556
8557 return ret;
8558}
8559
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008560#ifdef FEATURE_WLAN_TDLS
8561static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308562 struct net_device *dev,
8563#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
8564 const u8 *mac,
8565#else
8566 u8 *mac,
8567#endif
8568 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008569{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008570 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008571 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308572 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308573 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308574 hdd_adapter_t *pAdapter;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008575
8576 ENTER();
8577
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308578 if (!dev) {
8579 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
8580 return -EINVAL;
8581 }
8582
8583 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8584 if (!pAdapter) {
8585 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
8586 return -EINVAL;
8587 }
8588
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308589 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008590 {
8591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8592 "Invalid arguments");
8593 return -EINVAL;
8594 }
Hoonki Lee27511902013-03-14 18:19:06 -07008595
8596 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
8597 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
8598 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07008600 "%s: TDLS mode is disabled OR not enabled in FW."
8601 MAC_ADDRESS_STR " Request declined.",
8602 __func__, MAC_ADDR_ARRAY(mac));
8603 return -ENOTSUPP;
8604 }
8605
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008606 if (pHddCtx->isLogpInProgress)
8607 {
8608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8609 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05308610 wlan_hdd_tdls_set_link_status(pAdapter,
8611 mac,
8612 eTDLS_LINK_IDLE,
8613 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008614 return -EBUSY;
8615 }
8616
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308617 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05308618 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008619
8620 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008622 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
8623 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308624 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008625 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008626 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308627 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008628
8629 /* in add station, we accept existing valid staId if there is */
8630 if ((0 == update) &&
8631 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
8632 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008633 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008635 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008636 " link_status %d. staId %d. add station ignored.",
8637 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
8638 return 0;
8639 }
8640 /* in change station, we accept only when staId is valid */
8641 if ((1 == update) &&
8642 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
8643 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
8644 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008646 "%s: " MAC_ADDRESS_STR
8647 " link status %d. staId %d. change station %s.",
8648 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
8649 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
8650 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008651 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008652
8653 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05308654 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008655 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8657 "%s: " MAC_ADDRESS_STR
8658 " TDLS setup is ongoing. Request declined.",
8659 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07008660 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008661 }
8662
8663 /* first to check if we reached to maximum supported TDLS peer.
8664 TODO: for now, return -EPERM looks working fine,
8665 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308666 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8667 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008668 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008669 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8670 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308671 " TDLS Max peer already connected. Request declined."
8672 " Num of peers (%d), Max allowed (%d).",
8673 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
8674 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008675 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008676 }
8677 else
8678 {
8679 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308680 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008681 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008682 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008683 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8684 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
8685 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008686 return -EPERM;
8687 }
8688 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008689 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05308690 wlan_hdd_tdls_set_link_status(pAdapter,
8691 mac,
8692 eTDLS_LINK_CONNECTING,
8693 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008694
Jeff Johnsond75fe012013-04-06 10:53:06 -07008695 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308696 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008697 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008699 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008700 if(StaParams->htcap_present)
8701 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008703 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008705 "ht_capa->extended_capabilities: %0x",
8706 StaParams->HTCap.extendedHtCapInfo);
8707 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008709 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308710 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008711 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008712 if(StaParams->vhtcap_present)
8713 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008715 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
8716 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
8717 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
8718 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008719 {
8720 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008722 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008724 "[%d]: %x ", i, StaParams->supported_rates[i]);
8725 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07008726 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308727 else if ((1 == update) && (NULL == StaParams))
8728 {
8729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8730 "%s : update is true, but staParams is NULL. Error!", __func__);
8731 return -EPERM;
8732 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008733
8734 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
8735
8736 if (!update)
8737 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308738 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008739 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308740 if (ret != eHAL_STATUS_SUCCESS) {
8741 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to add TDLS peer STA"));
8742 return -EPERM;
8743 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008744 }
8745 else
8746 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308747 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008748 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308749 if (ret != eHAL_STATUS_SUCCESS) {
8750 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
8751 return -EPERM;
8752 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008753 }
8754
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308755 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008756 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
8757
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308758 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008759 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008760 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308761 "%s: timeout waiting for tdls add station indication %ld",
8762 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008763 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008764 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308765
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008766 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
8767 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008769 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008770 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008771 }
8772
8773 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008774
8775error:
Atul Mittal115287b2014-07-08 13:26:33 +05308776 wlan_hdd_tdls_set_link_status(pAdapter,
8777 mac,
8778 eTDLS_LINK_IDLE,
8779 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008780 return -EPERM;
8781
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008782}
8783#endif
8784
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308785static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008786 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308787#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
8788 const u8 *mac,
8789#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008790 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308791#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008792 struct station_parameters *params)
8793{
8794 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308795 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308796 hdd_context_t *pHddCtx;
8797 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008798 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308799 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008800#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008801 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008802 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308803 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008804#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008805
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308806 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308807
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308808 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308809 if ((NULL == pAdapter))
8810 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308811 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308812 "invalid adapter ");
8813 return -EINVAL;
8814 }
8815
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308816 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8817 TRACE_CODE_HDD_CHANGE_STATION,
8818 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05308819 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308820
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308821 ret = wlan_hdd_validate_context(pHddCtx);
8822 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05308823 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308824 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308825 }
8826
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308827 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8828
8829 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008830 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308831 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8832 "invalid HDD station context");
8833 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008834 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008835 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
8836
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008837 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8838 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07008839 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008840 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07008841 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308842 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07008843 WLANTL_STA_AUTHENTICATED);
8844
Gopichand Nakkala29149562013-05-10 21:43:41 +05308845 if (status != VOS_STATUS_SUCCESS)
8846 {
8847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8848 "%s: Not able to change TL state to AUTHENTICATED", __func__);
8849 return -EINVAL;
8850 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008851 }
8852 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07008853 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8854 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308855#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008856 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8857 StaParams.capability = params->capability;
8858 StaParams.uapsd_queues = params->uapsd_queues;
8859 StaParams.max_sp = params->max_sp;
8860
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308861 /* Convert (first channel , number of channels) tuple to
8862 * the total list of channels. This goes with the assumption
8863 * that if the first channel is < 14, then the next channels
8864 * are an incremental of 1 else an incremental of 4 till the number
8865 * of channels.
8866 */
8867 if (0 != params->supported_channels_len) {
8868 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
8869 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
8870 {
8871 int wifi_chan_index;
8872 StaParams.supported_channels[j] = params->supported_channels[i];
8873 wifi_chan_index =
8874 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
8875 no_of_channels = params->supported_channels[i+1];
8876 for(k=1; k <= no_of_channels; k++)
8877 {
8878 StaParams.supported_channels[j+1] =
8879 StaParams.supported_channels[j] + wifi_chan_index;
8880 j+=1;
8881 }
8882 }
8883 StaParams.supported_channels_len = j;
8884 }
8885 vos_mem_copy(StaParams.supported_oper_classes,
8886 params->supported_oper_classes,
8887 params->supported_oper_classes_len);
8888 StaParams.supported_oper_classes_len =
8889 params->supported_oper_classes_len;
8890
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008891 if (0 != params->ext_capab_len)
8892 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
8893 sizeof(StaParams.extn_capability));
8894
8895 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008896 {
8897 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008898 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008899 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008900
8901 StaParams.supported_rates_len = params->supported_rates_len;
8902
8903 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
8904 * The supported_rates array , for all the structures propogating till Add Sta
8905 * to the firmware has to be modified , if the supplicant (ieee80211) is
8906 * modified to send more rates.
8907 */
8908
8909 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
8910 */
8911 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
8912 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
8913
8914 if (0 != StaParams.supported_rates_len) {
8915 int i = 0;
8916 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
8917 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008919 "Supported Rates with Length %d", StaParams.supported_rates_len);
8920 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008922 "[%d]: %0x", i, StaParams.supported_rates[i]);
8923 }
8924
8925 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008926 {
8927 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008928 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008929 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008930
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008931 if (0 != params->ext_capab_len ) {
8932 /*Define A Macro : TODO Sunil*/
8933 if ((1<<4) & StaParams.extn_capability[3]) {
8934 isBufSta = 1;
8935 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308936 /* TDLS Channel Switching Support */
8937 if ((1<<6) & StaParams.extn_capability[3]) {
8938 isOffChannelSupported = 1;
8939 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008940 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308941 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
8942 &StaParams, isBufSta,
8943 isOffChannelSupported);
8944
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308945 if (VOS_STATUS_SUCCESS != status) {
8946 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8947 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
8948 return -EINVAL;
8949 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008950 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
8951
8952 if (VOS_STATUS_SUCCESS != status) {
8953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8954 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
8955 return -EINVAL;
8956 }
8957 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008958#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05308959 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008960 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008961 return status;
8962}
8963
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308964#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
8965static int wlan_hdd_change_station(struct wiphy *wiphy,
8966 struct net_device *dev,
8967 const u8 *mac,
8968 struct station_parameters *params)
8969#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308970static int wlan_hdd_change_station(struct wiphy *wiphy,
8971 struct net_device *dev,
8972 u8 *mac,
8973 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308974#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308975{
8976 int ret;
8977
8978 vos_ssr_protect(__func__);
8979 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
8980 vos_ssr_unprotect(__func__);
8981
8982 return ret;
8983}
8984
Jeff Johnson295189b2012-06-20 16:38:30 -07008985/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308986 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008987 * This function is used to initialize the key information
8988 */
8989#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308990static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008991 struct net_device *ndev,
8992 u8 key_index, bool pairwise,
8993 const u8 *mac_addr,
8994 struct key_params *params
8995 )
8996#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308997static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008998 struct net_device *ndev,
8999 u8 key_index, const u8 *mac_addr,
9000 struct key_params *params
9001 )
9002#endif
9003{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009004 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07009005 tCsrRoamSetKey setKey;
9006 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309007 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009008 v_U32_t roamId= 0xFF;
9009 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009010 hdd_hostapd_state_t *pHostapdState;
9011 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009012 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309013 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009014
9015 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309016
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309017 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9018 TRACE_CODE_HDD_CFG80211_ADD_KEY,
9019 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309020 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9021 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309022 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009023 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309024 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009025 }
9026
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309027 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9028 __func__, hdd_device_modetoString(pAdapter->device_mode),
9029 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009030
9031 if (CSR_MAX_NUM_KEY <= key_index)
9032 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009033 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009034 key_index);
9035
9036 return -EINVAL;
9037 }
9038
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009039 if (CSR_MAX_KEY_LEN < params->key_len)
9040 {
9041 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
9042 params->key_len);
9043
9044 return -EINVAL;
9045 }
9046
9047 hddLog(VOS_TRACE_LEVEL_INFO,
9048 "%s: called with key index = %d & key length %d",
9049 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009050
9051 /*extract key idx, key len and key*/
9052 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9053 setKey.keyId = key_index;
9054 setKey.keyLength = params->key_len;
9055 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
9056
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009057 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009058 {
9059 case WLAN_CIPHER_SUITE_WEP40:
9060 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
9061 break;
9062
9063 case WLAN_CIPHER_SUITE_WEP104:
9064 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
9065 break;
9066
9067 case WLAN_CIPHER_SUITE_TKIP:
9068 {
9069 u8 *pKey = &setKey.Key[0];
9070 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
9071
9072 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
9073
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009074 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07009075
9076 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009077 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009078 |--------------|----------|----------|
9079 <---16bytes---><--8bytes--><--8bytes-->
9080
9081 */
9082 /*Sme expects the 32 bytes key to be in the below order
9083
9084 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009085 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009086 |--------------|----------|----------|
9087 <---16bytes---><--8bytes--><--8bytes-->
9088 */
9089 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009090 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07009091
9092 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009093 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009094
9095 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009096 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009097
9098
9099 break;
9100 }
9101
9102 case WLAN_CIPHER_SUITE_CCMP:
9103 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
9104 break;
9105
9106#ifdef FEATURE_WLAN_WAPI
9107 case WLAN_CIPHER_SUITE_SMS4:
9108 {
9109 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9110 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
9111 params->key, params->key_len);
9112 return 0;
9113 }
9114#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009115
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009116#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009117 case WLAN_CIPHER_SUITE_KRK:
9118 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
9119 break;
9120#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009121
9122#ifdef WLAN_FEATURE_11W
9123 case WLAN_CIPHER_SUITE_AES_CMAC:
9124 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07009125 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07009126#endif
9127
Jeff Johnson295189b2012-06-20 16:38:30 -07009128 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009129 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009130 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309131 status = -EOPNOTSUPP;
9132 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009133 }
9134
9135 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
9136 __func__, setKey.encType);
9137
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009138 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07009139#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9140 (!pairwise)
9141#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009142 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07009143#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009144 )
9145 {
9146 /* set group key*/
9147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9148 "%s- %d: setting Broadcast key",
9149 __func__, __LINE__);
9150 setKey.keyDirection = eSIR_RX_ONLY;
9151 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9152 }
9153 else
9154 {
9155 /* set pairwise key*/
9156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9157 "%s- %d: setting pairwise key",
9158 __func__, __LINE__);
9159 setKey.keyDirection = eSIR_TX_RX;
9160 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9161 }
9162 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
9163 {
9164 setKey.keyDirection = eSIR_TX_RX;
9165 /*Set the group key*/
9166 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9167 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07009168
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009169 if ( 0 != status )
9170 {
9171 hddLog(VOS_TRACE_LEVEL_ERROR,
9172 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309173 status = -EINVAL;
9174 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009175 }
9176 /*Save the keys here and call sme_RoamSetKey for setting
9177 the PTK after peer joins the IBSS network*/
9178 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
9179 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309180 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009181 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05309182 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
9183 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
9184 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009185 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009186 if( pHostapdState->bssState == BSS_START )
9187 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009188 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9189 vos_status = wlan_hdd_check_ula_done(pAdapter);
9190
9191 if ( vos_status != VOS_STATUS_SUCCESS )
9192 {
9193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9194 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9195 __LINE__, vos_status );
9196
9197 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9198
9199 status = -EINVAL;
9200 goto end;
9201 }
9202
Jeff Johnson295189b2012-06-20 16:38:30 -07009203 status = WLANSAP_SetKeySta( pVosContext, &setKey);
9204
9205 if ( status != eHAL_STATUS_SUCCESS )
9206 {
9207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9208 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9209 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309210 status = -EINVAL;
9211 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009212 }
9213 }
9214
9215 /* Saving WEP keys */
9216 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
9217 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
9218 {
9219 //Save the wep key in ap context. Issue setkey after the BSS is started.
9220 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9221 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
9222 }
9223 else
9224 {
9225 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009226 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009227 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
9228 }
9229 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009230 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
9231 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009232 {
9233 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9234 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9235
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309236#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9237 if (!pairwise)
9238#else
9239 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9240#endif
9241 {
9242 /* set group key*/
9243 if (pHddStaCtx->roam_info.deferKeyComplete)
9244 {
9245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9246 "%s- %d: Perform Set key Complete",
9247 __func__, __LINE__);
9248 hdd_PerformRoamSetKeyComplete(pAdapter);
9249 }
9250 }
9251
Jeff Johnson295189b2012-06-20 16:38:30 -07009252 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
9253
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08009254 pWextState->roamProfile.Keys.defaultIndex = key_index;
9255
9256
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009257 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009258 params->key, params->key_len);
9259
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309260
Jeff Johnson295189b2012-06-20 16:38:30 -07009261 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9262
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309263 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009264 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309265 __func__, setKey.peerMac[0], setKey.peerMac[1],
9266 setKey.peerMac[2], setKey.peerMac[3],
9267 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009268 setKey.keyDirection);
9269
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009270 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +05309271
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009272 if ( vos_status != VOS_STATUS_SUCCESS )
9273 {
9274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009275 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9276 __LINE__, vos_status );
9277
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009278 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009279
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009280 status = -EINVAL;
9281 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009282
9283 }
9284
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009285#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309286 /* The supplicant may attempt to set the PTK once pre-authentication
9287 is done. Save the key in the UMAC and include it in the ADD BSS
9288 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009289 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309290 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009291 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309292 hddLog(VOS_TRACE_LEVEL_INFO_MED,
9293 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309294 status = 0;
9295 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309296 }
9297 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
9298 {
9299 hddLog(VOS_TRACE_LEVEL_ERROR,
9300 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309301 status = -EINVAL;
9302 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009303 }
9304#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07009305
9306 /* issue set key request to SME*/
9307 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9308 pAdapter->sessionId, &setKey, &roamId );
9309
9310 if ( 0 != status )
9311 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309312 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009313 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
9314 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309315 status = -EINVAL;
9316 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009317 }
9318
9319
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309320 /* in case of IBSS as there was no information available about WEP keys during
9321 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07009322 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309323 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
9324 !( ( IW_AUTH_KEY_MGMT_802_1X
9325 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07009326 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
9327 )
9328 &&
9329 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
9330 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
9331 )
9332 )
9333 {
9334 setKey.keyDirection = eSIR_RX_ONLY;
9335 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9336
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309337 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009338 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309339 __func__, setKey.peerMac[0], setKey.peerMac[1],
9340 setKey.peerMac[2], setKey.peerMac[3],
9341 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009342 setKey.keyDirection);
9343
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309344 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009345 pAdapter->sessionId, &setKey, &roamId );
9346
9347 if ( 0 != status )
9348 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309349 hddLog(VOS_TRACE_LEVEL_ERROR,
9350 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009351 __func__, status);
9352 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309353 status = -EINVAL;
9354 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009355 }
9356 }
9357 }
9358
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309359end:
9360 /* Need to clear any trace of key value in the memory.
9361 * Thus zero out the memory even though it is local
9362 * variable.
9363 */
9364 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309365 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309366 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009367}
9368
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309369#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9370static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9371 struct net_device *ndev,
9372 u8 key_index, bool pairwise,
9373 const u8 *mac_addr,
9374 struct key_params *params
9375 )
9376#else
9377static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9378 struct net_device *ndev,
9379 u8 key_index, const u8 *mac_addr,
9380 struct key_params *params
9381 )
9382#endif
9383{
9384 int ret;
9385 vos_ssr_protect(__func__);
9386#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9387 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
9388 mac_addr, params);
9389#else
9390 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
9391 params);
9392#endif
9393 vos_ssr_unprotect(__func__);
9394
9395 return ret;
9396}
9397
Jeff Johnson295189b2012-06-20 16:38:30 -07009398/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309399 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009400 * This function is used to get the key information
9401 */
9402#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309403static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309404 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009405 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309406 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009407 const u8 *mac_addr, void *cookie,
9408 void (*callback)(void *cookie, struct key_params*)
9409 )
9410#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309411static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309412 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009413 struct net_device *ndev,
9414 u8 key_index, const u8 *mac_addr, void *cookie,
9415 void (*callback)(void *cookie, struct key_params*)
9416 )
9417#endif
9418{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309419 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309420 hdd_wext_state_t *pWextState = NULL;
9421 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009422 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309423 hdd_context_t *pHddCtx;
9424 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009425
9426 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309427
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309428 if (NULL == pAdapter)
9429 {
9430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9431 "%s: HDD adapter is Null", __func__);
9432 return -ENODEV;
9433 }
9434
9435 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9436 ret = wlan_hdd_validate_context(pHddCtx);
9437 if (0 != ret)
9438 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309439 return ret;
9440 }
9441
9442 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9443 pRoamProfile = &(pWextState->roamProfile);
9444
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309445 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9446 __func__, hdd_device_modetoString(pAdapter->device_mode),
9447 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309448
Jeff Johnson295189b2012-06-20 16:38:30 -07009449 memset(&params, 0, sizeof(params));
9450
9451 if (CSR_MAX_NUM_KEY <= key_index)
9452 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309453 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07009454 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309455 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009456
9457 switch(pRoamProfile->EncryptionType.encryptionType[0])
9458 {
9459 case eCSR_ENCRYPT_TYPE_NONE:
9460 params.cipher = IW_AUTH_CIPHER_NONE;
9461 break;
9462
9463 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
9464 case eCSR_ENCRYPT_TYPE_WEP40:
9465 params.cipher = WLAN_CIPHER_SUITE_WEP40;
9466 break;
9467
9468 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
9469 case eCSR_ENCRYPT_TYPE_WEP104:
9470 params.cipher = WLAN_CIPHER_SUITE_WEP104;
9471 break;
9472
9473 case eCSR_ENCRYPT_TYPE_TKIP:
9474 params.cipher = WLAN_CIPHER_SUITE_TKIP;
9475 break;
9476
9477 case eCSR_ENCRYPT_TYPE_AES:
9478 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
9479 break;
9480
9481 default:
9482 params.cipher = IW_AUTH_CIPHER_NONE;
9483 break;
9484 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309485
c_hpothuaaf19692014-05-17 17:01:48 +05309486 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9487 TRACE_CODE_HDD_CFG80211_GET_KEY,
9488 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309489
Jeff Johnson295189b2012-06-20 16:38:30 -07009490 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
9491 params.seq_len = 0;
9492 params.seq = NULL;
9493 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
9494 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309495 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009496 return 0;
9497}
9498
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309499#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9500static int wlan_hdd_cfg80211_get_key(
9501 struct wiphy *wiphy,
9502 struct net_device *ndev,
9503 u8 key_index, bool pairwise,
9504 const u8 *mac_addr, void *cookie,
9505 void (*callback)(void *cookie, struct key_params*)
9506 )
9507#else
9508static int wlan_hdd_cfg80211_get_key(
9509 struct wiphy *wiphy,
9510 struct net_device *ndev,
9511 u8 key_index, const u8 *mac_addr, void *cookie,
9512 void (*callback)(void *cookie, struct key_params*)
9513 )
9514#endif
9515{
9516 int ret;
9517
9518 vos_ssr_protect(__func__);
9519#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9520 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
9521 mac_addr, cookie, callback);
9522#else
9523 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
9524 callback);
9525#endif
9526 vos_ssr_unprotect(__func__);
9527
9528 return ret;
9529}
9530
Jeff Johnson295189b2012-06-20 16:38:30 -07009531/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309532 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009533 * This function is used to delete the key information
9534 */
9535#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309536static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009537 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309538 u8 key_index,
9539 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009540 const u8 *mac_addr
9541 )
9542#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309543static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009544 struct net_device *ndev,
9545 u8 key_index,
9546 const u8 *mac_addr
9547 )
9548#endif
9549{
9550 int status = 0;
9551
9552 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309553 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009554 //it is observed that this is invalidating peer
9555 //key index whenever re-key is done. This is affecting data link.
9556 //It should be ok to ignore del_key.
9557#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309558 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
9559 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009560 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
9561 tCsrRoamSetKey setKey;
9562 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309563
Jeff Johnson295189b2012-06-20 16:38:30 -07009564 ENTER();
9565
9566 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
9567 __func__,pAdapter->device_mode);
9568
9569 if (CSR_MAX_NUM_KEY <= key_index)
9570 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309571 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009572 key_index);
9573
9574 return -EINVAL;
9575 }
9576
9577 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9578 setKey.keyId = key_index;
9579
9580 if (mac_addr)
9581 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9582 else
9583 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
9584
9585 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
9586
9587 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309589 )
9590 {
9591
9592 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07009593 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9594 if( pHostapdState->bssState == BSS_START)
9595 {
9596 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309597
Jeff Johnson295189b2012-06-20 16:38:30 -07009598 if ( status != eHAL_STATUS_SUCCESS )
9599 {
9600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9601 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9602 __LINE__, status );
9603 }
9604 }
9605 }
9606 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309607 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07009608 )
9609 {
9610 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9611
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309612 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9613
9614 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009615 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309616 __func__, setKey.peerMac[0], setKey.peerMac[1],
9617 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07009618 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309619 if(pAdapter->sessionCtx.station.conn_info.connState ==
9620 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07009621 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309622 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009623 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309624
Jeff Johnson295189b2012-06-20 16:38:30 -07009625 if ( 0 != status )
9626 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309627 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009628 "%s: sme_RoamSetKey failure, returned %d",
9629 __func__, status);
9630 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9631 return -EINVAL;
9632 }
9633 }
9634 }
9635#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009636 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009637 return status;
9638}
9639
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309640#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9641static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9642 struct net_device *ndev,
9643 u8 key_index,
9644 bool pairwise,
9645 const u8 *mac_addr
9646 )
9647#else
9648static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9649 struct net_device *ndev,
9650 u8 key_index,
9651 const u8 *mac_addr
9652 )
9653#endif
9654{
9655 int ret;
9656
9657 vos_ssr_protect(__func__);
9658#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9659 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
9660 mac_addr);
9661#else
9662 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
9663#endif
9664 vos_ssr_unprotect(__func__);
9665
9666 return ret;
9667}
9668
Jeff Johnson295189b2012-06-20 16:38:30 -07009669/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309670 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009671 * This function is used to set the default tx key index
9672 */
9673#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309674static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009675 struct net_device *ndev,
9676 u8 key_index,
9677 bool unicast, bool multicast)
9678#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309679static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009680 struct net_device *ndev,
9681 u8 key_index)
9682#endif
9683{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309684 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309685 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309686 hdd_wext_state_t *pWextState;
9687 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309688 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009689
9690 ENTER();
9691
Gopichand Nakkala29149562013-05-10 21:43:41 +05309692 if ((NULL == pAdapter))
9693 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309695 "invalid adapter");
9696 return -EINVAL;
9697 }
9698
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309699 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9700 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
9701 pAdapter->sessionId, key_index));
9702
Gopichand Nakkala29149562013-05-10 21:43:41 +05309703 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9704 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9705
9706 if ((NULL == pWextState) || (NULL == pHddStaCtx))
9707 {
9708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9709 "invalid Wext state or HDD context");
9710 return -EINVAL;
9711 }
9712
Arif Hussain6d2a3322013-11-17 19:50:10 -08009713 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009714 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309715
Jeff Johnson295189b2012-06-20 16:38:30 -07009716 if (CSR_MAX_NUM_KEY <= key_index)
9717 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309718 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009719 key_index);
9720
9721 return -EINVAL;
9722 }
9723
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309724 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9725 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309726 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009727 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309728 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009729 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309730
Jeff Johnson295189b2012-06-20 16:38:30 -07009731 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07009732 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309733 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009734 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309735 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08009736 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309737 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08009738 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07009739 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309740 {
9741 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07009742 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309743
Jeff Johnson295189b2012-06-20 16:38:30 -07009744 tCsrRoamSetKey setKey;
9745 v_U32_t roamId= 0xFF;
9746 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309747
9748 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009749 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309750
Jeff Johnson295189b2012-06-20 16:38:30 -07009751 Keys->defaultIndex = (u8)key_index;
9752 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9753 setKey.keyId = key_index;
9754 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309755
9756 vos_mem_copy(&setKey.Key[0],
9757 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009758 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309759
Gopichand Nakkala29149562013-05-10 21:43:41 +05309760 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309761
9762 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07009763 &pHddStaCtx->conn_info.bssId[0],
9764 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309765
Gopichand Nakkala29149562013-05-10 21:43:41 +05309766 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
9767 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
9768 eCSR_ENCRYPT_TYPE_WEP104)
9769 {
9770 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
9771 even though ap is configured for WEP-40 encryption. In this canse the key length
9772 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
9773 type(104) and switching encryption type to 40*/
9774 pWextState->roamProfile.EncryptionType.encryptionType[0] =
9775 eCSR_ENCRYPT_TYPE_WEP40;
9776 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
9777 eCSR_ENCRYPT_TYPE_WEP40;
9778 }
9779
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309780 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07009781 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309782
Jeff Johnson295189b2012-06-20 16:38:30 -07009783 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309784 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009785 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309786
Jeff Johnson295189b2012-06-20 16:38:30 -07009787 if ( 0 != status )
9788 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309789 hddLog(VOS_TRACE_LEVEL_ERROR,
9790 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009791 status);
9792 return -EINVAL;
9793 }
9794 }
9795 }
9796
9797 /* In SoftAp mode setting key direction for default mode */
9798 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
9799 {
9800 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
9801 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
9802 (eCSR_ENCRYPT_TYPE_AES !=
9803 pWextState->roamProfile.EncryptionType.encryptionType[0])
9804 )
9805 {
9806 /* Saving key direction for default key index to TX default */
9807 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9808 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
9809 }
9810 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309811 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009812 return status;
9813}
9814
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309815#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9816static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9817 struct net_device *ndev,
9818 u8 key_index,
9819 bool unicast, bool multicast)
9820#else
9821static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9822 struct net_device *ndev,
9823 u8 key_index)
9824#endif
9825{
9826 int ret;
9827 vos_ssr_protect(__func__);
9828#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9829 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
9830 multicast);
9831#else
9832 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
9833#endif
9834 vos_ssr_unprotect(__func__);
9835
9836 return ret;
9837}
9838
Jeff Johnson295189b2012-06-20 16:38:30 -07009839/*
9840 * FUNCTION: wlan_hdd_cfg80211_inform_bss
9841 * This function is used to inform the BSS details to nl80211 interface.
9842 */
9843static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
9844 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
9845{
9846 struct net_device *dev = pAdapter->dev;
9847 struct wireless_dev *wdev = dev->ieee80211_ptr;
9848 struct wiphy *wiphy = wdev->wiphy;
9849 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
9850 int chan_no;
9851 int ie_length;
9852 const char *ie;
9853 unsigned int freq;
9854 struct ieee80211_channel *chan;
9855 int rssi = 0;
9856 struct cfg80211_bss *bss = NULL;
9857
Jeff Johnson295189b2012-06-20 16:38:30 -07009858 if( NULL == pBssDesc )
9859 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009860 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009861 return bss;
9862 }
9863
9864 chan_no = pBssDesc->channelId;
9865 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
9866 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
9867
9868 if( NULL == ie )
9869 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009870 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009871 return bss;
9872 }
9873
9874#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9875 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9876 {
9877 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9878 }
9879 else
9880 {
9881 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9882 }
9883#else
9884 freq = ieee80211_channel_to_frequency(chan_no);
9885#endif
9886
9887 chan = __ieee80211_get_channel(wiphy, freq);
9888
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05309889 if (!chan) {
9890 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
9891 return NULL;
9892 }
9893
Abhishek Singhaee43942014-06-16 18:55:47 +05309894 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07009895
Anand N Sunkad9f80b742015-07-30 20:05:51 +05309896 return cfg80211_inform_bss(wiphy, chan,
9897#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9898 CFG80211_BSS_FTYPE_UNKNOWN,
9899#endif
9900 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309901 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07009902 pBssDesc->capabilityInfo,
9903 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05309904 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07009905}
9906
9907
9908
9909/*
9910 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
9911 * This function is used to inform the BSS details to nl80211 interface.
9912 */
9913struct cfg80211_bss*
9914wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
9915 tSirBssDescription *bss_desc
9916 )
9917{
9918 /*
9919 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
9920 already exists in bss data base of cfg80211 for that particular BSS ID.
9921 Using cfg80211_inform_bss_frame to update the bss entry instead of
9922 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
9923 now there is no possibility to get the mgmt(probe response) frame from PE,
9924 converting bss_desc to ieee80211_mgmt(probe response) and passing to
9925 cfg80211_inform_bss_frame.
9926 */
9927 struct net_device *dev = pAdapter->dev;
9928 struct wireless_dev *wdev = dev->ieee80211_ptr;
9929 struct wiphy *wiphy = wdev->wiphy;
9930 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009931#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9932 qcom_ie_age *qie_age = NULL;
9933 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
9934#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009935 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009936#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009937 const char *ie =
9938 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
9939 unsigned int freq;
9940 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309941 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009942 struct cfg80211_bss *bss_status = NULL;
9943 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
9944 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07009945 hdd_context_t *pHddCtx;
9946 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07009947#ifdef WLAN_OPEN_SOURCE
9948 struct timespec ts;
9949#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009950
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309951
Wilson Yangf80a0542013-10-07 13:02:37 -07009952 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9953 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -07009954 if (0 != status)
9955 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009956 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009957 }
9958
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309959 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07009960 if (!mgmt)
9961 {
9962 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9963 "%s: memory allocation failed ", __func__);
9964 return NULL;
9965 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009966
Jeff Johnson295189b2012-06-20 16:38:30 -07009967 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07009968
9969#ifdef WLAN_OPEN_SOURCE
9970 /* Android does not want the timestamp from the frame.
9971 Instead it wants a monotonic increasing value */
9972 get_monotonic_boottime(&ts);
9973 mgmt->u.probe_resp.timestamp =
9974 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
9975#else
9976 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009977 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
9978 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07009979
9980#endif
9981
Jeff Johnson295189b2012-06-20 16:38:30 -07009982 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
9983 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009984
9985#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9986 /* GPS Requirement: need age ie per entry. Using vendor specific. */
9987 /* Assuming this is the last IE, copy at the end */
9988 ie_length -=sizeof(qcom_ie_age);
9989 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
9990 qie_age->element_id = QCOM_VENDOR_IE_ID;
9991 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
9992 qie_age->oui_1 = QCOM_OUI1;
9993 qie_age->oui_2 = QCOM_OUI2;
9994 qie_age->oui_3 = QCOM_OUI3;
9995 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
9996 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
9997#endif
9998
Jeff Johnson295189b2012-06-20 16:38:30 -07009999 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053010000 if (bss_desc->fProbeRsp)
10001 {
10002 mgmt->frame_control |=
10003 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
10004 }
10005 else
10006 {
10007 mgmt->frame_control |=
10008 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
10009 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010010
10011#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010012 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010013 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
10014 {
10015 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10016 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010017 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010018 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
10019
10020 {
10021 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10022 }
10023 else
10024 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010025 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
10026 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070010027 kfree(mgmt);
10028 return NULL;
10029 }
10030#else
10031 freq = ieee80211_channel_to_frequency(chan_no);
10032#endif
10033 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010034 /*when the band is changed on the fly using the GUI, three things are done
10035 * 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)
10036 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
10037 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
10038 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
10039 * and discards the channels correponding to previous band and calls back with zero bss results.
10040 * 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
10041 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
10042 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
10043 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
10044 * So drop the bss and continue to next bss.
10045 */
10046 if(chan == NULL)
10047 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010048 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070010049 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010050 return NULL;
10051 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053010052 /*To keep the rssi icon of the connected AP in the scan window
10053 *and the rssi icon of the wireless networks in sync
10054 * */
10055 if (( eConnectionState_Associated ==
10056 pAdapter->sessionCtx.station.conn_info.connState ) &&
10057 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
10058 pAdapter->sessionCtx.station.conn_info.bssId,
10059 WNI_CFG_BSSID_LEN)) &&
10060 (pHddCtx->hdd_wlan_suspended == FALSE))
10061 {
10062 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
10063 rssi = (pAdapter->rssi * 100);
10064 }
10065 else
10066 {
10067 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
10068 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010069
Nirav Shah20ac06f2013-12-12 18:14:06 +053010070 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053010071 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
10072 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053010073
Jeff Johnson295189b2012-06-20 16:38:30 -070010074 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
10075 frame_len, rssi, GFP_KERNEL);
10076 kfree(mgmt);
10077 return bss_status;
10078}
10079
10080/*
10081 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
10082 * This function is used to update the BSS data base of CFG8011
10083 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010084struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010085 tCsrRoamInfo *pRoamInfo
10086 )
10087{
10088 tCsrRoamConnectedProfile roamProfile;
10089 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10090 struct cfg80211_bss *bss = NULL;
10091
10092 ENTER();
10093
10094 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
10095 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
10096
10097 if (NULL != roamProfile.pBssDesc)
10098 {
Girish Gowlif4b68022014-08-28 23:18:57 +053010099 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10100 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070010101
10102 if (NULL == bss)
10103 {
10104 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
10105 __func__);
10106 }
10107
10108 sme_RoamFreeConnectProfile(hHal, &roamProfile);
10109 }
10110 else
10111 {
10112 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
10113 __func__);
10114 }
10115 return bss;
10116}
10117
10118/*
10119 * FUNCTION: wlan_hdd_cfg80211_update_bss
10120 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010121static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
10122 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070010123 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010124{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010125 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010126 tCsrScanResultInfo *pScanResult;
10127 eHalStatus status = 0;
10128 tScanResultHandle pResult;
10129 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010130 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010131 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070010132 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010133
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010134 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10135 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
10136 NO_SESSION, pAdapter->sessionId));
10137
Wilson Yangf80a0542013-10-07 13:02:37 -070010138 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10139
10140 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070010141 {
Wilson Yangf80a0542013-10-07 13:02:37 -070010142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10143 "%s:LOGP in Progress. Ignore!!!",__func__);
10144 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010145 }
10146
Wilson Yangf80a0542013-10-07 13:02:37 -070010147
10148 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053010149 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070010150 {
10151 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10152 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
10153 return VOS_STATUS_E_PERM;
10154 }
10155
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010156 if (pAdapter->request != NULL)
10157 {
10158 if ((pAdapter->request->n_ssids == 1)
10159 && (pAdapter->request->ssids != NULL)
10160 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
10161 is_p2p_scan = true;
10162 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010163 /*
10164 * start getting scan results and populate cgf80211 BSS database
10165 */
10166 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
10167
10168 /* no scan results */
10169 if (NULL == pResult)
10170 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010171 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
10172 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053010173 wlan_hdd_get_frame_logs(pAdapter,
10174 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070010175 return status;
10176 }
10177
10178 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
10179
10180 while (pScanResult)
10181 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010182 /*
10183 * cfg80211_inform_bss() is not updating ie field of bss entry, if
10184 * entry already exists in bss data base of cfg80211 for that
10185 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
10186 * bss entry instead of cfg80211_inform_bss, But this call expects
10187 * mgmt packet as input. As of now there is no possibility to get
10188 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070010189 * ieee80211_mgmt(probe response) and passing to c
10190 * fg80211_inform_bss_frame.
10191 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010192 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
10193 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
10194 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010195 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10196 continue; //Skip the non p2p bss entries
10197 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010198 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10199 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010200
Jeff Johnson295189b2012-06-20 16:38:30 -070010201
10202 if (NULL == bss_status)
10203 {
10204 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010205 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010206 }
10207 else
10208 {
Yue Maf49ba872013-08-19 12:04:25 -070010209 cfg80211_put_bss(
10210#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
10211 wiphy,
10212#endif
10213 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010214 }
10215
10216 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10217 }
10218
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010219 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010220 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010221 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010222}
10223
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010224void
10225hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
10226{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010227 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080010228 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010229} /****** end hddPrintMacAddr() ******/
10230
10231void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010232hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010233{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010234 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010235 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010236 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
10237 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
10238 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010239} /****** end hddPrintPmkId() ******/
10240
10241//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
10242//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
10243
10244//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
10245//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
10246
10247#define dump_bssid(bssid) \
10248 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010249 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
10250 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010251 }
10252
10253#define dump_pmkid(pMac, pmkid) \
10254 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010255 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
10256 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010257 }
10258
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070010259#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010260/*
10261 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
10262 * This function is used to notify the supplicant of a new PMKSA candidate.
10263 */
10264int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010265 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010266 int index, bool preauth )
10267{
Jeff Johnsone7245742012-09-05 17:12:55 -070010268#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010269 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010270 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010271
10272 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070010273 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010274
10275 if( NULL == pRoamInfo )
10276 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010277 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010278 return -EINVAL;
10279 }
10280
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010281 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
10282 {
10283 dump_bssid(pRoamInfo->bssid);
10284 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010285 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010286 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010287#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010288 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010289}
10290#endif //FEATURE_WLAN_LFR
10291
Yue Maef608272013-04-08 23:09:17 -070010292#ifdef FEATURE_WLAN_LFR_METRICS
10293/*
10294 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
10295 * 802.11r/LFR metrics reporting function to report preauth initiation
10296 *
10297 */
10298#define MAX_LFR_METRICS_EVENT_LENGTH 100
10299VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
10300 tCsrRoamInfo *pRoamInfo)
10301{
10302 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10303 union iwreq_data wrqu;
10304
10305 ENTER();
10306
10307 if (NULL == pAdapter)
10308 {
10309 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10310 return VOS_STATUS_E_FAILURE;
10311 }
10312
10313 /* create the event */
10314 memset(&wrqu, 0, sizeof(wrqu));
10315 memset(metrics_notification, 0, sizeof(metrics_notification));
10316
10317 wrqu.data.pointer = metrics_notification;
10318 wrqu.data.length = scnprintf(metrics_notification,
10319 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
10320 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10321
10322 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10323
10324 EXIT();
10325
10326 return VOS_STATUS_SUCCESS;
10327}
10328
10329/*
10330 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
10331 * 802.11r/LFR metrics reporting function to report preauth completion
10332 * or failure
10333 */
10334VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
10335 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
10336{
10337 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10338 union iwreq_data wrqu;
10339
10340 ENTER();
10341
10342 if (NULL == pAdapter)
10343 {
10344 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10345 return VOS_STATUS_E_FAILURE;
10346 }
10347
10348 /* create the event */
10349 memset(&wrqu, 0, sizeof(wrqu));
10350 memset(metrics_notification, 0, sizeof(metrics_notification));
10351
10352 scnprintf(metrics_notification, sizeof(metrics_notification),
10353 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
10354 MAC_ADDR_ARRAY(pRoamInfo->bssid));
10355
10356 if (1 == preauth_status)
10357 strncat(metrics_notification, " TRUE", 5);
10358 else
10359 strncat(metrics_notification, " FALSE", 6);
10360
10361 wrqu.data.pointer = metrics_notification;
10362 wrqu.data.length = strlen(metrics_notification);
10363
10364 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10365
10366 EXIT();
10367
10368 return VOS_STATUS_SUCCESS;
10369}
10370
10371/*
10372 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
10373 * 802.11r/LFR metrics reporting function to report handover initiation
10374 *
10375 */
10376VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
10377 tCsrRoamInfo *pRoamInfo)
10378{
10379 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10380 union iwreq_data wrqu;
10381
10382 ENTER();
10383
10384 if (NULL == pAdapter)
10385 {
10386 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10387 return VOS_STATUS_E_FAILURE;
10388 }
10389
10390 /* create the event */
10391 memset(&wrqu, 0, sizeof(wrqu));
10392 memset(metrics_notification, 0, sizeof(metrics_notification));
10393
10394 wrqu.data.pointer = metrics_notification;
10395 wrqu.data.length = scnprintf(metrics_notification,
10396 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
10397 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10398
10399 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10400
10401 EXIT();
10402
10403 return VOS_STATUS_SUCCESS;
10404}
10405#endif
10406
Jeff Johnson295189b2012-06-20 16:38:30 -070010407/*
10408 * FUNCTION: hdd_cfg80211_scan_done_callback
10409 * scanning callback function, called after finishing scan
10410 *
10411 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010412static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070010413 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
10414{
10415 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010416 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070010417 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010418 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010419 struct cfg80211_scan_request *req = NULL;
10420 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010421 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010422 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010423 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010424 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010425
10426 ENTER();
10427
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010428 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053010429 if (NULL == pHddCtx) {
10430 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010431 goto allow_suspend;
10432 }
10433
10434 pScanInfo = &pHddCtx->scan_info;
10435
Jeff Johnson295189b2012-06-20 16:38:30 -070010436 hddLog(VOS_TRACE_LEVEL_INFO,
10437 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080010438 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010439 __func__, halHandle, pContext, (int) scanId, (int) status);
10440
Kiet Lamac06e2c2013-10-23 16:25:07 +053010441 pScanInfo->mScanPendingCounter = 0;
10442
Jeff Johnson295189b2012-06-20 16:38:30 -070010443 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010444 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070010445 &pScanInfo->scan_req_completion_event,
10446 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010447 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070010448 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010449 hddLog(VOS_TRACE_LEVEL_ERROR,
10450 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070010451 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010452 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010453 }
10454
Yue Maef608272013-04-08 23:09:17 -070010455 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010456 {
10457 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010458 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010459 }
10460
10461 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010462 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070010463 {
10464 hddLog(VOS_TRACE_LEVEL_INFO,
10465 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010466 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070010467 (int) scanId);
10468 }
10469
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010470 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010471 pAdapter);
10472
10473 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010474 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010475
10476
10477 /* If any client wait scan result through WEXT
10478 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010479 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070010480 {
10481 /* The other scan request waiting for current scan finish
10482 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010483 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010484 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010485 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070010486 }
10487 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010488 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010489 {
10490 struct net_device *dev = pAdapter->dev;
10491 union iwreq_data wrqu;
10492 int we_event;
10493 char *msg;
10494
10495 memset(&wrqu, '\0', sizeof(wrqu));
10496 we_event = SIOCGIWSCAN;
10497 msg = NULL;
10498 wireless_send_event(dev, we_event, &wrqu, msg);
10499 }
10500 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010501 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010502
10503 /* Get the Scan Req */
10504 req = pAdapter->request;
10505
10506 if (!req)
10507 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010508 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010509 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010510 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010511 }
10512
Jeff Johnson295189b2012-06-20 16:38:30 -070010513 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070010514 /* Scan is no longer pending */
10515 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010516
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010517 /* last_scan_timestamp is used to decide if new scan
10518 * is needed or not on station interface. If last station
10519 * scan time and new station scan time is less then
10520 * last_scan_timestamp ; driver will return cached scan.
10521 */
10522 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
10523 {
10524 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
10525
10526 if ( req->n_channels )
10527 {
10528 for (i = 0; i < req->n_channels ; i++ )
10529 {
10530 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
10531 }
10532 /* store no of channel scanned */
10533 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
10534 }
10535
10536 }
10537
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070010538 /*
10539 * cfg80211_scan_done informing NL80211 about completion
10540 * of scanning
10541 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010542 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
10543 {
10544 aborted = true;
10545 }
10546 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080010547 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010548
Siddharth Bhal76972212014-10-15 16:22:51 +053010549 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
10550 /* Generate new random mac addr for next scan */
10551 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
10552 hdd_processSpoofMacAddrRequest(pHddCtx);
10553 }
10554
Jeff Johnsone7245742012-09-05 17:12:55 -070010555allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010556 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010557 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010558
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010559 /* Acquire wakelock to handle the case where APP's tries to suspend
10560 * immediatly after the driver gets connect request(i.e after scan)
10561 * from supplicant, this result in app's is suspending and not able
10562 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010563 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010564
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010565#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010566 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010567#endif
10568
Jeff Johnson295189b2012-06-20 16:38:30 -070010569 EXIT();
10570 return 0;
10571}
10572
10573/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053010574 * FUNCTION: hdd_isConnectionInProgress
10575 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010576 *
10577 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010578v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010579{
10580 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10581 hdd_station_ctx_t *pHddStaCtx = NULL;
10582 hdd_adapter_t *pAdapter = NULL;
10583 VOS_STATUS status = 0;
10584 v_U8_t staId = 0;
10585 v_U8_t *staMac = NULL;
10586
c_hpothu9b781ba2013-12-30 20:57:45 +053010587 if (TRUE == pHddCtx->btCoexModeSet)
10588 {
10589 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053010590 FL("BTCoex Mode operation in progress"));
10591 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053010592 }
10593
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010594 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10595
10596 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10597 {
10598 pAdapter = pAdapterNode->pAdapter;
10599
10600 if( pAdapter )
10601 {
10602 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010603 "%s: Adapter with device mode %s (%d) exists",
10604 __func__, hdd_device_modetoString(pAdapter->device_mode),
10605 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010606 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053010607 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10608 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
10609 (eConnectionState_Connecting ==
10610 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
10611 {
10612 hddLog(VOS_TRACE_LEVEL_ERROR,
10613 "%s: %p(%d) Connection is in progress", __func__,
10614 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10615 return VOS_TRUE;
10616 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010617 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053010618 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010619 {
10620 hddLog(VOS_TRACE_LEVEL_ERROR,
10621 "%s: %p(%d) Reassociation is in progress", __func__,
10622 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10623 return VOS_TRUE;
10624 }
10625 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010626 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10627 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010628 {
10629 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10630 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010631 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010632 {
10633 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
10634 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010635 "%s: client " MAC_ADDRESS_STR
10636 " is in the middle of WPS/EAPOL exchange.", __func__,
10637 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010638 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010639 }
10640 }
10641 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
10642 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
10643 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010644 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10645 ptSapContext pSapCtx = NULL;
10646 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10647 if(pSapCtx == NULL){
10648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10649 FL("psapCtx is NULL"));
10650 return VOS_FALSE;
10651 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010652 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
10653 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010654 if ((pSapCtx->aStaInfo[staId].isUsed) &&
10655 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010656 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010657 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010658
10659 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010660 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
10661 "middle of WPS/EAPOL exchange.", __func__,
10662 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010663 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010664 }
10665 }
10666 }
10667 }
10668 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10669 pAdapterNode = pNext;
10670 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053010671 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010672}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010673
10674/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010675 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070010676 * this scan respond to scan trigger and update cfg80211 scan database
10677 * later, scan dump command can be used to recieve scan results
10678 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010679int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010680#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10681 struct net_device *dev,
10682#endif
10683 struct cfg80211_scan_request *request)
10684{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010685 hdd_adapter_t *pAdapter = NULL;
10686 hdd_context_t *pHddCtx = NULL;
10687 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010688 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010689 tCsrScanRequest scanRequest;
10690 tANI_U8 *channelList = NULL, i;
10691 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010692 int status;
10693 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010694 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010695 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053010696 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010697 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053010698 v_S7_t rssi=0;
10699 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010700
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010701#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
10702 struct net_device *dev = NULL;
10703 if (NULL == request)
10704 {
10705 hddLog(VOS_TRACE_LEVEL_ERROR,
10706 "%s: scan req param null", __func__);
10707 return -EINVAL;
10708 }
10709 dev = request->wdev->netdev;
10710#endif
10711
10712 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
10713 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
10714 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10715
Jeff Johnson295189b2012-06-20 16:38:30 -070010716 ENTER();
10717
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010718 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10719 __func__, hdd_device_modetoString(pAdapter->device_mode),
10720 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010721
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010722 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010723 if (0 != status)
10724 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010725 return status;
10726 }
10727
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010728 if (NULL == pwextBuf)
10729 {
10730 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
10731 __func__);
10732 return -EIO;
10733 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010734 cfg_param = pHddCtx->cfg_ini;
10735 pScanInfo = &pHddCtx->scan_info;
10736
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053010737 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10738 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
10739 {
10740 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
10741 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
10742 }
10743
Jeff Johnson295189b2012-06-20 16:38:30 -070010744#ifdef WLAN_BTAMP_FEATURE
10745 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010746 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070010747 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010748 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010749 "%s: No scanning when AMP is on", __func__);
10750 return -EOPNOTSUPP;
10751 }
10752#endif
10753 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010754 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010755 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010756 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010757 "%s: Not scanning on device_mode = %s (%d)",
10758 __func__, hdd_device_modetoString(pAdapter->device_mode),
10759 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010760 return -EOPNOTSUPP;
10761 }
10762
10763 if (TRUE == pScanInfo->mScanPending)
10764 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010765 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
10766 {
10767 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
10768 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010769 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010770 }
10771
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010772 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070010773 //Channel and action frame is pending
10774 //Otherwise Cancel Remain On Channel and allow Scan
10775 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010776 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070010777 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010778 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010779 return -EBUSY;
10780 }
10781
Jeff Johnson295189b2012-06-20 16:38:30 -070010782 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
10783 {
10784 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080010785 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010786 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010787 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010788 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
10789 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010790 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010791 "%s: MAX TM Level Scan not allowed", __func__);
10792 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010793 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010794 }
10795 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
10796
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010797 /* Check if scan is allowed at this point of time.
10798 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010799 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010800 {
10801 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
10802 return -EBUSY;
10803 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010804
Jeff Johnson295189b2012-06-20 16:38:30 -070010805 vos_mem_zero( &scanRequest, sizeof(scanRequest));
10806
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010807 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
10808 * Becasue of this, driver is assuming that this is not wildcard scan and so
10809 * is not aging out the scan results.
10810 */
10811 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010812 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010813 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010814 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010815
10816 if ((request->ssids) && (0 < request->n_ssids))
10817 {
10818 tCsrSSIDInfo *SsidInfo;
10819 int j;
10820 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
10821 /* Allocate num_ssid tCsrSSIDInfo structure */
10822 SsidInfo = scanRequest.SSIDs.SSIDList =
10823 ( tCsrSSIDInfo *)vos_mem_malloc(
10824 request->n_ssids*sizeof(tCsrSSIDInfo));
10825
10826 if(NULL == scanRequest.SSIDs.SSIDList)
10827 {
10828 hddLog(VOS_TRACE_LEVEL_ERROR,
10829 "%s: memory alloc failed SSIDInfo buffer", __func__);
10830 return -ENOMEM;
10831 }
10832
10833 /* copy all the ssid's and their length */
10834 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
10835 {
10836 /* get the ssid length */
10837 SsidInfo->SSID.length = request->ssids[j].ssid_len;
10838 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
10839 SsidInfo->SSID.length);
10840 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
10841 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
10842 j, SsidInfo->SSID.ssId);
10843 }
10844 /* set the scan type to active */
10845 scanRequest.scanType = eSIR_ACTIVE_SCAN;
10846 }
10847 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070010848 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010849 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10850 TRACE_CODE_HDD_CFG80211_SCAN,
10851 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070010852 /* set the scan type to active */
10853 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010854 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010855 else
10856 {
10857 /*Set the scan type to default type, in this case it is ACTIVE*/
10858 scanRequest.scanType = pScanInfo->scan_mode;
10859 }
10860 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
10861 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070010862
10863 /* set BSSType to default type */
10864 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
10865
10866 /*TODO: scan the requested channels only*/
10867
10868 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010869 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070010870 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010871 hddLog(VOS_TRACE_LEVEL_WARN,
10872 "No of Scan Channels exceeded limit: %d", request->n_channels);
10873 request->n_channels = MAX_CHANNEL;
10874 }
10875
10876 hddLog(VOS_TRACE_LEVEL_INFO,
10877 "No of Scan Channels: %d", request->n_channels);
10878
10879
10880 if( request->n_channels )
10881 {
10882 char chList [(request->n_channels*5)+1];
10883 int len;
10884 channelList = vos_mem_malloc( request->n_channels );
10885 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053010886 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010887 hddLog(VOS_TRACE_LEVEL_ERROR,
10888 "%s: memory alloc failed channelList", __func__);
10889 status = -ENOMEM;
10890 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053010891 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010892
10893 for( i = 0, len = 0; i < request->n_channels ; i++ )
10894 {
10895 channelList[i] = request->channels[i]->hw_value;
10896 len += snprintf(chList+len, 5, "%d ", channelList[i]);
10897 }
10898
Nirav Shah20ac06f2013-12-12 18:14:06 +053010899 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010900 "Channel-List: %s ", chList);
10901 }
c_hpothu53512302014-04-15 18:49:53 +053010902
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010903 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
10904 scanRequest.ChannelInfo.ChannelList = channelList;
10905
10906 /* set requestType to full scan */
10907 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10908
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010909 /* if there is back to back scan happening in driver with in
10910 * nDeferScanTimeInterval interval driver should defer new scan request
10911 * and should provide last cached scan results instead of new channel list.
10912 * This rule is not applicable if scan is p2p scan.
10913 * This condition will work only in case when last request no of channels
10914 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053010915 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053010916 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010917 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010918
Sushant Kaushik86592172015-04-27 16:35:03 +053010919 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
10920 /* if wps ie is NULL , then only defer scan */
10921 if ( pWpsIe == NULL &&
10922 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053010923 {
10924 if ( pScanInfo->last_scan_timestamp !=0 &&
10925 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
10926 {
10927 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
10928 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
10929 vos_mem_compare(pScanInfo->last_scan_channelList,
10930 channelList, pScanInfo->last_scan_numChannels))
10931 {
10932 hddLog(VOS_TRACE_LEVEL_WARN,
10933 " New and old station scan time differ is less then %u",
10934 pHddCtx->cfg_ini->nDeferScanTimeInterval);
10935
10936 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010937 pAdapter);
10938
Agarwal Ashish57e84372014-12-05 18:26:53 +053010939 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010940 "Return old cached scan as all channels and no of channels are same");
10941
Agarwal Ashish57e84372014-12-05 18:26:53 +053010942 if (0 > ret)
10943 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010944
Agarwal Ashish57e84372014-12-05 18:26:53 +053010945 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010946
10947 status = eHAL_STATUS_SUCCESS;
10948 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053010949 }
10950 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010951 }
10952
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010953 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10954 * search (Flush on both full scan and social scan but not on single
10955 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10956 */
10957
10958 /* Supplicant does single channel scan after 8-way handshake
10959 * and in that case driver shoudnt flush scan results. If
10960 * driver flushes the scan results here and unfortunately if
10961 * the AP doesnt respond to our probe req then association
10962 * fails which is not desired
10963 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010964 if ((request->n_ssids == 1)
10965 && (request->ssids != NULL)
10966 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
10967 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010968
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010969 if( is_p2p_scan ||
10970 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010971 {
10972 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
10973 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
10974 pAdapter->sessionId );
10975 }
10976
10977 if( request->ie_len )
10978 {
10979 /* save this for future association (join requires this) */
10980 /*TODO: Array needs to be converted to dynamic allocation,
10981 * as multiple ie.s can be sent in cfg80211_scan_request structure
10982 * CR 597966
10983 */
10984 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
10985 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
10986 pScanInfo->scanAddIE.length = request->ie_len;
10987
10988 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10989 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10990 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010991 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053010992 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070010993 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010994 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
10995 memcpy( pwextBuf->roamProfile.addIEScan,
10996 request->ie, request->ie_len);
10997 }
10998 else
10999 {
11000 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
11001 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011002 }
11003
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011004 }
11005 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
11006 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
11007
11008 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
11009 request->ie_len);
11010 if (pP2pIe != NULL)
11011 {
11012#ifdef WLAN_FEATURE_P2P_DEBUG
11013 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
11014 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
11015 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053011016 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011017 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
11018 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11019 "Go nego completed to Connection is started");
11020 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11021 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053011022 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011023 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
11024 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011025 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011026 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
11027 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11028 "Disconnected state to Connection is started");
11029 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11030 "for 4way Handshake");
11031 }
11032#endif
11033
11034 /* no_cck will be set during p2p find to disable 11b rates */
11035 if(TRUE == request->no_cck)
11036 {
11037 hddLog(VOS_TRACE_LEVEL_INFO,
11038 "%s: This is a P2P Search", __func__);
11039 scanRequest.p2pSearch = 1;
11040
11041 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053011042 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011043 /* set requestType to P2P Discovery */
11044 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
11045 }
11046
11047 /*
11048 Skip Dfs Channel in case of P2P Search
11049 if it is set in ini file
11050 */
11051 if(cfg_param->skipDfsChnlInP2pSearch)
11052 {
11053 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011054 }
11055 else
11056 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011057 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011058 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011059
Agarwal Ashish4f616132013-12-30 23:32:50 +053011060 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011061 }
11062 }
11063
11064 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
11065
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011066#ifdef FEATURE_WLAN_TDLS
11067 /* if tdls disagree scan right now, return immediately.
11068 tdls will schedule the scan when scan is allowed. (return SUCCESS)
11069 or will reject the scan if any TDLS is in progress. (return -EBUSY)
11070 */
11071 status = wlan_hdd_tdls_scan_callback (pAdapter,
11072 wiphy,
11073#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11074 dev,
11075#endif
11076 request);
11077 if(status <= 0)
11078 {
11079 if(!status)
11080 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
11081 "scan rejected %d", __func__, status);
11082 else
11083 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
11084 __func__, status);
11085
11086 return status;
11087 }
11088#endif
11089
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011090 /* acquire the wakelock to avoid the apps suspend during the scan. To
11091 * address the following issues.
11092 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
11093 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
11094 * for long time, this result in apps running at full power for long time.
11095 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
11096 * be stuck in full power because of resume BMPS
11097 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011098 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011099
Nirav Shah20ac06f2013-12-12 18:14:06 +053011100 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11101 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011102 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
11103 scanRequest.requestType, scanRequest.scanType,
11104 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053011105 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
11106
Siddharth Bhal76972212014-10-15 16:22:51 +053011107 if (pHddCtx->spoofMacAddr.isEnabled)
11108 {
11109 hddLog(VOS_TRACE_LEVEL_INFO,
11110 "%s: MAC Spoofing enabled for current scan", __func__);
11111 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
11112 * to fill TxBds for probe request during current scan
11113 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011114 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053011115 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011116
11117 if(status != VOS_STATUS_SUCCESS)
11118 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011119 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011120 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053011121#ifdef FEATURE_WLAN_TDLS
11122 wlan_hdd_tdls_scan_done_callback(pAdapter);
11123#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011124 goto free_mem;
11125 }
Siddharth Bhal76972212014-10-15 16:22:51 +053011126 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053011127 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070011128 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011129 pAdapter->sessionId, &scanRequest, &scanId,
11130 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070011131
Jeff Johnson295189b2012-06-20 16:38:30 -070011132 if (eHAL_STATUS_SUCCESS != status)
11133 {
11134 hddLog(VOS_TRACE_LEVEL_ERROR,
11135 "%s: sme_ScanRequest returned error %d", __func__, status);
11136 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011137 if(eHAL_STATUS_RESOURCES == status)
11138 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011139 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
11140 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011141 status = -EBUSY;
11142 } else {
11143 status = -EIO;
11144 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011145 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011146
11147#ifdef FEATURE_WLAN_TDLS
11148 wlan_hdd_tdls_scan_done_callback(pAdapter);
11149#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011150 goto free_mem;
11151 }
11152
11153 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011154 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011155 pAdapter->request = request;
11156 pScanInfo->scanId = scanId;
11157
11158 complete(&pScanInfo->scan_req_completion_event);
11159
11160free_mem:
11161 if( scanRequest.SSIDs.SSIDList )
11162 {
11163 vos_mem_free(scanRequest.SSIDs.SSIDList);
11164 }
11165
11166 if( channelList )
11167 vos_mem_free( channelList );
11168
11169 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011170 return status;
11171}
11172
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011173int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
11174#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11175 struct net_device *dev,
11176#endif
11177 struct cfg80211_scan_request *request)
11178{
11179 int ret;
11180
11181 vos_ssr_protect(__func__);
11182 ret = __wlan_hdd_cfg80211_scan(wiphy,
11183#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11184 dev,
11185#endif
11186 request);
11187 vos_ssr_unprotect(__func__);
11188
11189 return ret;
11190}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011191
11192void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
11193{
11194 v_U8_t iniDot11Mode =
11195 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
11196 eHddDot11Mode hddDot11Mode = iniDot11Mode;
11197
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011198 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
11199 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011200 switch ( iniDot11Mode )
11201 {
11202 case eHDD_DOT11_MODE_AUTO:
11203 case eHDD_DOT11_MODE_11ac:
11204 case eHDD_DOT11_MODE_11ac_ONLY:
11205#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053011206 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
11207 sme_IsFeatureSupportedByFW(DOT11AC) )
11208 hddDot11Mode = eHDD_DOT11_MODE_11ac;
11209 else
11210 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011211#else
11212 hddDot11Mode = eHDD_DOT11_MODE_11n;
11213#endif
11214 break;
11215 case eHDD_DOT11_MODE_11n:
11216 case eHDD_DOT11_MODE_11n_ONLY:
11217 hddDot11Mode = eHDD_DOT11_MODE_11n;
11218 break;
11219 default:
11220 hddDot11Mode = iniDot11Mode;
11221 break;
11222 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011223#ifdef WLAN_FEATURE_AP_HT40_24G
11224 if (operationChannel > SIR_11B_CHANNEL_END)
11225#endif
11226 {
11227 /* This call decides required channel bonding mode */
11228 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011229 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
11230 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011231 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011232}
11233
Jeff Johnson295189b2012-06-20 16:38:30 -070011234/*
11235 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011236 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011237 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011238int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011239 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070011240{
11241 int status = 0;
11242 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080011243 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011244 v_U32_t roamId;
11245 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070011246 eCsrAuthType RSNAuthType;
11247
11248 ENTER();
11249
11250 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080011251 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11252
11253 status = wlan_hdd_validate_context(pHddCtx);
11254 if (status)
11255 {
Yue Mae36e3552014-03-05 17:06:20 -080011256 return status;
11257 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011258
Jeff Johnson295189b2012-06-20 16:38:30 -070011259 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
11260 {
11261 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
11262 return -EINVAL;
11263 }
11264
11265 pRoamProfile = &pWextState->roamProfile;
11266
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011267 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070011268 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011269 hdd_station_ctx_t *pHddStaCtx;
11270 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011271
Siddharth Bhalda0d1622015-04-24 15:47:49 +053011272 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
11273
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011274 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070011275 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
11276 {
11277 /*QoS not enabled in cfg file*/
11278 pRoamProfile->uapsd_mask = 0;
11279 }
11280 else
11281 {
11282 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011283 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070011284 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
11285 }
11286
11287 pRoamProfile->SSIDs.numOfSSIDs = 1;
11288 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
11289 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011290 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070011291 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
11292 ssid, ssid_len);
11293
11294 if (bssid)
11295 {
11296 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
11297 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
11298 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011299 /* Save BSSID in seperate variable as well, as RoamProfile
11300 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070011301 case of join failure we should send valid BSSID to supplicant
11302 */
11303 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
11304 WNI_CFG_BSSID_LEN);
11305 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070011306 else
11307 {
11308 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
11309 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011310
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011311 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
11312 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011313 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
11314 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011315 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011316 /*set gen ie*/
11317 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
11318 /*set auth*/
11319 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
11320 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011321#ifdef FEATURE_WLAN_WAPI
11322 if (pAdapter->wapi_info.nWapiMode)
11323 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011324 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011325 switch (pAdapter->wapi_info.wapiAuthMode)
11326 {
11327 case WAPI_AUTH_MODE_PSK:
11328 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011329 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011330 pAdapter->wapi_info.wapiAuthMode);
11331 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
11332 break;
11333 }
11334 case WAPI_AUTH_MODE_CERT:
11335 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011336 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011337 pAdapter->wapi_info.wapiAuthMode);
11338 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
11339 break;
11340 }
11341 } // End of switch
11342 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
11343 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
11344 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011345 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011346 pRoamProfile->AuthType.numEntries = 1;
11347 pRoamProfile->EncryptionType.numEntries = 1;
11348 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11349 pRoamProfile->mcEncryptionType.numEntries = 1;
11350 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11351 }
11352 }
11353#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011354#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011355 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011356 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11357 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
11358 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011359 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
11360 sizeof (tSirGtkOffloadParams));
11361 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011362 }
11363#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011364 pRoamProfile->csrPersona = pAdapter->device_mode;
11365
Jeff Johnson32d95a32012-09-10 13:15:23 -070011366 if( operatingChannel )
11367 {
11368 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
11369 pRoamProfile->ChannelInfo.numOfChannels = 1;
11370 }
Chet Lanctot186b5732013-03-18 10:26:30 -070011371 else
11372 {
11373 pRoamProfile->ChannelInfo.ChannelList = NULL;
11374 pRoamProfile->ChannelInfo.numOfChannels = 0;
11375 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011376 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
11377 {
11378 hdd_select_cbmode(pAdapter,operatingChannel);
11379 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011380
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011381 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
11382 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011383 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011384 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011385 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
11386 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011387 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11388 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053011389 {
11390 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11391 "%s: Set HDD connState to eConnectionState_Connecting",
11392 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011393 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
11394 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053011395 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011396 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011397 pAdapter->sessionId, pRoamProfile, &roamId);
11398
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011399 if ((eHAL_STATUS_SUCCESS != status) &&
11400 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11401 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011402
11403 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011404 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
11405 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
11406 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011407 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011408 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011409 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011410
11411 pRoamProfile->ChannelInfo.ChannelList = NULL;
11412 pRoamProfile->ChannelInfo.numOfChannels = 0;
11413
Jeff Johnson295189b2012-06-20 16:38:30 -070011414 }
11415 else
11416 {
11417 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
11418 return -EINVAL;
11419 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011420 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011421 return status;
11422}
11423
11424/*
11425 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
11426 * This function is used to set the authentication type (OPEN/SHARED).
11427 *
11428 */
11429static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
11430 enum nl80211_auth_type auth_type)
11431{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011432 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011433 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11434
11435 ENTER();
11436
11437 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011438 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070011439 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011440 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011441 hddLog(VOS_TRACE_LEVEL_INFO,
11442 "%s: set authentication type to AUTOSWITCH", __func__);
11443 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
11444 break;
11445
11446 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011447#ifdef WLAN_FEATURE_VOWIFI_11R
11448 case NL80211_AUTHTYPE_FT:
11449#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011450 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011451 "%s: set authentication type to OPEN", __func__);
11452 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11453 break;
11454
11455 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011456 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011457 "%s: set authentication type to SHARED", __func__);
11458 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
11459 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011460#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011461 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011462 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011463 "%s: set authentication type to CCKM WPA", __func__);
11464 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
11465 break;
11466#endif
11467
11468
11469 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011470 hddLog(VOS_TRACE_LEVEL_ERROR,
11471 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011472 auth_type);
11473 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
11474 return -EINVAL;
11475 }
11476
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011477 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011478 pHddStaCtx->conn_info.authType;
11479 return 0;
11480}
11481
11482/*
11483 * FUNCTION: wlan_hdd_set_akm_suite
11484 * This function is used to set the key mgmt type(PSK/8021x).
11485 *
11486 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011487static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011488 u32 key_mgmt
11489 )
11490{
11491 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11492 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053011493 /* Should be in ieee802_11_defs.h */
11494#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
11495#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070011496 /*set key mgmt type*/
11497 switch(key_mgmt)
11498 {
11499 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053011500 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011501#ifdef WLAN_FEATURE_VOWIFI_11R
11502 case WLAN_AKM_SUITE_FT_PSK:
11503#endif
11504 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070011505 __func__);
11506 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
11507 break;
11508
11509 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053011510 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011511#ifdef WLAN_FEATURE_VOWIFI_11R
11512 case WLAN_AKM_SUITE_FT_8021X:
11513#endif
11514 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070011515 __func__);
11516 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11517 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011518#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011519#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
11520#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
11521 case WLAN_AKM_SUITE_CCKM:
11522 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
11523 __func__);
11524 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
11525 break;
11526#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070011527#ifndef WLAN_AKM_SUITE_OSEN
11528#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
11529 case WLAN_AKM_SUITE_OSEN:
11530 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
11531 __func__);
11532 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11533 break;
11534#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011535
11536 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011537 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011538 __func__, key_mgmt);
11539 return -EINVAL;
11540
11541 }
11542 return 0;
11543}
11544
11545/*
11546 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011547 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070011548 * (NONE/WEP40/WEP104/TKIP/CCMP).
11549 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011550static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
11551 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070011552 bool ucast
11553 )
11554{
11555 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011556 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011557 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11558
11559 ENTER();
11560
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011561 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011562 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011563 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070011564 __func__, cipher);
11565 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11566 }
11567 else
11568 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011569
Jeff Johnson295189b2012-06-20 16:38:30 -070011570 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011571 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011572 {
11573 case IW_AUTH_CIPHER_NONE:
11574 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11575 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011576
Jeff Johnson295189b2012-06-20 16:38:30 -070011577 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011578 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070011579 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011580
Jeff Johnson295189b2012-06-20 16:38:30 -070011581 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011582 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070011583 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011584
Jeff Johnson295189b2012-06-20 16:38:30 -070011585 case WLAN_CIPHER_SUITE_TKIP:
11586 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
11587 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011588
Jeff Johnson295189b2012-06-20 16:38:30 -070011589 case WLAN_CIPHER_SUITE_CCMP:
11590 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11591 break;
11592#ifdef FEATURE_WLAN_WAPI
11593 case WLAN_CIPHER_SUITE_SMS4:
11594 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
11595 break;
11596#endif
11597
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011598#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011599 case WLAN_CIPHER_SUITE_KRK:
11600 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
11601 break;
11602#endif
11603 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011604 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011605 __func__, cipher);
11606 return -EOPNOTSUPP;
11607 }
11608 }
11609
11610 if (ucast)
11611 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011612 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011613 __func__, encryptionType);
11614 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11615 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011616 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011617 encryptionType;
11618 }
11619 else
11620 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011621 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011622 __func__, encryptionType);
11623 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
11624 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
11625 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
11626 }
11627
11628 return 0;
11629}
11630
11631
11632/*
11633 * FUNCTION: wlan_hdd_cfg80211_set_ie
11634 * This function is used to parse WPA/RSN IE's.
11635 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011636int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011637#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11638 const u8 *ie,
11639#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011640 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011641#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011642 size_t ie_len
11643 )
11644{
11645 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011646#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11647 const u8 *genie = ie;
11648#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011649 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011650#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011651 v_U16_t remLen = ie_len;
11652#ifdef FEATURE_WLAN_WAPI
11653 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
11654 u16 *tmp;
11655 v_U16_t akmsuiteCount;
11656 int *akmlist;
11657#endif
11658 ENTER();
11659
11660 /* clear previous assocAddIE */
11661 pWextState->assocAddIE.length = 0;
11662 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011663 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011664
11665 while (remLen >= 2)
11666 {
11667 v_U16_t eLen = 0;
11668 v_U8_t elementId;
11669 elementId = *genie++;
11670 eLen = *genie++;
11671 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011672
Arif Hussain6d2a3322013-11-17 19:50:10 -080011673 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070011674 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011675
11676 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070011677 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011678 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011679 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 -070011680 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011681 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011682 "%s: Invalid WPA IE", __func__);
11683 return -EINVAL;
11684 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011685 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070011686 {
11687 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011688 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011689 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011690
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011691 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011692 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011693 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
11694 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011695 VOS_ASSERT(0);
11696 return -ENOMEM;
11697 }
11698 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11699 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11700 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011701
Jeff Johnson295189b2012-06-20 16:38:30 -070011702 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
11703 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11704 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11705 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011706 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
11707 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011708 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
11709 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11710 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
11711 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
11712 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
11713 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011714 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053011715 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011716 {
11717 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011718 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011719 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011720
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011721 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011722 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011723 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11724 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011725 VOS_ASSERT(0);
11726 return -ENOMEM;
11727 }
11728 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11729 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11730 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011731
Jeff Johnson295189b2012-06-20 16:38:30 -070011732 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11733 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11734 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011735#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011736 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
11737 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011738 /*Consider WFD IE, only for P2P Client */
11739 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11740 {
11741 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011742 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011743 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011744
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011745 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011746 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011747 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11748 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011749 VOS_ASSERT(0);
11750 return -ENOMEM;
11751 }
11752 // WFD IE is saved to Additional IE ; it should be accumulated to handle
11753 // WPS IE + P2P IE + WFD IE
11754 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11755 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011756
Jeff Johnson295189b2012-06-20 16:38:30 -070011757 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11758 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11759 }
11760#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011761 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011762 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011763 HS20_OUI_TYPE_SIZE)) )
11764 {
11765 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011766 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011767 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011768
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011769 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011770 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011771 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11772 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011773 VOS_ASSERT(0);
11774 return -ENOMEM;
11775 }
11776 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11777 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011778
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011779 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11780 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11781 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011782 /* Appending OSEN Information Element in Assiciation Request */
11783 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
11784 OSEN_OUI_TYPE_SIZE)) )
11785 {
11786 v_U16_t curAddIELen = pWextState->assocAddIE.length;
11787 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
11788 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011789
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011790 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011791 {
11792 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11793 "Need bigger buffer space");
11794 VOS_ASSERT(0);
11795 return -ENOMEM;
11796 }
11797 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11798 pWextState->assocAddIE.length += eLen + 2;
11799
11800 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
11801 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11802 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11803 }
11804
Abhishek Singh4322e622015-06-10 15:42:54 +053011805 /* Update only for WPA IE */
11806 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
11807 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070011808
11809 /* populating as ADDIE in beacon frames */
11810 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011811 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070011812 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
11813 {
11814 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11815 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
11816 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11817 {
11818 hddLog(LOGE,
11819 "Coldn't pass "
11820 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
11821 }
11822 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
11823 else
11824 hddLog(LOGE,
11825 "Could not pass on "
11826 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
11827
11828 /* IBSS mode doesn't contain params->proberesp_ies still
11829 beaconIE's need to be populated in probe response frames */
11830 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
11831 {
11832 u16 rem_probe_resp_ie_len = eLen + 2;
11833 u8 probe_rsp_ie_len[3] = {0};
11834 u8 counter = 0;
11835
11836 /* Check Probe Resp Length if it is greater then 255 then
11837 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
11838 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
11839 not able Store More then 255 bytes into One Variable */
11840
11841 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
11842 {
11843 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
11844 {
11845 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
11846 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
11847 }
11848 else
11849 {
11850 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
11851 rem_probe_resp_ie_len = 0;
11852 }
11853 }
11854
11855 rem_probe_resp_ie_len = 0;
11856
11857 if (probe_rsp_ie_len[0] > 0)
11858 {
11859 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11860 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
11861 (tANI_U8*)(genie - 2),
11862 probe_rsp_ie_len[0], NULL,
11863 eANI_BOOLEAN_FALSE)
11864 == eHAL_STATUS_FAILURE)
11865 {
11866 hddLog(LOGE,
11867 "Could not pass"
11868 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
11869 }
11870 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
11871 }
11872
11873 if (probe_rsp_ie_len[1] > 0)
11874 {
11875 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11876 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
11877 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11878 probe_rsp_ie_len[1], NULL,
11879 eANI_BOOLEAN_FALSE)
11880 == eHAL_STATUS_FAILURE)
11881 {
11882 hddLog(LOGE,
11883 "Could not pass"
11884 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
11885 }
11886 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
11887 }
11888
11889 if (probe_rsp_ie_len[2] > 0)
11890 {
11891 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11892 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
11893 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11894 probe_rsp_ie_len[2], NULL,
11895 eANI_BOOLEAN_FALSE)
11896 == eHAL_STATUS_FAILURE)
11897 {
11898 hddLog(LOGE,
11899 "Could not pass"
11900 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
11901 }
11902 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
11903 }
11904
11905 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11906 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
11907 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11908 {
11909 hddLog(LOGE,
11910 "Could not pass"
11911 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
11912 }
11913 }
11914 else
11915 {
11916 // Reset WNI_CFG_PROBE_RSP Flags
11917 wlan_hdd_reset_prob_rspies(pAdapter);
11918
11919 hddLog(VOS_TRACE_LEVEL_INFO,
11920 "%s: No Probe Response IE received in set beacon",
11921 __func__);
11922 }
11923 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011924 break;
11925 case DOT11F_EID_RSN:
11926 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
11927 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11928 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
11929 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
11930 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
11931 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053011932
11933 /* Appending Extended Capabilities with Interworking bit set
11934 * in Assoc Req.
11935 *
11936 * In assoc req this EXT Cap will only be taken into account if
11937 * interworkingService bit is set to 1. Currently
11938 * driver is only interested in interworkingService capability
11939 * from supplicant. If in future any other EXT Cap info is
11940 * required from supplicat, it needs to be handled while
11941 * sending Assoc Req in LIM.
11942 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011943 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011944 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011945 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011946 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011947 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011948
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011949 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011950 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011951 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11952 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011953 VOS_ASSERT(0);
11954 return -ENOMEM;
11955 }
11956 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11957 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011958
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011959 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11960 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11961 break;
11962 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011963#ifdef FEATURE_WLAN_WAPI
11964 case WLAN_EID_WAPI:
11965 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011966 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011967 pAdapter->wapi_info.nWapiMode);
11968 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011969 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070011970 akmsuiteCount = WPA_GET_LE16(tmp);
11971 tmp = tmp + 1;
11972 akmlist = (int *)(tmp);
11973 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
11974 {
11975 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
11976 }
11977 else
11978 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011979 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070011980 VOS_ASSERT(0);
11981 return -EINVAL;
11982 }
11983
11984 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
11985 {
11986 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011987 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011988 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011989 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011990 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011991 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011992 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011993 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011994 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
11995 }
11996 break;
11997#endif
11998 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011999 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012000 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012001 /* when Unknown IE is received we should break and continue
12002 * to the next IE in the buffer instead we were returning
12003 * so changing this to break */
12004 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070012005 }
12006 genie += eLen;
12007 remLen -= eLen;
12008 }
12009 EXIT();
12010 return 0;
12011}
12012
12013/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012014 * FUNCTION: hdd_isWPAIEPresent
12015 * Parse the received IE to find the WPA IE
12016 *
12017 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012018static bool hdd_isWPAIEPresent(
12019#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
12020 const u8 *ie,
12021#else
12022 u8 *ie,
12023#endif
12024 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012025{
12026 v_U8_t eLen = 0;
12027 v_U16_t remLen = ie_len;
12028 v_U8_t elementId = 0;
12029
12030 while (remLen >= 2)
12031 {
12032 elementId = *ie++;
12033 eLen = *ie++;
12034 remLen -= 2;
12035 if (eLen > remLen)
12036 {
12037 hddLog(VOS_TRACE_LEVEL_ERROR,
12038 "%s: IE length is wrong %d", __func__, eLen);
12039 return FALSE;
12040 }
12041 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
12042 {
12043 /* OUI - 0x00 0X50 0XF2
12044 WPA Information Element - 0x01
12045 WPA version - 0x01*/
12046 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
12047 return TRUE;
12048 }
12049 ie += eLen;
12050 remLen -= eLen;
12051 }
12052 return FALSE;
12053}
12054
12055/*
Jeff Johnson295189b2012-06-20 16:38:30 -070012056 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012057 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012058 * parameters during connect operation.
12059 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012060int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012061 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012062 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012063{
12064 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012065 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012066 ENTER();
12067
12068 /*set wpa version*/
12069 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
12070
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012071 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012072 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053012073 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012074 {
12075 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12076 }
12077 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
12078 {
12079 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12080 }
12081 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012082
12083 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012084 pWextState->wpaVersion);
12085
12086 /*set authentication type*/
12087 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
12088
12089 if (0 > status)
12090 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012091 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012092 "%s: failed to set authentication type ", __func__);
12093 return status;
12094 }
12095
12096 /*set key mgmt type*/
12097 if (req->crypto.n_akm_suites)
12098 {
12099 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
12100 if (0 > status)
12101 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012102 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070012103 __func__);
12104 return status;
12105 }
12106 }
12107
12108 /*set pairwise cipher type*/
12109 if (req->crypto.n_ciphers_pairwise)
12110 {
12111 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
12112 req->crypto.ciphers_pairwise[0], true);
12113 if (0 > status)
12114 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012115 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012116 "%s: failed to set unicast cipher type", __func__);
12117 return status;
12118 }
12119 }
12120 else
12121 {
12122 /*Reset previous cipher suite to none*/
12123 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
12124 if (0 > status)
12125 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012126 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012127 "%s: failed to set unicast cipher type", __func__);
12128 return status;
12129 }
12130 }
12131
12132 /*set group cipher type*/
12133 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
12134 false);
12135
12136 if (0 > status)
12137 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012138 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070012139 __func__);
12140 return status;
12141 }
12142
Chet Lanctot186b5732013-03-18 10:26:30 -070012143#ifdef WLAN_FEATURE_11W
12144 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
12145#endif
12146
Jeff Johnson295189b2012-06-20 16:38:30 -070012147 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
12148 if (req->ie_len)
12149 {
12150 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
12151 if ( 0 > status)
12152 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012153 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012154 __func__);
12155 return status;
12156 }
12157 }
12158
12159 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012160 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012161 {
12162 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
12163 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
12164 )
12165 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012166 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070012167 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
12168 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012169 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012170 __func__);
12171 return -EOPNOTSUPP;
12172 }
12173 else
12174 {
12175 u8 key_len = req->key_len;
12176 u8 key_idx = req->key_idx;
12177
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012178 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012179 && (CSR_MAX_NUM_KEY > key_idx)
12180 )
12181 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012182 hddLog(VOS_TRACE_LEVEL_INFO,
12183 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012184 __func__, key_idx, key_len);
12185 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012186 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012187 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012188 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012189 (u8)key_len;
12190 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
12191 }
12192 }
12193 }
12194 }
12195
12196 return status;
12197}
12198
12199/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012200 * FUNCTION: wlan_hdd_try_disconnect
12201 * This function is used to disconnect from previous
12202 * connection
12203 */
12204static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
12205{
12206 long ret = 0;
12207 hdd_station_ctx_t *pHddStaCtx;
12208 eMib_dot11DesiredBssType connectedBssType;
12209
12210 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12211
12212 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
12213
12214 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
12215 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
12216 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
12217 {
12218 /* Issue disconnect to CSR */
12219 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12220 if( eHAL_STATUS_SUCCESS ==
12221 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12222 pAdapter->sessionId,
12223 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12224 {
12225 ret = wait_for_completion_interruptible_timeout(
12226 &pAdapter->disconnect_comp_var,
12227 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12228 if (0 >= ret)
12229 {
12230 hddLog(LOGE, FL("Failed to receive disconnect event"));
12231 return -EALREADY;
12232 }
12233 }
12234 }
12235 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
12236 {
12237 ret = wait_for_completion_interruptible_timeout(
12238 &pAdapter->disconnect_comp_var,
12239 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12240 if (0 >= ret)
12241 {
12242 hddLog(LOGE, FL("Failed to receive disconnect event"));
12243 return -EALREADY;
12244 }
12245 }
12246
12247 return 0;
12248}
12249
12250/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053012251 * FUNCTION: __wlan_hdd_cfg80211_connect
12252 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070012253 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012254static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012255 struct net_device *ndev,
12256 struct cfg80211_connect_params *req
12257 )
12258{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012259 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012260 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012261 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053012262 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012263
12264 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012265
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012266 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12267 TRACE_CODE_HDD_CFG80211_CONNECT,
12268 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012269 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012270 "%s: device_mode = %s (%d)", __func__,
12271 hdd_device_modetoString(pAdapter->device_mode),
12272 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012273
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012274 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012275 if (!pHddCtx)
12276 {
12277 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12278 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053012279 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012280 }
12281
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012282 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012283 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012284 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012285 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012286 }
12287
Agarwal Ashish51325b52014-06-16 16:50:49 +053012288 if (vos_max_concurrent_connections_reached()) {
12289 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12290 return -ECONNREFUSED;
12291 }
12292
Jeff Johnson295189b2012-06-20 16:38:30 -070012293#ifdef WLAN_BTAMP_FEATURE
12294 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012295 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070012296 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012297 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012298 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012299 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070012300 }
12301#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012302
12303 //If Device Mode is Station Concurrent Sessions Exit BMps
12304 //P2P Mode will be taken care in Open/close adapter
12305 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012306 (vos_concurrent_open_sessions_running())) {
12307 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
12308 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012309 }
12310
12311 /*Try disconnecting if already in connected state*/
12312 status = wlan_hdd_try_disconnect(pAdapter);
12313 if ( 0 > status)
12314 {
12315 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12316 " connection"));
12317 return -EALREADY;
12318 }
12319
Jeff Johnson295189b2012-06-20 16:38:30 -070012320 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012321 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070012322
12323 if ( 0 > status)
12324 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012325 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070012326 __func__);
12327 return status;
12328 }
Mohit Khanna765234a2012-09-11 15:08:35 -070012329 if ( req->channel )
12330 {
12331 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
12332 req->ssid_len, req->bssid,
12333 req->channel->hw_value);
12334 }
12335 else
12336 {
12337 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012338 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070012339 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012340
Sushant Kaushikd7083982015-03-18 14:33:24 +053012341 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012342 {
12343 //ReEnable BMPS if disabled
12344 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
12345 (NULL != pHddCtx))
12346 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012347 if (pHddCtx->hdd_wlan_suspended)
12348 {
12349 hdd_set_pwrparams(pHddCtx);
12350 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012351 //ReEnable Bmps and Imps back
12352 hdd_enable_bmps_imps(pHddCtx);
12353 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053012354 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070012355 return status;
12356 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012357 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012358 EXIT();
12359 return status;
12360}
12361
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012362static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
12363 struct net_device *ndev,
12364 struct cfg80211_connect_params *req)
12365{
12366 int ret;
12367 vos_ssr_protect(__func__);
12368 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
12369 vos_ssr_unprotect(__func__);
12370
12371 return ret;
12372}
Jeff Johnson295189b2012-06-20 16:38:30 -070012373
12374/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012375 * FUNCTION: wlan_hdd_disconnect
12376 * This function is used to issue a disconnect request to SME
12377 */
12378int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
12379{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012380 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012381 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012382 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012383 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012384
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012385 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012386
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012387 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012388 if (0 != status)
12389 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012390 return status;
12391 }
12392
Sushant Kaushikb4834d22015-07-15 15:29:05 +053012393 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
12394 {
12395 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
12396 pAdapter->sessionId);
12397 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012398 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012399
Agarwal Ashish47d18112014-08-04 19:55:07 +053012400 /* Need to apply spin lock before decreasing active sessions
12401 * as there can be chance for double decrement if context switch
12402 * Calls hdd_DisConnectHandler.
12403 */
12404
12405 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012406 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
12407 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012408 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
12409 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053012410 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
12411 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012412
Abhishek Singhf4669da2014-05-26 15:07:49 +053012413 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053012414 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
12415
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012416 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012417
Mihir Shete182a0b22014-08-18 16:08:48 +053012418 /*
12419 * stop tx queues before deleting STA/BSS context from the firmware.
12420 * tx has to be disabled because the firmware can get busy dropping
12421 * the tx frames after BSS/STA has been deleted and will not send
12422 * back a response resulting in WDI timeout
12423 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053012424 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053012425 netif_tx_disable(pAdapter->dev);
12426 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012427
Mihir Shete182a0b22014-08-18 16:08:48 +053012428 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012429 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12430 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012431 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
12432 {
12433 hddLog(VOS_TRACE_LEVEL_INFO,
12434 FL("status = %d, already disconnected"),
12435 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012436
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012437 }
12438 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012439 {
12440 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012441 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012442 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012443 result = -EINVAL;
12444 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012445 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012446 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012447 &pAdapter->disconnect_comp_var,
12448 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012449 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012450 {
12451 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012452 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012453 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012454 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012455 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012456 {
12457 hddLog(VOS_TRACE_LEVEL_ERROR,
12458 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012459 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012460 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012461disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12463 FL("Set HDD connState to eConnectionState_NotConnected"));
12464 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
12465
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012466 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012467 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012468}
12469
12470
12471/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012472 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070012473 * This function is used to issue a disconnect request to SME
12474 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012475static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012476 struct net_device *dev,
12477 u16 reason
12478 )
12479{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012480 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012481 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012482 tCsrRoamProfile *pRoamProfile;
12483 hdd_station_ctx_t *pHddStaCtx;
12484 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012485#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012486 tANI_U8 staIdx;
12487#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012488
Jeff Johnson295189b2012-06-20 16:38:30 -070012489 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012490
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012491 if (!pAdapter) {
12492 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
12493 return -EINVAL;
12494 }
12495
12496 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12497 if (!pHddStaCtx) {
12498 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
12499 return -EINVAL;
12500 }
12501
12502 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12503 status = wlan_hdd_validate_context(pHddCtx);
12504 if (0 != status)
12505 {
12506 return status;
12507 }
12508
12509 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
12510
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012511 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12512 TRACE_CODE_HDD_CFG80211_DISCONNECT,
12513 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012514 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
12515 __func__, hdd_device_modetoString(pAdapter->device_mode),
12516 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012517
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012518 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
12519 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070012520
Jeff Johnson295189b2012-06-20 16:38:30 -070012521 if (NULL != pRoamProfile)
12522 {
12523 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012524 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
12525 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070012526 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012527 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070012528 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012529 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012530 switch(reason)
12531 {
12532 case WLAN_REASON_MIC_FAILURE:
12533 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
12534 break;
12535
12536 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
12537 case WLAN_REASON_DISASSOC_AP_BUSY:
12538 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
12539 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
12540 break;
12541
12542 case WLAN_REASON_PREV_AUTH_NOT_VALID:
12543 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053012544 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070012545 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
12546 break;
12547
Jeff Johnson295189b2012-06-20 16:38:30 -070012548 default:
12549 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
12550 break;
12551 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012552 pScanInfo = &pHddCtx->scan_info;
12553 if (pScanInfo->mScanPending)
12554 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012555 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012556 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012557 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012558 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012559 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012560
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012561#ifdef FEATURE_WLAN_TDLS
12562 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012563 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012564 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012565 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
12566 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012567 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012568 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012569 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012571 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012572 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012573 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012574 status = sme_DeleteTdlsPeerSta(
12575 WLAN_HDD_GET_HAL_CTX(pAdapter),
12576 pAdapter->sessionId,
12577 mac);
12578 if (status != eHAL_STATUS_SUCCESS) {
12579 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
12580 return -EPERM;
12581 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012582 }
12583 }
12584#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012585 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012586 status = wlan_hdd_disconnect(pAdapter, reasonCode);
12587 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070012588 {
12589 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012590 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012591 __func__, (int)status );
12592 return -EINVAL;
12593 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012594 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012595 else
12596 {
12597 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
12598 "called while in %d state", __func__,
12599 pHddStaCtx->conn_info.connState);
12600 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012601 }
12602 else
12603 {
12604 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
12605 }
12606
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012607 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012608 return status;
12609}
12610
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012611static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
12612 struct net_device *dev,
12613 u16 reason
12614 )
12615{
12616 int ret;
12617 vos_ssr_protect(__func__);
12618 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
12619 vos_ssr_unprotect(__func__);
12620
12621 return ret;
12622}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012623
Jeff Johnson295189b2012-06-20 16:38:30 -070012624/*
12625 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012626 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012627 * settings in IBSS mode.
12628 */
12629static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012630 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012631 struct cfg80211_ibss_params *params
12632 )
12633{
12634 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012635 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012636 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12637 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012638
Jeff Johnson295189b2012-06-20 16:38:30 -070012639 ENTER();
12640
12641 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070012642 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070012643
12644 if (params->ie_len && ( NULL != params->ie) )
12645 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012646 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12647 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012648 {
12649 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12650 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12651 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012652 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012653 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012654 tDot11fIEWPA dot11WPAIE;
12655 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012656 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012657
Wilson Yang00256342013-10-10 23:13:38 -070012658 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012659 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12660 params->ie_len, DOT11F_EID_WPA);
12661 if ( NULL != ie )
12662 {
12663 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12664 // Unpack the WPA IE
12665 //Skip past the EID byte and length byte - and four byte WiFi OUI
12666 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
12667 &ie[2+4],
12668 ie[1] - 4,
12669 &dot11WPAIE);
12670 /*Extract the multicast cipher, the encType for unicast
12671 cipher for wpa-none is none*/
12672 encryptionType =
12673 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
12674 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012675 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012676
Jeff Johnson295189b2012-06-20 16:38:30 -070012677 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
12678
12679 if (0 > status)
12680 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012681 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012682 __func__);
12683 return status;
12684 }
12685 }
12686
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012687 pWextState->roamProfile.AuthType.authType[0] =
12688 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012689 eCSR_AUTH_TYPE_OPEN_SYSTEM;
12690
12691 if (params->privacy)
12692 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012693 /* Security enabled IBSS, At this time there is no information available
12694 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070012695 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012696 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070012697 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012698 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070012699 *enable privacy bit in beacons */
12700
12701 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12702 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012703 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
12704 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070012705 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12706 pWextState->roamProfile.EncryptionType.numEntries = 1;
12707 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070012708 return status;
12709}
12710
12711/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012712 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012713 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012714 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012715static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012716 struct net_device *dev,
12717 struct cfg80211_ibss_params *params
12718 )
12719{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012720 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012721 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12722 tCsrRoamProfile *pRoamProfile;
12723 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012724 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12725 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012726 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070012727
12728 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012729
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012730 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12731 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
12732 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012733 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012734 "%s: device_mode = %s (%d)", __func__,
12735 hdd_device_modetoString(pAdapter->device_mode),
12736 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012737
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012738 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012739 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012740 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012741 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012742 }
12743
12744 if (NULL == pWextState)
12745 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012746 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012747 __func__);
12748 return -EIO;
12749 }
12750
Agarwal Ashish51325b52014-06-16 16:50:49 +053012751 if (vos_max_concurrent_connections_reached()) {
12752 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12753 return -ECONNREFUSED;
12754 }
12755
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012756 /*Try disconnecting if already in connected state*/
12757 status = wlan_hdd_try_disconnect(pAdapter);
12758 if ( 0 > status)
12759 {
12760 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12761 " IBSS connection"));
12762 return -EALREADY;
12763 }
12764
Jeff Johnson295189b2012-06-20 16:38:30 -070012765 pRoamProfile = &pWextState->roamProfile;
12766
12767 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
12768 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012769 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012770 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012771 return -EINVAL;
12772 }
12773
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012774 /* BSSID is provided by upper layers hence no need to AUTO generate */
12775 if (NULL != params->bssid) {
12776 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12777 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
12778 hddLog (VOS_TRACE_LEVEL_ERROR,
12779 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12780 return -EIO;
12781 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012782 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012783 }
krunal sonie9002db2013-11-25 14:24:17 -080012784 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
12785 {
12786 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12787 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
12788 {
12789 hddLog (VOS_TRACE_LEVEL_ERROR,
12790 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12791 return -EIO;
12792 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012793
12794 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080012795 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012796 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080012797 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012798
Jeff Johnson295189b2012-06-20 16:38:30 -070012799 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070012800 if (NULL !=
12801#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12802 params->chandef.chan)
12803#else
12804 params->channel)
12805#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012806 {
12807 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012808 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12809 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
12810 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12811 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012812
12813 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012814 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070012815 ieee80211_frequency_to_channel(
12816#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12817 params->chandef.chan->center_freq);
12818#else
12819 params->channel->center_freq);
12820#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012821
12822 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12823 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070012824 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012825 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
12826 __func__);
12827 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012828 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012829
12830 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012831 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012832 if (channelNum == validChan[indx])
12833 {
12834 break;
12835 }
12836 }
12837 if (indx >= numChans)
12838 {
12839 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012840 __func__, channelNum);
12841 return -EINVAL;
12842 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012843 /* Set the Operational Channel */
12844 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
12845 channelNum);
12846 pRoamProfile->ChannelInfo.numOfChannels = 1;
12847 pHddStaCtx->conn_info.operationChannel = channelNum;
12848 pRoamProfile->ChannelInfo.ChannelList =
12849 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070012850 }
12851
12852 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012853 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070012854 if (status < 0)
12855 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012856 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070012857 __func__);
12858 return status;
12859 }
12860
12861 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012862 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012863 params->ssid_len, params->bssid,
12864 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012865
12866 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012867 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012868
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012869 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012870 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012871}
12872
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012873static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
12874 struct net_device *dev,
12875 struct cfg80211_ibss_params *params
12876 )
12877{
12878 int ret = 0;
12879
12880 vos_ssr_protect(__func__);
12881 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
12882 vos_ssr_unprotect(__func__);
12883
12884 return ret;
12885}
12886
Jeff Johnson295189b2012-06-20 16:38:30 -070012887/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012888 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012889 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012890 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012891static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012892 struct net_device *dev
12893 )
12894{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012895 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012896 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12897 tCsrRoamProfile *pRoamProfile;
12898 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012899 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012900
12901 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012902
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012903 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12904 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
12905 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012906 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012907 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012908 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012909 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012910 }
12911
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012912 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
12913 hdd_device_modetoString(pAdapter->device_mode),
12914 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012915 if (NULL == pWextState)
12916 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012917 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012918 __func__);
12919 return -EIO;
12920 }
12921
12922 pRoamProfile = &pWextState->roamProfile;
12923
12924 /* Issue disconnect only if interface type is set to IBSS */
12925 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
12926 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012927 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070012928 __func__);
12929 return -EINVAL;
12930 }
12931
12932 /* Issue Disconnect request */
12933 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12934 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12935 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
12936
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012937 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012938 return 0;
12939}
12940
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012941static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
12942 struct net_device *dev
12943 )
12944{
12945 int ret = 0;
12946
12947 vos_ssr_protect(__func__);
12948 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
12949 vos_ssr_unprotect(__func__);
12950
12951 return ret;
12952}
12953
Jeff Johnson295189b2012-06-20 16:38:30 -070012954/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012955 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070012956 * This function is used to set the phy parameters
12957 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
12958 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012959static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012960 u32 changed)
12961{
12962 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
12963 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012964 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012965
12966 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012967
12968 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012969 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
12970 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012971
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012972 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012973 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012974 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012975 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012976 }
12977
Jeff Johnson295189b2012-06-20 16:38:30 -070012978 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
12979 {
12980 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
12981 WNI_CFG_RTS_THRESHOLD_STAMAX :
12982 wiphy->rts_threshold;
12983
12984 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012985 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070012986 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012987 hddLog(VOS_TRACE_LEVEL_ERROR,
12988 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012989 __func__, rts_threshold);
12990 return -EINVAL;
12991 }
12992
12993 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
12994 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012995 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012996 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012997 hddLog(VOS_TRACE_LEVEL_ERROR,
12998 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012999 __func__, rts_threshold);
13000 return -EIO;
13001 }
13002
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013003 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013004 rts_threshold);
13005 }
13006
13007 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
13008 {
13009 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
13010 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
13011 wiphy->frag_threshold;
13012
13013 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013014 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013015 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013016 hddLog(VOS_TRACE_LEVEL_ERROR,
13017 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013018 frag_threshold);
13019 return -EINVAL;
13020 }
13021
13022 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
13023 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013024 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013025 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013026 hddLog(VOS_TRACE_LEVEL_ERROR,
13027 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013028 __func__, frag_threshold);
13029 return -EIO;
13030 }
13031
13032 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
13033 frag_threshold);
13034 }
13035
13036 if ((changed & WIPHY_PARAM_RETRY_SHORT)
13037 || (changed & WIPHY_PARAM_RETRY_LONG))
13038 {
13039 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
13040 wiphy->retry_short :
13041 wiphy->retry_long;
13042
13043 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
13044 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
13045 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013046 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013047 __func__, retry_value);
13048 return -EINVAL;
13049 }
13050
13051 if (changed & WIPHY_PARAM_RETRY_SHORT)
13052 {
13053 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
13054 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013055 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013056 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013057 hddLog(VOS_TRACE_LEVEL_ERROR,
13058 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013059 __func__, retry_value);
13060 return -EIO;
13061 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013062 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013063 __func__, retry_value);
13064 }
13065 else if (changed & WIPHY_PARAM_RETRY_SHORT)
13066 {
13067 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
13068 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013069 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013070 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013071 hddLog(VOS_TRACE_LEVEL_ERROR,
13072 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013073 __func__, retry_value);
13074 return -EIO;
13075 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013076 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013077 __func__, retry_value);
13078 }
13079 }
13080
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013081 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013082 return 0;
13083}
13084
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013085static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
13086 u32 changed)
13087{
13088 int ret;
13089
13090 vos_ssr_protect(__func__);
13091 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
13092 vos_ssr_unprotect(__func__);
13093
13094 return ret;
13095}
13096
Jeff Johnson295189b2012-06-20 16:38:30 -070013097/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013098 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013099 * This function is used to set the txpower
13100 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013101static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013102#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13103 struct wireless_dev *wdev,
13104#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013105#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013106 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013107#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013108 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013109#endif
13110 int dbm)
13111{
13112 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013113 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013114 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13115 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013116 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013117
13118 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013119
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013120 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13121 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
13122 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013123 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013124 if (0 != status)
13125 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013126 return status;
13127 }
13128
13129 hHal = pHddCtx->hHal;
13130
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013131 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
13132 dbm, ccmCfgSetCallback,
13133 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013134 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013135 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013136 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
13137 return -EIO;
13138 }
13139
13140 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
13141 dbm);
13142
13143 switch(type)
13144 {
13145 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
13146 /* Fall through */
13147 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
13148 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
13149 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013150 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
13151 __func__);
13152 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013153 }
13154 break;
13155 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013156 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070013157 __func__);
13158 return -EOPNOTSUPP;
13159 break;
13160 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013161 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
13162 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070013163 return -EIO;
13164 }
13165
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013166 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013167 return 0;
13168}
13169
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013170static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
13171#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13172 struct wireless_dev *wdev,
13173#endif
13174#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13175 enum tx_power_setting type,
13176#else
13177 enum nl80211_tx_power_setting type,
13178#endif
13179 int dbm)
13180{
13181 int ret;
13182 vos_ssr_protect(__func__);
13183 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
13184#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13185 wdev,
13186#endif
13187#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13188 type,
13189#else
13190 type,
13191#endif
13192 dbm);
13193 vos_ssr_unprotect(__func__);
13194
13195 return ret;
13196}
13197
Jeff Johnson295189b2012-06-20 16:38:30 -070013198/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013199 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013200 * This function is used to read the txpower
13201 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013202static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013203#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13204 struct wireless_dev *wdev,
13205#endif
13206 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070013207{
13208
13209 hdd_adapter_t *pAdapter;
13210 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013211 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013212
Jeff Johnsone7245742012-09-05 17:12:55 -070013213 ENTER();
13214
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013215 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013216 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013217 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013218 *dbm = 0;
13219 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013220 }
13221
Jeff Johnson295189b2012-06-20 16:38:30 -070013222 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
13223 if (NULL == pAdapter)
13224 {
13225 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
13226 return -ENOENT;
13227 }
13228
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053013229 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13230 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
13231 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013232 wlan_hdd_get_classAstats(pAdapter);
13233 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
13234
Jeff Johnsone7245742012-09-05 17:12:55 -070013235 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013236 return 0;
13237}
13238
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013239static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
13240#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13241 struct wireless_dev *wdev,
13242#endif
13243 int *dbm)
13244{
13245 int ret;
13246
13247 vos_ssr_protect(__func__);
13248 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
13249#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13250 wdev,
13251#endif
13252 dbm);
13253 vos_ssr_unprotect(__func__);
13254
13255 return ret;
13256}
13257
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013258static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013259#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13260 const u8* mac,
13261#else
13262 u8* mac,
13263#endif
13264 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070013265{
13266 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13267 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13268 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053013269 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013270
13271 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
13272 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070013273
13274 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
13275 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
13276 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
13277 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
13278 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
13279 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
13280 tANI_U16 maxRate = 0;
13281 tANI_U16 myRate;
13282 tANI_U16 currentRate = 0;
13283 tANI_U8 maxSpeedMCS = 0;
13284 tANI_U8 maxMCSIdx = 0;
13285 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053013286 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013287 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013288 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013289
Leo Chang6f8870f2013-03-26 18:11:36 -070013290#ifdef WLAN_FEATURE_11AC
13291 tANI_U32 vht_mcs_map;
13292 eDataRate11ACMaxMcs vhtMaxMcs;
13293#endif /* WLAN_FEATURE_11AC */
13294
Jeff Johnsone7245742012-09-05 17:12:55 -070013295 ENTER();
13296
Jeff Johnson295189b2012-06-20 16:38:30 -070013297 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
13298 (0 == ssidlen))
13299 {
13300 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
13301 " Invalid ssidlen, %d", __func__, ssidlen);
13302 /*To keep GUI happy*/
13303 return 0;
13304 }
13305
Mukul Sharma811205f2014-07-09 21:07:30 +053013306 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
13307 {
13308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13309 "%s: Roaming in progress, so unable to proceed this request", __func__);
13310 return 0;
13311 }
13312
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013313 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013314 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013315 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013316 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013317 }
13318
Jeff Johnson295189b2012-06-20 16:38:30 -070013319
Kiet Lam3b17fc82013-09-27 05:24:08 +053013320 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
13321 sinfo->filled |= STATION_INFO_SIGNAL;
13322
c_hpothu09f19542014-05-30 21:53:31 +053013323 wlan_hdd_get_station_stats(pAdapter);
13324 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
13325
13326 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053013327 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
13328 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053013329 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053013330 {
13331 rate_flags = pAdapter->maxRateFlags;
13332 }
c_hpothu44ff4e02014-05-08 00:13:57 +053013333
Jeff Johnson295189b2012-06-20 16:38:30 -070013334 //convert to the UI units of 100kbps
13335 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
13336
13337#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070013338 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 -070013339 sinfo->signal,
13340 pCfg->reportMaxLinkSpeed,
13341 myRate,
13342 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013343 (int) pCfg->linkSpeedRssiMid,
13344 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070013345 (int) rate_flags,
13346 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013347#endif //LINKSPEED_DEBUG_ENABLED
13348
13349 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
13350 {
13351 // we do not want to necessarily report the current speed
13352 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
13353 {
13354 // report the max possible speed
13355 rssidx = 0;
13356 }
13357 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
13358 {
13359 // report the max possible speed with RSSI scaling
13360 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
13361 {
13362 // report the max possible speed
13363 rssidx = 0;
13364 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013365 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070013366 {
13367 // report middle speed
13368 rssidx = 1;
13369 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013370 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
13371 {
13372 // report middle speed
13373 rssidx = 2;
13374 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013375 else
13376 {
13377 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013378 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070013379 }
13380 }
13381 else
13382 {
13383 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
13384 hddLog(VOS_TRACE_LEVEL_ERROR,
13385 "%s: Invalid value for reportMaxLinkSpeed: %u",
13386 __func__, pCfg->reportMaxLinkSpeed);
13387 rssidx = 0;
13388 }
13389
13390 maxRate = 0;
13391
13392 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013393 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
13394 OperationalRates, &ORLeng))
13395 {
13396 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13397 /*To keep GUI happy*/
13398 return 0;
13399 }
13400
Jeff Johnson295189b2012-06-20 16:38:30 -070013401 for (i = 0; i < ORLeng; i++)
13402 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013403 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013404 {
13405 /* Validate Rate Set */
13406 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
13407 {
13408 currentRate = supported_data_rate[j].supported_rate[rssidx];
13409 break;
13410 }
13411 }
13412 /* Update MAX rate */
13413 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13414 }
13415
13416 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013417 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
13418 ExtendedRates, &ERLeng))
13419 {
13420 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13421 /*To keep GUI happy*/
13422 return 0;
13423 }
13424
Jeff Johnson295189b2012-06-20 16:38:30 -070013425 for (i = 0; i < ERLeng; i++)
13426 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013427 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013428 {
13429 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
13430 {
13431 currentRate = supported_data_rate[j].supported_rate[rssidx];
13432 break;
13433 }
13434 }
13435 /* Update MAX rate */
13436 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13437 }
c_hpothu79aab322014-07-14 21:11:01 +053013438
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013439 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053013440 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013441 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053013442 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070013443 {
c_hpothu79aab322014-07-14 21:11:01 +053013444 if (rate_flags & eHAL_TX_RATE_VHT80)
13445 mode = 2;
13446 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
13447 mode = 1;
13448 else
13449 mode = 0;
13450
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013451 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
13452 MCSRates, &MCSLeng))
13453 {
13454 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13455 /*To keep GUI happy*/
13456 return 0;
13457 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013458 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070013459#ifdef WLAN_FEATURE_11AC
13460 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013461 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070013462 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013463 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013464 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070013465 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070013466 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013467 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013468 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013469 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070013470 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013471 maxMCSIdx = 7;
13472 }
13473 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
13474 {
13475 maxMCSIdx = 8;
13476 }
13477 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
13478 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013479 //VHT20 is supporting 0~8
13480 if (rate_flags & eHAL_TX_RATE_VHT20)
13481 maxMCSIdx = 8;
13482 else
13483 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070013484 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013485
c_hpothu79aab322014-07-14 21:11:01 +053013486 if (0 != rssidx)/*check for scaled */
13487 {
13488 //get middle rate MCS index if rssi=1/2
13489 for (i=0; i <= maxMCSIdx; i++)
13490 {
13491 if (sinfo->signal <= rssiMcsTbl[mode][i])
13492 {
13493 maxMCSIdx = i;
13494 break;
13495 }
13496 }
13497 }
13498
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013499 if (rate_flags & eHAL_TX_RATE_VHT80)
13500 {
13501 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
13502 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
13503 }
13504 else if (rate_flags & eHAL_TX_RATE_VHT40)
13505 {
13506 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
13507 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
13508 }
13509 else if (rate_flags & eHAL_TX_RATE_VHT20)
13510 {
13511 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
13512 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
13513 }
13514
Leo Chang6f8870f2013-03-26 18:11:36 -070013515 maxSpeedMCS = 1;
13516 if (currentRate > maxRate)
13517 {
13518 maxRate = currentRate;
13519 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013520
Leo Chang6f8870f2013-03-26 18:11:36 -070013521 }
13522 else
13523#endif /* WLAN_FEATURE_11AC */
13524 {
13525 if (rate_flags & eHAL_TX_RATE_HT40)
13526 {
13527 rateFlag |= 1;
13528 }
13529 if (rate_flags & eHAL_TX_RATE_SGI)
13530 {
13531 rateFlag |= 2;
13532 }
13533
Girish Gowli01abcee2014-07-31 20:18:55 +053013534 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053013535 if (rssidx == 1 || rssidx == 2)
13536 {
13537 //get middle rate MCS index if rssi=1/2
13538 for (i=0; i <= 7; i++)
13539 {
13540 if (sinfo->signal <= rssiMcsTbl[mode][i])
13541 {
13542 temp = i+1;
13543 break;
13544 }
13545 }
13546 }
c_hpothu79aab322014-07-14 21:11:01 +053013547
13548 for (i = 0; i < MCSLeng; i++)
13549 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013550 for (j = 0; j < temp; j++)
13551 {
13552 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
13553 {
13554 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053013555 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013556 break;
13557 }
13558 }
13559 if ((j < temp) && (currentRate > maxRate))
13560 {
13561 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070013562 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013563 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053013564 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013565 }
13566 }
13567
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013568 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
13569 {
13570 maxRate = myRate;
13571 maxSpeedMCS = 1;
13572 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13573 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013574 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053013575 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070013576 {
13577 maxRate = myRate;
13578 if (rate_flags & eHAL_TX_RATE_LEGACY)
13579 {
13580 maxSpeedMCS = 0;
13581 }
13582 else
13583 {
13584 maxSpeedMCS = 1;
13585 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13586 }
13587 }
13588
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013589 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070013590 {
13591 sinfo->txrate.legacy = maxRate;
13592#ifdef LINKSPEED_DEBUG_ENABLED
13593 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
13594#endif //LINKSPEED_DEBUG_ENABLED
13595 }
13596 else
13597 {
13598 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070013599#ifdef WLAN_FEATURE_11AC
13600 sinfo->txrate.nss = 1;
13601 if (rate_flags & eHAL_TX_RATE_VHT80)
13602 {
13603 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013604 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070013605 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013606 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070013607 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013608 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13609 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13610 }
13611 else if (rate_flags & eHAL_TX_RATE_VHT20)
13612 {
13613 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13614 }
13615#endif /* WLAN_FEATURE_11AC */
13616 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
13617 {
13618 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13619 if (rate_flags & eHAL_TX_RATE_HT40)
13620 {
13621 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13622 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013623 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013624 if (rate_flags & eHAL_TX_RATE_SGI)
13625 {
13626 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13627 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013628
Jeff Johnson295189b2012-06-20 16:38:30 -070013629#ifdef LINKSPEED_DEBUG_ENABLED
13630 pr_info("Reporting MCS rate %d flags %x\n",
13631 sinfo->txrate.mcs,
13632 sinfo->txrate.flags );
13633#endif //LINKSPEED_DEBUG_ENABLED
13634 }
13635 }
13636 else
13637 {
13638 // report current rate instead of max rate
13639
13640 if (rate_flags & eHAL_TX_RATE_LEGACY)
13641 {
13642 //provide to the UI in units of 100kbps
13643 sinfo->txrate.legacy = myRate;
13644#ifdef LINKSPEED_DEBUG_ENABLED
13645 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
13646#endif //LINKSPEED_DEBUG_ENABLED
13647 }
13648 else
13649 {
13650 //must be MCS
13651 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013652#ifdef WLAN_FEATURE_11AC
13653 sinfo->txrate.nss = 1;
13654 if (rate_flags & eHAL_TX_RATE_VHT80)
13655 {
13656 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13657 }
13658 else
13659#endif /* WLAN_FEATURE_11AC */
13660 {
13661 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13662 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013663 if (rate_flags & eHAL_TX_RATE_SGI)
13664 {
13665 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13666 }
13667 if (rate_flags & eHAL_TX_RATE_HT40)
13668 {
13669 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13670 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013671#ifdef WLAN_FEATURE_11AC
13672 else if (rate_flags & eHAL_TX_RATE_VHT80)
13673 {
13674 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
13675 }
13676#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070013677#ifdef LINKSPEED_DEBUG_ENABLED
13678 pr_info("Reporting actual MCS rate %d flags %x\n",
13679 sinfo->txrate.mcs,
13680 sinfo->txrate.flags );
13681#endif //LINKSPEED_DEBUG_ENABLED
13682 }
13683 }
13684 sinfo->filled |= STATION_INFO_TX_BITRATE;
13685
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013686 sinfo->tx_packets =
13687 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
13688 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
13689 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
13690 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
13691
13692 sinfo->tx_retries =
13693 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
13694 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
13695 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
13696 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
13697
13698 sinfo->tx_failed =
13699 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
13700 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
13701 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
13702 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
13703
13704 sinfo->filled |=
13705 STATION_INFO_TX_PACKETS |
13706 STATION_INFO_TX_RETRIES |
13707 STATION_INFO_TX_FAILED;
13708
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013709 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13710 TRACE_CODE_HDD_CFG80211_GET_STA,
13711 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013712 EXIT();
13713 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013714}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013715#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13716static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13717 const u8* mac, struct station_info *sinfo)
13718#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013719static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13720 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013721#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013722{
13723 int ret;
13724
13725 vos_ssr_protect(__func__);
13726 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
13727 vos_ssr_unprotect(__func__);
13728
13729 return ret;
13730}
13731
13732static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070013733 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070013734{
13735 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013736 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013737 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013738 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013739
Jeff Johnsone7245742012-09-05 17:12:55 -070013740 ENTER();
13741
Jeff Johnson295189b2012-06-20 16:38:30 -070013742 if (NULL == pAdapter)
13743 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013744 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013745 return -ENODEV;
13746 }
13747
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013748 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13749 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
13750 pAdapter->sessionId, timeout));
13751
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013752 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013753 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013754 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013755 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013756 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013757 }
13758
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013759 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
13760 (TRUE == pHddCtx->hdd_wlan_suspended) &&
13761 (pHddCtx->cfg_ini->fhostArpOffload) &&
13762 (eConnectionState_Associated ==
13763 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13764 {
Amar Singhald53568e2013-09-26 11:03:45 -070013765
13766 hddLog(VOS_TRACE_LEVEL_INFO,
13767 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053013768 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013769 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13770 {
13771 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013772 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013773 __func__, vos_status);
13774 }
13775 }
13776
Jeff Johnson295189b2012-06-20 16:38:30 -070013777 /**The get power cmd from the supplicant gets updated by the nl only
13778 *on successful execution of the function call
13779 *we are oppositely mapped w.r.t mode in the driver
13780 **/
13781 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
13782
13783 if (VOS_STATUS_E_FAILURE == vos_status)
13784 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013785 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13786 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013787 return -EINVAL;
13788 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013789 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013790 return 0;
13791}
13792
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013793static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
13794 struct net_device *dev, bool mode, int timeout)
13795{
13796 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013797
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013798 vos_ssr_protect(__func__);
13799 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
13800 vos_ssr_unprotect(__func__);
13801
13802 return ret;
13803}
Jeff Johnson295189b2012-06-20 16:38:30 -070013804#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013805static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
13806 struct net_device *netdev,
13807 u8 key_index)
13808{
13809 ENTER();
13810 return 0;
13811}
13812
Jeff Johnson295189b2012-06-20 16:38:30 -070013813static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013814 struct net_device *netdev,
13815 u8 key_index)
13816{
13817 int ret;
13818 vos_ssr_protect(__func__);
13819 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
13820 vos_ssr_unprotect(__func__);
13821 return ret;
13822}
13823#endif //LINUX_VERSION_CODE
13824
13825#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13826static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13827 struct net_device *dev,
13828 struct ieee80211_txq_params *params)
13829{
13830 ENTER();
13831 return 0;
13832}
13833#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13834static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13835 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013836{
Jeff Johnsone7245742012-09-05 17:12:55 -070013837 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013838 return 0;
13839}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013840#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070013841
13842#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13843static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013844 struct net_device *dev,
13845 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013846{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013847 int ret;
13848
13849 vos_ssr_protect(__func__);
13850 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
13851 vos_ssr_unprotect(__func__);
13852 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013853}
13854#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13855static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
13856 struct ieee80211_txq_params *params)
13857{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013858 int ret;
13859
13860 vos_ssr_protect(__func__);
13861 ret = __wlan_hdd_set_txq_params(wiphy, params);
13862 vos_ssr_unprotect(__func__);
13863 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013864}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013865#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013866
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013867static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013868 struct net_device *dev,
13869 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070013870{
13871 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013872 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013873 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013874 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013875 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013876 v_CONTEXT_t pVosContext = NULL;
13877 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013878
Jeff Johnsone7245742012-09-05 17:12:55 -070013879 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013880
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013881 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070013882 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013883 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013884 return -EINVAL;
13885 }
13886
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013887 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13888 TRACE_CODE_HDD_CFG80211_DEL_STA,
13889 pAdapter->sessionId, pAdapter->device_mode));
13890
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013891 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13892 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013893 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013894 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013895 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013896 }
13897
Jeff Johnson295189b2012-06-20 16:38:30 -070013898 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013899 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013900 )
13901 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013902 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13903 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13904 if(pSapCtx == NULL){
13905 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13906 FL("psapCtx is NULL"));
13907 return -ENOENT;
13908 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013909 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013910 {
13911 v_U16_t i;
13912 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13913 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013914 if ((pSapCtx->aStaInfo[i].isUsed) &&
13915 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070013916 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013917 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013918 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013919 ETHER_ADDR_LEN);
13920
Jeff Johnson295189b2012-06-20 16:38:30 -070013921 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013922 "%s: Delete STA with MAC::"
13923 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013924 __func__,
13925 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
13926 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013927 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013928 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013929 }
13930 }
13931 }
13932 else
13933 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013934
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013935 vos_status = hdd_softap_GetStaId(pAdapter,
13936 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013937 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13938 {
13939 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013940 "%s: Skip this DEL STA as this is not used::"
13941 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013942 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013943 return -ENOENT;
13944 }
13945
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013946 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013947 {
13948 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013949 "%s: Skip this DEL STA as deauth is in progress::"
13950 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013951 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013952 return -ENOENT;
13953 }
13954
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013955 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013956
Jeff Johnson295189b2012-06-20 16:38:30 -070013957 hddLog(VOS_TRACE_LEVEL_INFO,
13958 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013959 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013960 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013961 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013962
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013963 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013964 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13965 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013966 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013967 hddLog(VOS_TRACE_LEVEL_INFO,
13968 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013969 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013970 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013971 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013972 return -ENOENT;
13973 }
13974
Jeff Johnson295189b2012-06-20 16:38:30 -070013975 }
13976 }
13977
13978 EXIT();
13979
13980 return 0;
13981}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013982
13983#ifdef CFG80211_DEL_STA_V2
13984static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13985 struct net_device *dev,
13986 struct station_del_parameters *param)
13987#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013988#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13989static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13990 struct net_device *dev, const u8 *mac)
13991#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013992static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13993 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013994#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013995#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013996{
13997 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013998 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070013999
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014000 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014001
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014002#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014003 if (NULL == param) {
14004 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014005 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014006 return -EINVAL;
14007 }
14008
14009 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
14010 param->subtype, &delStaParams);
14011
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014012#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014013 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014014 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014015#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014016 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
14017
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014018 vos_ssr_unprotect(__func__);
14019
14020 return ret;
14021}
14022
14023static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014024 struct net_device *dev,
14025#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14026 const u8 *mac,
14027#else
14028 u8 *mac,
14029#endif
14030 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014031{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014032 hdd_adapter_t *pAdapter;
14033 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014034 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014035#ifdef FEATURE_WLAN_TDLS
14036 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014037
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014038 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014039
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014040 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14041 if (NULL == pAdapter)
14042 {
14043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14044 "%s: Adapter is NULL",__func__);
14045 return -EINVAL;
14046 }
14047 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14048 status = wlan_hdd_validate_context(pHddCtx);
14049 if (0 != status)
14050 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014051 return status;
14052 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014053
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014054 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14055 TRACE_CODE_HDD_CFG80211_ADD_STA,
14056 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014057 mask = params->sta_flags_mask;
14058
14059 set = params->sta_flags_set;
14060
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014061 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014062 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
14063 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014064
14065 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
14066 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014067 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014068 }
14069 }
14070#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014071 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014072 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014073}
14074
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014075#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14076static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14077 struct net_device *dev, const u8 *mac,
14078 struct station_parameters *params)
14079#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014080static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14081 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014082#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014083{
14084 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014085
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014086 vos_ssr_protect(__func__);
14087 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
14088 vos_ssr_unprotect(__func__);
14089
14090 return ret;
14091}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014092#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070014093
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014094static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070014095 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014096{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014097 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14098 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014099 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014100 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014101 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014102 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070014103
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014104 ENTER();
14105
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014106 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014107 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014108 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014109 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014110 return -EINVAL;
14111 }
14112
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014113 if (!pmksa) {
14114 hddLog(LOGE, FL("pmksa is NULL"));
14115 return -EINVAL;
14116 }
14117
14118 if (!pmksa->bssid || !pmksa->pmkid) {
14119 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
14120 pmksa->bssid, pmksa->pmkid);
14121 return -EINVAL;
14122 }
14123
14124 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
14125 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14126
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014127 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14128 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014129 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014130 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014131 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014132 }
14133
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014134 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014135 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14136
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014137 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
14138 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014139
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014140 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014141 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014142 &pmk_id, 1, FALSE);
14143
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014144 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14145 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
14146 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014147
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014148 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014149 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014150}
14151
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014152static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
14153 struct cfg80211_pmksa *pmksa)
14154{
14155 int ret;
14156
14157 vos_ssr_protect(__func__);
14158 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
14159 vos_ssr_unprotect(__func__);
14160
14161 return ret;
14162}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014163
Wilson Yang6507c4e2013-10-01 20:11:19 -070014164
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014165static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070014166 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014167{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014168 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14169 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014170 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014171 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014172
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014173 ENTER();
14174
Wilson Yang6507c4e2013-10-01 20:11:19 -070014175 /* Validate pAdapter */
14176 if (NULL == pAdapter)
14177 {
14178 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
14179 return -EINVAL;
14180 }
14181
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014182 if (!pmksa) {
14183 hddLog(LOGE, FL("pmksa is NULL"));
14184 return -EINVAL;
14185 }
14186
14187 if (!pmksa->bssid) {
14188 hddLog(LOGE, FL("pmksa->bssid is NULL"));
14189 return -EINVAL;
14190 }
14191
Kiet Lam98c46a12014-10-31 15:34:57 -070014192 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
14193 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14194
Wilson Yang6507c4e2013-10-01 20:11:19 -070014195 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14196 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014197 if (0 != status)
14198 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014199 return status;
14200 }
14201
14202 /*Retrieve halHandle*/
14203 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14204
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014205 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14206 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
14207 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014208 /* Delete the PMKID CSR cache */
14209 if (eHAL_STATUS_SUCCESS !=
14210 sme_RoamDelPMKIDfromCache(halHandle,
14211 pAdapter->sessionId, pmksa->bssid, FALSE)) {
14212 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
14213 MAC_ADDR_ARRAY(pmksa->bssid));
14214 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014215 }
14216
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014217 EXIT();
14218 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014219}
14220
Wilson Yang6507c4e2013-10-01 20:11:19 -070014221
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014222static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
14223 struct cfg80211_pmksa *pmksa)
14224{
14225 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014226
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014227 vos_ssr_protect(__func__);
14228 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
14229 vos_ssr_unprotect(__func__);
14230
14231 return ret;
14232
14233}
14234
14235static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014236{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014237 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14238 tHalHandle halHandle;
14239 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014240 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014241
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014242 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070014243
14244 /* Validate pAdapter */
14245 if (NULL == pAdapter)
14246 {
14247 hddLog(VOS_TRACE_LEVEL_ERROR,
14248 "%s: Invalid Adapter" ,__func__);
14249 return -EINVAL;
14250 }
14251
14252 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14253 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014254 if (0 != status)
14255 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014256 return status;
14257 }
14258
14259 /*Retrieve halHandle*/
14260 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14261
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014262 /* Flush the PMKID cache in CSR */
14263 if (eHAL_STATUS_SUCCESS !=
14264 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
14265 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
14266 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014267 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014268 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080014269 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014270}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014271
14272static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
14273{
14274 int ret;
14275
14276 vos_ssr_protect(__func__);
14277 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
14278 vos_ssr_unprotect(__func__);
14279
14280 return ret;
14281}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014282#endif
14283
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014284#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014285static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14286 struct net_device *dev,
14287 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014288{
14289 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14290 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014291 hdd_context_t *pHddCtx;
14292 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014293
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014294 ENTER();
14295
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014296 if (NULL == pAdapter)
14297 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014298 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014299 return -ENODEV;
14300 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014301 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14302 ret = wlan_hdd_validate_context(pHddCtx);
14303 if (0 != ret)
14304 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014305 return ret;
14306 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014307 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014308 if (NULL == pHddStaCtx)
14309 {
14310 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
14311 return -EINVAL;
14312 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014313
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014314 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14315 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
14316 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014317 // Added for debug on reception of Re-assoc Req.
14318 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
14319 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014320 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014321 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080014322 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014323 }
14324
14325#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080014326 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014327 ftie->ie_len);
14328#endif
14329
14330 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014331 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
14332 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014333 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014334
14335 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014336 return 0;
14337}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014338
14339static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14340 struct net_device *dev,
14341 struct cfg80211_update_ft_ies_params *ftie)
14342{
14343 int ret;
14344
14345 vos_ssr_protect(__func__);
14346 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
14347 vos_ssr_unprotect(__func__);
14348
14349 return ret;
14350}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014351#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014352
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014353#ifdef FEATURE_WLAN_SCAN_PNO
14354
14355void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
14356 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
14357{
14358 int ret;
14359 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
14360 hdd_context_t *pHddCtx;
14361
Nirav Shah80830bf2013-12-31 16:35:12 +053014362 ENTER();
14363
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014364 if (NULL == pAdapter)
14365 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014367 "%s: HDD adapter is Null", __func__);
14368 return ;
14369 }
14370
14371 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14372 if (NULL == pHddCtx)
14373 {
14374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14375 "%s: HDD context is Null!!!", __func__);
14376 return ;
14377 }
14378
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014379 spin_lock(&pHddCtx->schedScan_lock);
14380 if (TRUE == pHddCtx->isWiphySuspended)
14381 {
14382 pHddCtx->isSchedScanUpdatePending = TRUE;
14383 spin_unlock(&pHddCtx->schedScan_lock);
14384 hddLog(VOS_TRACE_LEVEL_INFO,
14385 "%s: Update cfg80211 scan database after it resume", __func__);
14386 return ;
14387 }
14388 spin_unlock(&pHddCtx->schedScan_lock);
14389
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014390 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
14391
14392 if (0 > ret)
14393 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
14394
14395 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014396 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14397 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014398}
14399
14400/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014401 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014402 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014403 */
14404static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
14405{
14406 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14407 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014408 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014409 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14410 int status = 0;
14411 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
14412
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014413 /* The current firmware design does not allow PNO during any
14414 * active sessions. Hence, determine the active sessions
14415 * and return a failure.
14416 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014417 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
14418 {
14419 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014420 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014421
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014422 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
14423 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
14424 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
14425 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
14426 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053014427 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014428 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014429 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014430 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014431 }
14432 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14433 pAdapterNode = pNext;
14434 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014435 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014436}
14437
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014438void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
14439{
14440 hdd_adapter_t *pAdapter = callbackContext;
14441 hdd_context_t *pHddCtx;
14442
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014443 ENTER();
14444
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014445 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
14446 {
14447 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14448 FL("Invalid adapter or adapter has invalid magic"));
14449 return;
14450 }
14451
14452 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14453 if (0 != wlan_hdd_validate_context(pHddCtx))
14454 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014455 return;
14456 }
14457
c_hpothub53c45d2014-08-18 16:53:14 +053014458 if (VOS_STATUS_SUCCESS != status)
14459 {
14460 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014461 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053014462 pHddCtx->isPnoEnable = FALSE;
14463 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014464
14465 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
14466 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014467 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014468}
14469
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014470/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014471 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
14472 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014473 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014474static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014475 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14476{
14477 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014478 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014479 hdd_context_t *pHddCtx;
14480 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014481 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053014482 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
14483 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014484 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14485 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014486 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014487 hdd_config_t *pConfig = NULL;
14488 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014489
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014490 ENTER();
14491
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014492 if (NULL == pAdapter)
14493 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014494 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014495 "%s: HDD adapter is Null", __func__);
14496 return -ENODEV;
14497 }
14498
14499 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014500 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014501
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014502 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014503 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014504 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014505 }
14506
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014507 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014508 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14509 if (NULL == hHal)
14510 {
14511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14512 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014513 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014514 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014515 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14516 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
14517 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053014518 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014519 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053014520 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014521 {
14522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14523 "%s: aborting the existing scan is unsuccessfull", __func__);
14524 return -EBUSY;
14525 }
14526
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014527 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014528 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014530 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014531 return -EBUSY;
14532 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014533
c_hpothu37f21312014-04-09 21:49:54 +053014534 if (TRUE == pHddCtx->isPnoEnable)
14535 {
14536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14537 FL("already PNO is enabled"));
14538 return -EBUSY;
14539 }
c_hpothu225aa7c2014-10-22 17:45:13 +053014540
14541 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
14542 {
14543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14544 "%s: abort ROC failed ", __func__);
14545 return -EBUSY;
14546 }
14547
c_hpothu37f21312014-04-09 21:49:54 +053014548 pHddCtx->isPnoEnable = TRUE;
14549
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014550 pnoRequest.enable = 1; /*Enable PNO */
14551 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014552
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014553 if (( !pnoRequest.ucNetworksCount ) ||
14554 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014555 {
14556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014557 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014558 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014559 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014560 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014561 goto error;
14562 }
14563
14564 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
14565 {
14566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014567 "%s: Incorrect number of channels %d",
14568 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014569 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014570 goto error;
14571 }
14572
14573 /* Framework provides one set of channels(all)
14574 * common for all saved profile */
14575 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14576 channels_allowed, &num_channels_allowed))
14577 {
14578 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14579 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014580 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014581 goto error;
14582 }
14583 /* Checking each channel against allowed channel list */
14584 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053014585 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014586 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014587 char chList [(request->n_channels*5)+1];
14588 int len;
14589 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014590 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014591 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014592 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014593 if (request->channels[i]->hw_value == channels_allowed[indx])
14594 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014595 if ((!pConfig->enableDFSPnoChnlScan) &&
14596 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
14597 {
14598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14599 "%s : Dropping DFS channel : %d",
14600 __func__,channels_allowed[indx]);
14601 num_ignore_dfs_ch++;
14602 break;
14603 }
14604
Nirav Shah80830bf2013-12-31 16:35:12 +053014605 valid_ch[num_ch++] = request->channels[i]->hw_value;
14606 len += snprintf(chList+len, 5, "%d ",
14607 request->channels[i]->hw_value);
14608 break ;
14609 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014610 }
14611 }
Nirav Shah80830bf2013-12-31 16:35:12 +053014612 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014613
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014614 /*If all channels are DFS and dropped, then ignore the PNO request*/
14615 if (num_ignore_dfs_ch == request->n_channels)
14616 {
14617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14618 "%s : All requested channels are DFS channels", __func__);
14619 ret = -EINVAL;
14620 goto error;
14621 }
14622 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014623
14624 pnoRequest.aNetworks =
14625 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14626 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014627 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014628 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14629 FL("failed to allocate memory aNetworks %u"),
14630 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14631 goto error;
14632 }
14633 vos_mem_zero(pnoRequest.aNetworks,
14634 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14635
14636 /* Filling per profile params */
14637 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
14638 {
14639 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014640 request->match_sets[i].ssid.ssid_len;
14641
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014642 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
14643 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014644 {
14645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014646 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014647 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014648 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014649 goto error;
14650 }
14651
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014652 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014653 request->match_sets[i].ssid.ssid,
14654 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14656 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014657 i, pnoRequest.aNetworks[i].ssId.ssId);
14658 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
14659 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
14660 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014661
14662 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014663 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
14664 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014665
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014666 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014667 }
14668
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014669 for (i = 0; i < request->n_ssids; i++)
14670 {
14671 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014672 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014673 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014674 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014675 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014676 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014677 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014678 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014679 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014680 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014681 break;
14682 }
14683 j++;
14684 }
14685 }
14686 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14687 "Number of hidden networks being Configured = %d",
14688 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080014690 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014691
14692 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14693 if (pnoRequest.p24GProbeTemplate == NULL)
14694 {
14695 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14696 FL("failed to allocate memory p24GProbeTemplate %u"),
14697 SIR_PNO_MAX_PB_REQ_SIZE);
14698 goto error;
14699 }
14700
14701 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14702 if (pnoRequest.p5GProbeTemplate == NULL)
14703 {
14704 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14705 FL("failed to allocate memory p5GProbeTemplate %u"),
14706 SIR_PNO_MAX_PB_REQ_SIZE);
14707 goto error;
14708 }
14709
14710 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14711 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14712
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053014713 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
14714 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014715 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014716 pnoRequest.us24GProbeTemplateLen = request->ie_len;
14717 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
14718 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014719
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014720 pnoRequest.us5GProbeTemplateLen = request->ie_len;
14721 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
14722 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014723 }
14724
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014725 /* Driver gets only one time interval which is hardcoded in
14726 * supplicant for 10000ms. Taking power consumption into account 6 timers
14727 * will be used, Timervalue is increased exponentially i.e 10,20,40,
14728 * 80,160,320 secs. And number of scan cycle for each timer
14729 * is configurable through INI param gPNOScanTimerRepeatValue.
14730 * If it is set to 0 only one timer will be used and PNO scan cycle
14731 * will be repeated after each interval specified by supplicant
14732 * till PNO is disabled.
14733 */
14734 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014735 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014736 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014737 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014738 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
14739
14740 tempInterval = (request->interval)/1000;
14741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14742 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
14743 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014744 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014745 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014746 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014747 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014748 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014749 tempInterval *= 2;
14750 }
14751 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014752 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014753
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014754 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014755
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014756 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014757 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
14758 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014759 pAdapter->pno_req_status = 0;
14760
Nirav Shah80830bf2013-12-31 16:35:12 +053014761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14762 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014763 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
14764 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053014765
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014766 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014767 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014768 hdd_cfg80211_sched_scan_done_callback, pAdapter);
14769 if (eHAL_STATUS_SUCCESS != status)
14770 {
14771 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014772 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014773 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014774 goto error;
14775 }
14776
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014777 ret = wait_for_completion_timeout(
14778 &pAdapter->pno_comp_var,
14779 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
14780 if (0 >= ret)
14781 {
14782 // Did not receive the response for PNO enable in time.
14783 // Assuming the PNO enable was success.
14784 // Returning error from here, because we timeout, results
14785 // in side effect of Wifi (Wifi Setting) not to work.
14786 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14787 FL("Timed out waiting for PNO to be Enabled"));
14788 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014789 }
14790
14791 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053014792 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014793
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014794error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14796 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053014797 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014798 if (pnoRequest.aNetworks)
14799 vos_mem_free(pnoRequest.aNetworks);
14800 if (pnoRequest.p24GProbeTemplate)
14801 vos_mem_free(pnoRequest.p24GProbeTemplate);
14802 if (pnoRequest.p5GProbeTemplate)
14803 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014804
14805 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014806 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014807}
14808
14809/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014810 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
14811 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014812 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014813static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
14814 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14815{
14816 int ret;
14817
14818 vos_ssr_protect(__func__);
14819 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
14820 vos_ssr_unprotect(__func__);
14821
14822 return ret;
14823}
14824
14825/*
14826 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
14827 * Function to disable PNO
14828 */
14829static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014830 struct net_device *dev)
14831{
14832 eHalStatus status = eHAL_STATUS_FAILURE;
14833 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14834 hdd_context_t *pHddCtx;
14835 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014836 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014837 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014838
14839 ENTER();
14840
14841 if (NULL == pAdapter)
14842 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014844 "%s: HDD adapter is Null", __func__);
14845 return -ENODEV;
14846 }
14847
14848 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014849
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014850 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014851 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014853 "%s: HDD context is Null", __func__);
14854 return -ENODEV;
14855 }
14856
14857 /* The return 0 is intentional when isLogpInProgress and
14858 * isLoadUnloadInProgress. We did observe a crash due to a return of
14859 * failure in sched_scan_stop , especially for a case where the unload
14860 * of the happens at the same time. The function __cfg80211_stop_sched_scan
14861 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
14862 * success. If it returns a failure , then its next invocation due to the
14863 * clean up of the second interface will have the dev pointer corresponding
14864 * to the first one leading to a crash.
14865 */
14866 if (pHddCtx->isLogpInProgress)
14867 {
14868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14869 "%s: LOGP in Progress. Ignore!!!", __func__);
14870 return ret;
14871 }
14872
Mihir Shete18156292014-03-11 15:38:30 +053014873 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014874 {
14875 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14876 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14877 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014878 }
14879
14880 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14881 if (NULL == hHal)
14882 {
14883 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14884 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014885 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014886 }
14887
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014888 pnoRequest.enable = 0; /* Disable PNO */
14889 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014890
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014891 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14892 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
14893 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014894 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014895 pAdapter->sessionId,
14896 NULL, pAdapter);
14897 if (eHAL_STATUS_SUCCESS != status)
14898 {
14899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14900 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014901 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014902 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014903 }
c_hpothu37f21312014-04-09 21:49:54 +053014904 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014905
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014906error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014907 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014908 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014909
14910 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014911 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014912}
14913
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014914/*
14915 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
14916 * NL interface to disable PNO
14917 */
14918static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
14919 struct net_device *dev)
14920{
14921 int ret;
14922
14923 vos_ssr_protect(__func__);
14924 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
14925 vos_ssr_unprotect(__func__);
14926
14927 return ret;
14928}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014929#endif /*FEATURE_WLAN_SCAN_PNO*/
14930
14931
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014932#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014933#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014934static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14935 struct net_device *dev,
14936 u8 *peer, u8 action_code,
14937 u8 dialog_token,
14938 u16 status_code, u32 peer_capability,
14939 const u8 *buf, size_t len)
14940#else /* TDLS_MGMT_VERSION2 */
14941#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
14942static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14943 struct net_device *dev,
14944 const u8 *peer, u8 action_code,
14945 u8 dialog_token, u16 status_code,
14946 u32 peer_capability, bool initiator,
14947 const u8 *buf, size_t len)
14948#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
14949static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14950 struct net_device *dev,
14951 const u8 *peer, u8 action_code,
14952 u8 dialog_token, u16 status_code,
14953 u32 peer_capability, const u8 *buf,
14954 size_t len)
14955#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
14956static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14957 struct net_device *dev,
14958 u8 *peer, u8 action_code,
14959 u8 dialog_token,
14960 u16 status_code, u32 peer_capability,
14961 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014962#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014963static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14964 struct net_device *dev,
14965 u8 *peer, u8 action_code,
14966 u8 dialog_token,
14967 u16 status_code, const u8 *buf,
14968 size_t len)
14969#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014970#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014971{
14972
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014973 hdd_adapter_t *pAdapter;
14974 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014975 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070014976 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080014977 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070014978 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014979 int ret;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053014980#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014981 u32 peer_capability = 0;
14982#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014983 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014984
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014985 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14986 if (NULL == pAdapter)
14987 {
14988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14989 "%s: Adapter is NULL",__func__);
14990 return -EINVAL;
14991 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014992 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14993 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
14994 pAdapter->sessionId, action_code));
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014995 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014996 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014997 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014999 "Invalid arguments");
15000 return -EINVAL;
15001 }
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015002 if (pHddCtx->isLogpInProgress)
15003 {
15004 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15005 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053015006 wlan_hdd_tdls_set_link_status(pAdapter,
15007 peer,
15008 eTDLS_LINK_IDLE,
15009 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015010 return -EBUSY;
15011 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015012 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
15013 {
15014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15015 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15016 return -EAGAIN;
15017 }
Hoonki Lee27511902013-03-14 18:19:06 -070015018 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015019 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015020 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015021 "%s: TDLS mode is disabled OR not enabled in FW."
15022 MAC_ADDRESS_STR " action %d declined.",
15023 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015024 return -ENOTSUPP;
15025 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015026
Hoonki Lee27511902013-03-14 18:19:06 -070015027 /* other than teardown frame, other mgmt frames are not sent if disabled */
15028 if (SIR_MAC_TDLS_TEARDOWN != action_code)
15029 {
15030 /* if tdls_mode is disabled to respond to peer's request */
15031 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
15032 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015033 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015034 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015035 " TDLS mode is disabled. action %d declined.",
15036 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070015037
15038 return -ENOTSUPP;
15039 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053015040
15041 if (vos_max_concurrent_connections_reached())
15042 {
15043 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15044 return -EINVAL;
15045 }
Hoonki Lee27511902013-03-14 18:19:06 -070015046 }
15047
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015048 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
15049 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053015050 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015051 {
15052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015053 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015054 " TDLS setup is ongoing. action %d declined.",
15055 __func__, MAC_ADDR_ARRAY(peer), action_code);
15056 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015057 }
15058 }
15059
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015060 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
15061 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080015062 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015063 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15064 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015065 {
15066 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
15067 we return error code at 'add_station()'. Hence we have this
15068 check again in addtion to add_station().
15069 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015070 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015071 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015072 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15073 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015074 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
15075 __func__, MAC_ADDR_ARRAY(peer), action_code,
15076 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053015077 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080015078 }
15079 else
15080 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015081 /* maximum reached. tweak to send error code to peer and return
15082 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015083 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015084 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15085 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015086 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
15087 __func__, MAC_ADDR_ARRAY(peer), status_code,
15088 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070015089 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015090 /* fall through to send setup resp with failure status
15091 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015092 }
15093 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015094 else
15095 {
15096 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053015097 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015098 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015099 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015101 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
15102 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015103 return -EPERM;
15104 }
15105 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015106 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015107
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015109 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015110 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
15111 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015112
Hoonki Leea34dd892013-02-05 22:56:02 -080015113 /*Except teardown responder will not be used so just make 0*/
15114 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015115 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080015116 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015117
15118 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015119 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015120
15121 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
15122 responder = pTdlsPeer->is_responder;
15123 else
Hoonki Leea34dd892013-02-05 22:56:02 -080015124 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015126 "%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 -070015127 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
15128 dialog_token, status_code, len);
15129 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080015130 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015131 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015132
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015133 /* For explicit trigger of DIS_REQ come out of BMPS for
15134 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070015135 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015136 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
15137 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070015138 {
15139 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
15140 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015142 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015143 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
15144 if (status != VOS_STATUS_SUCCESS) {
15145 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
15146 }
Hoonki Lee14621352013-04-16 17:51:19 -070015147 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015148 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015149 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015150 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
15151 }
15152 }
Hoonki Lee14621352013-04-16 17:51:19 -070015153 }
15154
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015155 /* make sure doesn't call send_mgmt() while it is pending */
15156 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
15157 {
15158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015159 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015160 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015161 ret = -EBUSY;
15162 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015163 }
15164
15165 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015166 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
15167
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015168 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015169 peer, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015170
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015171 if (VOS_STATUS_SUCCESS != status)
15172 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15174 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015175 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015176 ret = -EINVAL;
15177 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015178 }
15179
Hoonki Leed37cbb32013-04-20 00:31:14 -070015180 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
15181 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
15182
15183 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015184 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070015185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015186 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070015187 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015188 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080015189
15190 if (pHddCtx->isLogpInProgress)
15191 {
15192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15193 "%s: LOGP in Progress. Ignore!!!", __func__);
15194 return -EAGAIN;
15195 }
15196
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015197 ret = -EINVAL;
15198 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015199 }
15200
Gopichand Nakkala05922802013-03-14 12:23:19 -070015201 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070015202 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015203 ret = max_sta_failed;
15204 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070015205 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015206
Hoonki Leea34dd892013-02-05 22:56:02 -080015207 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
15208 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015209 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015210 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15211 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015212 }
15213 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
15214 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015215 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015216 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15217 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015218 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015219
15220 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015221
15222tx_failed:
15223 /* add_station will be called before sending TDLS_SETUP_REQ and
15224 * TDLS_SETUP_RSP and as part of add_station driver will enable
15225 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
15226 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
15227 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
15228 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
15229 */
15230
15231 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
15232 (SIR_MAC_TDLS_SETUP_RSP == action_code))
15233 wlan_hdd_tdls_check_bmps(pAdapter);
15234 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015235}
15236
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015237#if TDLS_MGMT_VERSION2
15238static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15239 u8 *peer, u8 action_code, u8 dialog_token,
15240 u16 status_code, u32 peer_capability,
15241 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015242#else /* TDLS_MGMT_VERSION2 */
15243#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
15244static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15245 struct net_device *dev,
15246 const u8 *peer, u8 action_code,
15247 u8 dialog_token, u16 status_code,
15248 u32 peer_capability, bool initiator,
15249 const u8 *buf, size_t len)
15250#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15251static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15252 struct net_device *dev,
15253 const u8 *peer, u8 action_code,
15254 u8 dialog_token, u16 status_code,
15255 u32 peer_capability, const u8 *buf,
15256 size_t len)
15257#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
15258static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15259 struct net_device *dev,
15260 u8 *peer, u8 action_code,
15261 u8 dialog_token,
15262 u16 status_code, u32 peer_capability,
15263 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015264#else
15265static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15266 u8 *peer, u8 action_code, u8 dialog_token,
15267 u16 status_code, const u8 *buf, size_t len)
15268#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015269#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015270{
15271 int ret;
15272
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015273 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015274#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015275 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15276 dialog_token, status_code,
15277 peer_capability, buf, len);
15278#else /* TDLS_MGMT_VERSION2 */
15279#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
15280 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15281 dialog_token, status_code,
15282 peer_capability, initiator,
15283 buf, len);
15284#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
15285 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15286 dialog_token, status_code,
15287 peer_capability, buf, len);
15288#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
15289 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15290 dialog_token, status_code,
15291 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015292#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015293 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15294 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015295#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015296#endif
15297 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015298
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015299 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015300}
Atul Mittal115287b2014-07-08 13:26:33 +053015301
15302int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015303#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15304 const u8 *peer,
15305#else
Atul Mittal115287b2014-07-08 13:26:33 +053015306 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015307#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015308 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053015309 cfg80211_exttdls_callback callback)
15310{
15311
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015312 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053015313 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015314 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053015315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15316 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
15317 __func__, MAC_ADDR_ARRAY(peer));
15318
15319 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15320 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15321
15322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015323 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15324 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15325 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015326 return -ENOTSUPP;
15327 }
15328
15329 /* To cater the requirement of establishing the TDLS link
15330 * irrespective of the data traffic , get an entry of TDLS peer.
15331 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015332 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015333 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
15334 if (pTdlsPeer == NULL) {
15335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15336 "%s: peer " MAC_ADDRESS_STR " not existing",
15337 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015338 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015339 return -EINVAL;
15340 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015341 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015342
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015343 /* check FW TDLS Off Channel capability */
15344 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015345 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015346 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015347 {
15348 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
15349 pTdlsPeer->peerParams.global_operating_class =
15350 tdls_peer_params->global_operating_class;
15351 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
15352 pTdlsPeer->peerParams.min_bandwidth_kbps =
15353 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015354 /* check configured channel is valid, non dfs and
15355 * not current operating channel */
15356 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
15357 tdls_peer_params->channel)) &&
15358 (pHddStaCtx) &&
15359 (tdls_peer_params->channel !=
15360 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015361 {
15362 pTdlsPeer->isOffChannelConfigured = TRUE;
15363 }
15364 else
15365 {
15366 pTdlsPeer->isOffChannelConfigured = FALSE;
15367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15368 "%s: Configured Tdls Off Channel is not valid", __func__);
15369
15370 }
15371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015372 "%s: tdls_off_channel %d isOffChannelConfigured %d "
15373 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015374 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015375 pTdlsPeer->isOffChannelConfigured,
15376 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015377 }
15378 else
15379 {
15380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015381 "%s: TDLS off channel FW capability %d, "
15382 "host capab %d or Invalid TDLS Peer Params", __func__,
15383 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
15384 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015385 }
15386
Atul Mittal115287b2014-07-08 13:26:33 +053015387 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
15388
15389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15390 " %s TDLS Add Force Peer Failed",
15391 __func__);
15392 return -EINVAL;
15393 }
15394 /*EXT TDLS*/
15395
15396 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
15397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15398 " %s TDLS set callback Failed",
15399 __func__);
15400 return -EINVAL;
15401 }
15402
15403 return(0);
15404
15405}
15406
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015407int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
15408#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15409 const u8 *peer
15410#else
15411 u8 *peer
15412#endif
15413)
Atul Mittal115287b2014-07-08 13:26:33 +053015414{
15415
15416 hddTdlsPeer_t *pTdlsPeer;
15417 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15418 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15419 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
15420 __func__, MAC_ADDR_ARRAY(peer));
15421
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015422 if (0 != wlan_hdd_validate_context(pHddCtx)) {
15423 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
15424 return -EINVAL;
15425 }
15426
Atul Mittal115287b2014-07-08 13:26:33 +053015427 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15428 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15429
15430 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015431 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15432 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15433 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015434 return -ENOTSUPP;
15435 }
15436
15437
15438 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15439
15440 if ( NULL == pTdlsPeer ) {
15441 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015442 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053015443 __func__, MAC_ADDR_ARRAY(peer));
15444 return -EINVAL;
15445 }
15446 else {
15447 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
15448 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015449 /* if channel switch is configured, reset
15450 the channel for this peer */
15451 if (TRUE == pTdlsPeer->isOffChannelConfigured)
15452 {
15453 pTdlsPeer->peerParams.channel = 0;
15454 pTdlsPeer->isOffChannelConfigured = FALSE;
15455 }
Atul Mittal115287b2014-07-08 13:26:33 +053015456 }
15457
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015458 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
15459 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053015460 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015461 }
Atul Mittal115287b2014-07-08 13:26:33 +053015462
15463 /*EXT TDLS*/
15464
15465 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
15466
15467 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15468 " %s TDLS set callback Failed",
15469 __func__);
15470 return -EINVAL;
15471 }
15472 return(0);
15473
15474}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015475static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015476#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15477 const u8 *peer,
15478#else
15479 u8 *peer,
15480#endif
15481 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015482{
15483 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15484 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015485 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015486 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015487
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015488 ENTER();
15489
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015490 if (!pAdapter) {
15491 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15492 return -EINVAL;
15493 }
15494
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015495 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15496 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
15497 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015498 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015499 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070015501 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015502 return -EINVAL;
15503 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015504
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015505 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015506 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015507 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015508 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015509 }
15510
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015511
15512 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015513 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015514 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015515 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015516 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
15517 "Cannot process TDLS commands",
15518 pHddCtx->cfg_ini->fEnableTDLSSupport,
15519 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015520 return -ENOTSUPP;
15521 }
15522
15523 switch (oper) {
15524 case NL80211_TDLS_ENABLE_LINK:
15525 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015526 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015527 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015528 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053015529 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015530 tANI_U16 numCurrTdlsPeers = 0;
15531 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015532 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015533
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015534 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15535 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
15536 __func__, MAC_ADDR_ARRAY(peer));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015537 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015538 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015539 if ( NULL == pTdlsPeer ) {
15540 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15541 " (oper %d) not exsting. ignored",
15542 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15543 return -EINVAL;
15544 }
15545
15546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15547 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15548 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15549 "NL80211_TDLS_ENABLE_LINK");
15550
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070015551 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
15552 {
15553 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
15554 MAC_ADDRESS_STR " failed",
15555 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
15556 return -EINVAL;
15557 }
15558
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053015559 /* before starting tdls connection, set tdls
15560 * off channel established status to default value */
15561 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015562 /* TDLS Off Channel, Disable tdls channel switch,
15563 when there are more than one tdls link */
15564 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053015565 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015566 {
15567 /* get connected peer and send disable tdls off chan */
15568 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015569 if ((connPeer) &&
15570 (connPeer->isOffChannelSupported == TRUE) &&
15571 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015572 {
15573 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15574 "%s: More then one peer connected, Disable "
15575 "TDLS channel switch", __func__);
15576
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015577 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015578 ret = sme_SendTdlsChanSwitchReq(
15579 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015580 pAdapter->sessionId,
15581 connPeer->peerMac,
15582 connPeer->peerParams.channel,
15583 TDLS_OFF_CHANNEL_BW_OFFSET,
15584 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015585 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015586 hddLog(VOS_TRACE_LEVEL_ERROR,
15587 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015588 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015589 }
15590 else
15591 {
15592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15593 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015594 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015595 "isOffChannelConfigured %d",
15596 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015597 (connPeer ? (connPeer->isOffChannelSupported)
15598 : -1),
15599 (connPeer ? (connPeer->isOffChannelConfigured)
15600 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015601 }
15602 }
15603
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015604 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015605 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015606 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053015607
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015608 if (0 != wlan_hdd_tdls_get_link_establish_params(
15609 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015610 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015611 return -EINVAL;
15612 }
15613 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015614
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015615 ret = sme_SendTdlsLinkEstablishParams(
15616 WLAN_HDD_GET_HAL_CTX(pAdapter),
15617 pAdapter->sessionId, peer,
15618 &tdlsLinkEstablishParams);
15619 if (ret != VOS_STATUS_SUCCESS) {
15620 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
15621 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015622 /* Send TDLS peer UAPSD capabilities to the firmware and
15623 * register with the TL on after the response for this operation
15624 * is received .
15625 */
15626 ret = wait_for_completion_interruptible_timeout(
15627 &pAdapter->tdls_link_establish_req_comp,
15628 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
15629 if (ret <= 0)
15630 {
15631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015632 FL("Link Establish Request Failed Status %ld"),
15633 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015634 return -EINVAL;
15635 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015636 }
Atul Mittal115287b2014-07-08 13:26:33 +053015637 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15638 eTDLS_LINK_CONNECTED,
15639 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015640 staDesc.ucSTAId = pTdlsPeer->staId;
15641 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015642 ret = WLANTL_UpdateTdlsSTAClient(
15643 pHddCtx->pvosContext,
15644 &staDesc);
15645 if (ret != VOS_STATUS_SUCCESS) {
15646 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
15647 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053015648
Gopichand Nakkala471708b2013-06-04 20:03:01 +053015649 /* Mark TDLS client Authenticated .*/
15650 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
15651 pTdlsPeer->staId,
15652 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015653 if (VOS_STATUS_SUCCESS == status)
15654 {
Hoonki Lee14621352013-04-16 17:51:19 -070015655 if (pTdlsPeer->is_responder == 0)
15656 {
15657 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
15658
15659 wlan_hdd_tdls_timer_restart(pAdapter,
15660 &pTdlsPeer->initiatorWaitTimeoutTimer,
15661 WAIT_TIME_TDLS_INITIATOR);
15662 /* suspend initiator TX until it receives direct packet from the
15663 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015664 ret = WLANTL_SuspendDataTx(
15665 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15666 &staId, NULL);
15667 if (ret != VOS_STATUS_SUCCESS) {
15668 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
15669 }
Hoonki Lee14621352013-04-16 17:51:19 -070015670 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015671
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015672 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015673 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015674 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015675 suppChannelLen =
15676 tdlsLinkEstablishParams.supportedChannelsLen;
15677
15678 if ((suppChannelLen > 0) &&
15679 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
15680 {
15681 tANI_U8 suppPeerChannel = 0;
15682 int i = 0;
15683 for (i = 0U; i < suppChannelLen; i++)
15684 {
15685 suppPeerChannel =
15686 tdlsLinkEstablishParams.supportedChannels[i];
15687
15688 pTdlsPeer->isOffChannelSupported = FALSE;
15689 if (suppPeerChannel ==
15690 pTdlsPeer->peerParams.channel)
15691 {
15692 pTdlsPeer->isOffChannelSupported = TRUE;
15693 break;
15694 }
15695 }
15696 }
15697 else
15698 {
15699 pTdlsPeer->isOffChannelSupported = FALSE;
15700 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015701 }
15702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15703 "%s: TDLS channel switch request for channel "
15704 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015705 "%d isOffChannelSupported %d", __func__,
15706 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015707 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015708 suppChannelLen,
15709 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015710
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015711 /* TDLS Off Channel, Enable tdls channel switch,
15712 when their is only one tdls link and it supports */
15713 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15714 if ((numCurrTdlsPeers == 1) &&
15715 (TRUE == pTdlsPeer->isOffChannelSupported) &&
15716 (TRUE == pTdlsPeer->isOffChannelConfigured))
15717 {
15718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15719 "%s: Send TDLS channel switch request for channel %d",
15720 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015721
15722 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015723 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
15724 pAdapter->sessionId,
15725 pTdlsPeer->peerMac,
15726 pTdlsPeer->peerParams.channel,
15727 TDLS_OFF_CHANNEL_BW_OFFSET,
15728 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015729 if (ret != VOS_STATUS_SUCCESS) {
15730 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
15731 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015732 }
15733 else
15734 {
15735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15736 "%s: TDLS channel switch request not sent"
15737 " numCurrTdlsPeers %d "
15738 "isOffChannelSupported %d "
15739 "isOffChannelConfigured %d",
15740 __func__, numCurrTdlsPeers,
15741 pTdlsPeer->isOffChannelSupported,
15742 pTdlsPeer->isOffChannelConfigured);
15743 }
15744
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015745 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015746 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015747
15748 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015749 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
15750 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015751 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015752 int ac;
15753 uint8 ucAc[4] = { WLANTL_AC_VO,
15754 WLANTL_AC_VI,
15755 WLANTL_AC_BK,
15756 WLANTL_AC_BE };
15757 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
15758 for(ac=0; ac < 4; ac++)
15759 {
15760 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15761 pTdlsPeer->staId, ucAc[ac],
15762 tlTid[ac], tlTid[ac], 0, 0,
15763 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015764 if (status != VOS_STATUS_SUCCESS) {
15765 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
15766 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015767 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015768 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015769 }
15770
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015771 }
15772 break;
15773 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080015774 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015775 tANI_U16 numCurrTdlsPeers = 0;
15776 hddTdlsPeer_t *connPeer = NULL;
15777
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15779 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
15780 __func__, MAC_ADDR_ARRAY(peer));
15781
Sunil Dutt41de4e22013-11-14 18:09:02 +053015782 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15783
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015784
Sunil Dutt41de4e22013-11-14 18:09:02 +053015785 if ( NULL == pTdlsPeer ) {
15786 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15787 " (oper %d) not exsting. ignored",
15788 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15789 return -EINVAL;
15790 }
15791
15792 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15793 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15794 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15795 "NL80211_TDLS_DISABLE_LINK");
15796
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015797 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080015798 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015799 long status;
15800
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053015801 /* set tdls off channel status to false for this peer */
15802 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053015803 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15804 eTDLS_LINK_TEARING,
15805 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
15806 eTDLS_LINK_UNSPECIFIED:
15807 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015808 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
15809
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015810 status = sme_DeleteTdlsPeerSta(
15811 WLAN_HDD_GET_HAL_CTX(pAdapter),
15812 pAdapter->sessionId, peer );
15813 if (status != VOS_STATUS_SUCCESS) {
15814 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15815 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015816
15817 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
15818 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053015819 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053015820 eTDLS_LINK_IDLE,
15821 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015822 if (status <= 0)
15823 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15825 "%s: Del station failed status %ld",
15826 __func__, status);
15827 return -EPERM;
15828 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015829
15830 /* TDLS Off Channel, Enable tdls channel switch,
15831 when their is only one tdls link and it supports */
15832 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15833 if (numCurrTdlsPeers == 1)
15834 {
15835 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
15836 if ((connPeer) &&
15837 (connPeer->isOffChannelSupported == TRUE) &&
15838 (connPeer->isOffChannelConfigured == TRUE))
15839 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015840 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015841 status = sme_SendTdlsChanSwitchReq(
15842 WLAN_HDD_GET_HAL_CTX(pAdapter),
15843 pAdapter->sessionId,
15844 connPeer->peerMac,
15845 connPeer->peerParams.channel,
15846 TDLS_OFF_CHANNEL_BW_OFFSET,
15847 TDLS_CHANNEL_SWITCH_ENABLE);
15848 if (status != VOS_STATUS_SUCCESS) {
15849 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
15850 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015851 }
15852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15853 "%s: TDLS channel switch "
15854 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015855 "isOffChannelConfigured %d "
15856 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015857 __func__,
15858 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015859 (connPeer ? connPeer->isOffChannelConfigured : -1),
15860 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015861 }
15862 else
15863 {
15864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15865 "%s: TDLS channel switch request not sent "
15866 "numCurrTdlsPeers %d ",
15867 __func__, numCurrTdlsPeers);
15868 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015869 }
15870 else
15871 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015872 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15873 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080015874 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015875 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015876 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015877 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015878 {
Atul Mittal115287b2014-07-08 13:26:33 +053015879 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015880
Atul Mittal115287b2014-07-08 13:26:33 +053015881 if (0 != status)
15882 {
15883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015884 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053015885 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015886 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053015887 break;
15888 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015889 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015890 {
Atul Mittal115287b2014-07-08 13:26:33 +053015891 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
15892 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015893 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053015894 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015895
Atul Mittal115287b2014-07-08 13:26:33 +053015896 if (0 != status)
15897 {
15898 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015899 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053015900 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053015901 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053015902 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015903 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015904 case NL80211_TDLS_DISCOVERY_REQ:
15905 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015907 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015908 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015909 return -ENOTSUPP;
15910 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015911 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15912 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015913 return -ENOTSUPP;
15914 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015915
15916 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015917 return 0;
15918}
Chilam NG571c65a2013-01-19 12:27:36 +053015919
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015920static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015921#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15922 const u8 *peer,
15923#else
15924 u8 *peer,
15925#endif
15926 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015927{
15928 int ret;
15929
15930 vos_ssr_protect(__func__);
15931 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
15932 vos_ssr_unprotect(__func__);
15933
15934 return ret;
15935}
15936
Chilam NG571c65a2013-01-19 12:27:36 +053015937int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
15938 struct net_device *dev, u8 *peer)
15939{
Arif Hussaina7c8e412013-11-20 11:06:42 -080015940 hddLog(VOS_TRACE_LEVEL_INFO,
15941 "tdls send discover req: "MAC_ADDRESS_STR,
15942 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053015943
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015944#if TDLS_MGMT_VERSION2
15945 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15946 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15947#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015948#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
15949 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15950 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
15951#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15952 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15953 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15954#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
15955 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15956 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15957#else
Chilam NG571c65a2013-01-19 12:27:36 +053015958 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15959 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015960#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015961#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053015962}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015963#endif
15964
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015965#ifdef WLAN_FEATURE_GTK_OFFLOAD
15966/*
15967 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
15968 * Callback rountine called upon receiving response for
15969 * get offload info
15970 */
15971void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
15972 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
15973{
15974
15975 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015976 tANI_U8 tempReplayCounter[8];
15977 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015978
15979 ENTER();
15980
15981 if (NULL == pAdapter)
15982 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053015983 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015984 "%s: HDD adapter is Null", __func__);
15985 return ;
15986 }
15987
15988 if (NULL == pGtkOffloadGetInfoRsp)
15989 {
15990 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15991 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
15992 return ;
15993 }
15994
15995 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
15996 {
15997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15998 "%s: wlan Failed to get replay counter value",
15999 __func__);
16000 return ;
16001 }
16002
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016003 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16004 /* Update replay counter */
16005 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
16006 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16007
16008 {
16009 /* changing from little to big endian since supplicant
16010 * works on big endian format
16011 */
16012 int i;
16013 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16014
16015 for (i = 0; i < 8; i++)
16016 {
16017 tempReplayCounter[7-i] = (tANI_U8)p[i];
16018 }
16019 }
16020
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016021 /* Update replay counter to NL */
16022 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016023 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016024}
16025
16026/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016027 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016028 * This function is used to offload GTK rekeying job to the firmware.
16029 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016030int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016031 struct cfg80211_gtk_rekey_data *data)
16032{
16033 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16034 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16035 hdd_station_ctx_t *pHddStaCtx;
16036 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016037 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016038 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016039 eHalStatus status = eHAL_STATUS_FAILURE;
16040
16041 ENTER();
16042
16043 if (NULL == pAdapter)
16044 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016045 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016046 "%s: HDD adapter is Null", __func__);
16047 return -ENODEV;
16048 }
16049
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016050 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16051 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
16052 pAdapter->sessionId, pAdapter->device_mode));
16053
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016054 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016055 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016056 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016057 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016058 }
16059
16060 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16061 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16062 if (NULL == hHal)
16063 {
16064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16065 "%s: HAL context is Null!!!", __func__);
16066 return -EAGAIN;
16067 }
16068
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016069 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
16070 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
16071 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
16072 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016073 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016074 {
16075 /* changing from big to little endian since driver
16076 * works on little endian format
16077 */
16078 tANI_U8 *p =
16079 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
16080 int i;
16081
16082 for (i = 0; i < 8; i++)
16083 {
16084 p[7-i] = data->replay_ctr[i];
16085 }
16086 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016087
16088 if (TRUE == pHddCtx->hdd_wlan_suspended)
16089 {
16090 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016091 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
16092 sizeof (tSirGtkOffloadParams));
16093 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016094 pAdapter->sessionId);
16095
16096 if (eHAL_STATUS_SUCCESS != status)
16097 {
16098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16099 "%s: sme_SetGTKOffload failed, returned %d",
16100 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016101
16102 /* Need to clear any trace of key value in the memory.
16103 * Thus zero out the memory even though it is local
16104 * variable.
16105 */
16106 vos_mem_zero(&hddGtkOffloadReqParams,
16107 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016108 return status;
16109 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16111 "%s: sme_SetGTKOffload successfull", __func__);
16112 }
16113 else
16114 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016115 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16116 "%s: wlan not suspended GTKOffload request is stored",
16117 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016118 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016119
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016120 /* Need to clear any trace of key value in the memory.
16121 * Thus zero out the memory even though it is local
16122 * variable.
16123 */
16124 vos_mem_zero(&hddGtkOffloadReqParams,
16125 sizeof(hddGtkOffloadReqParams));
16126
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016127 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016128 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016129}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016130
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016131int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
16132 struct cfg80211_gtk_rekey_data *data)
16133{
16134 int ret;
16135
16136 vos_ssr_protect(__func__);
16137 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
16138 vos_ssr_unprotect(__func__);
16139
16140 return ret;
16141}
16142#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016143/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016144 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016145 * This function is used to set access control policy
16146 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016147static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16148 struct net_device *dev,
16149 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016150{
16151 int i;
16152 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16153 hdd_hostapd_state_t *pHostapdState;
16154 tsap_Config_t *pConfig;
16155 v_CONTEXT_t pVosContext = NULL;
16156 hdd_context_t *pHddCtx;
16157 int status;
16158
16159 ENTER();
16160
16161 if (NULL == pAdapter)
16162 {
16163 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16164 "%s: HDD adapter is Null", __func__);
16165 return -ENODEV;
16166 }
16167
16168 if (NULL == params)
16169 {
16170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16171 "%s: params is Null", __func__);
16172 return -EINVAL;
16173 }
16174
16175 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16176 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016177 if (0 != status)
16178 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016179 return status;
16180 }
16181
16182 pVosContext = pHddCtx->pvosContext;
16183 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
16184
16185 if (NULL == pHostapdState)
16186 {
16187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16188 "%s: pHostapdState is Null", __func__);
16189 return -EINVAL;
16190 }
16191
16192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
16193 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016194 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16195 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
16196 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016197
16198 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
16199 {
16200 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
16201
16202 /* default value */
16203 pConfig->num_accept_mac = 0;
16204 pConfig->num_deny_mac = 0;
16205
16206 /**
16207 * access control policy
16208 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
16209 * listed in hostapd.deny file.
16210 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
16211 * listed in hostapd.accept file.
16212 */
16213 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
16214 {
16215 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
16216 }
16217 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
16218 {
16219 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
16220 }
16221 else
16222 {
16223 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16224 "%s:Acl Policy : %d is not supported",
16225 __func__, params->acl_policy);
16226 return -ENOTSUPP;
16227 }
16228
16229 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
16230 {
16231 pConfig->num_accept_mac = params->n_acl_entries;
16232 for (i = 0; i < params->n_acl_entries; i++)
16233 {
16234 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16235 "** Add ACL MAC entry %i in WhiletList :"
16236 MAC_ADDRESS_STR, i,
16237 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16238
16239 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
16240 sizeof(qcmacaddr));
16241 }
16242 }
16243 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
16244 {
16245 pConfig->num_deny_mac = params->n_acl_entries;
16246 for (i = 0; i < params->n_acl_entries; i++)
16247 {
16248 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16249 "** Add ACL MAC entry %i in BlackList :"
16250 MAC_ADDRESS_STR, i,
16251 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16252
16253 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
16254 sizeof(qcmacaddr));
16255 }
16256 }
16257
16258 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
16259 {
16260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16261 "%s: SAP Set Mac Acl fail", __func__);
16262 return -EINVAL;
16263 }
16264 }
16265 else
16266 {
16267 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016268 "%s: Invalid device_mode = %s (%d)",
16269 __func__, hdd_device_modetoString(pAdapter->device_mode),
16270 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016271 return -EINVAL;
16272 }
16273
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016274 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016275 return 0;
16276}
16277
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016278static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16279 struct net_device *dev,
16280 const struct cfg80211_acl_data *params)
16281{
16282 int ret;
16283 vos_ssr_protect(__func__);
16284 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
16285 vos_ssr_unprotect(__func__);
16286
16287 return ret;
16288}
16289
Leo Chang9056f462013-08-01 19:21:11 -070016290#ifdef WLAN_NL80211_TESTMODE
16291#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070016292void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070016293(
16294 void *pAdapter,
16295 void *indCont
16296)
16297{
Leo Changd9df8aa2013-09-26 13:32:26 -070016298 tSirLPHBInd *lphbInd;
16299 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053016300 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070016301
16302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016303 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070016304
c_hpothu73f35e62014-04-18 13:40:08 +053016305 if (pAdapter == NULL)
16306 {
16307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16308 "%s: pAdapter is NULL\n",__func__);
16309 return;
16310 }
16311
Leo Chang9056f462013-08-01 19:21:11 -070016312 if (NULL == indCont)
16313 {
16314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016315 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070016316 return;
16317 }
16318
c_hpothu73f35e62014-04-18 13:40:08 +053016319 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070016320 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070016321 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053016322 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070016323 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070016324 GFP_ATOMIC);
16325 if (!skb)
16326 {
16327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16328 "LPHB timeout, NL buffer alloc fail");
16329 return;
16330 }
16331
Leo Changac3ba772013-10-07 09:47:04 -070016332 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070016333 {
16334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16335 "WLAN_HDD_TM_ATTR_CMD put fail");
16336 goto nla_put_failure;
16337 }
Leo Changac3ba772013-10-07 09:47:04 -070016338 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070016339 {
16340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16341 "WLAN_HDD_TM_ATTR_TYPE put fail");
16342 goto nla_put_failure;
16343 }
Leo Changac3ba772013-10-07 09:47:04 -070016344 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070016345 sizeof(tSirLPHBInd), lphbInd))
16346 {
16347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16348 "WLAN_HDD_TM_ATTR_DATA put fail");
16349 goto nla_put_failure;
16350 }
Leo Chang9056f462013-08-01 19:21:11 -070016351 cfg80211_testmode_event(skb, GFP_ATOMIC);
16352 return;
16353
16354nla_put_failure:
16355 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16356 "NLA Put fail");
16357 kfree_skb(skb);
16358
16359 return;
16360}
16361#endif /* FEATURE_WLAN_LPHB */
16362
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016363static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070016364{
16365 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
16366 int err = 0;
16367#ifdef FEATURE_WLAN_LPHB
16368 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070016369 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016370
16371 ENTER();
16372
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016373 err = wlan_hdd_validate_context(pHddCtx);
16374 if (0 != err)
16375 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016376 return err;
16377 }
Leo Chang9056f462013-08-01 19:21:11 -070016378#endif /* FEATURE_WLAN_LPHB */
16379
16380 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
16381 if (err)
16382 {
16383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16384 "%s Testmode INV ATTR", __func__);
16385 return err;
16386 }
16387
16388 if (!tb[WLAN_HDD_TM_ATTR_CMD])
16389 {
16390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16391 "%s Testmode INV CMD", __func__);
16392 return -EINVAL;
16393 }
16394
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016395 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16396 TRACE_CODE_HDD_CFG80211_TESTMODE,
16397 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070016398 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
16399 {
16400#ifdef FEATURE_WLAN_LPHB
16401 /* Low Power Heartbeat configuration request */
16402 case WLAN_HDD_TM_CMD_WLAN_HB:
16403 {
16404 int buf_len;
16405 void *buf;
16406 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080016407 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070016408
16409 if (!tb[WLAN_HDD_TM_ATTR_DATA])
16410 {
16411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16412 "%s Testmode INV DATA", __func__);
16413 return -EINVAL;
16414 }
16415
16416 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
16417 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080016418
16419 hb_params_temp =(tSirLPHBReq *)buf;
16420 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
16421 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
16422 return -EINVAL;
16423
Leo Chang9056f462013-08-01 19:21:11 -070016424 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
16425 if (NULL == hb_params)
16426 {
16427 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16428 "%s Request Buffer Alloc Fail", __func__);
16429 return -EINVAL;
16430 }
16431
16432 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070016433 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
16434 hb_params,
16435 wlan_hdd_cfg80211_lphb_ind_handler);
16436 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070016437 {
Leo Changd9df8aa2013-09-26 13:32:26 -070016438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16439 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070016440 vos_mem_free(hb_params);
16441 }
Leo Chang9056f462013-08-01 19:21:11 -070016442 return 0;
16443 }
16444#endif /* FEATURE_WLAN_LPHB */
16445 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16447 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070016448 return -EOPNOTSUPP;
16449 }
16450
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016451 EXIT();
16452 return err;
Leo Chang9056f462013-08-01 19:21:11 -070016453}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016454
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053016455static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
16456#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
16457 struct wireless_dev *wdev,
16458#endif
16459 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016460{
16461 int ret;
16462
16463 vos_ssr_protect(__func__);
16464 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
16465 vos_ssr_unprotect(__func__);
16466
16467 return ret;
16468}
Leo Chang9056f462013-08-01 19:21:11 -070016469#endif /* CONFIG_NL80211_TESTMODE */
16470
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016471static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016472 struct net_device *dev,
16473 int idx, struct survey_info *survey)
16474{
16475 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16476 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053016477 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016478 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053016479 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016480 v_S7_t snr,rssi;
16481 int status, i, j, filled = 0;
16482
16483 ENTER();
16484
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016485 if (NULL == pAdapter)
16486 {
16487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16488 "%s: HDD adapter is Null", __func__);
16489 return -ENODEV;
16490 }
16491
16492 if (NULL == wiphy)
16493 {
16494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16495 "%s: wiphy is Null", __func__);
16496 return -ENODEV;
16497 }
16498
16499 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16500 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016501 if (0 != status)
16502 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016503 return status;
16504 }
16505
Mihir Sheted9072e02013-08-21 17:02:29 +053016506 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16507
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016508 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053016509 0 != pAdapter->survey_idx ||
16510 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016511 {
16512 /* The survey dump ops when implemented completely is expected to
16513 * return a survey of all channels and the ops is called by the
16514 * kernel with incremental values of the argument 'idx' till it
16515 * returns -ENONET. But we can only support the survey for the
16516 * operating channel for now. survey_idx is used to track
16517 * that the ops is called only once and then return -ENONET for
16518 * the next iteration
16519 */
16520 pAdapter->survey_idx = 0;
16521 return -ENONET;
16522 }
16523
Mukul Sharma9d5233b2015-06-11 20:28:20 +053016524 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16525 {
16526 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16527 "%s: Roaming in progress, hence return ", __func__);
16528 return -ENONET;
16529 }
16530
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016531 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16532
16533 wlan_hdd_get_snr(pAdapter, &snr);
16534 wlan_hdd_get_rssi(pAdapter, &rssi);
16535
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016536 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16537 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
16538 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016539 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
16540 hdd_wlan_get_freq(channel, &freq);
16541
16542
16543 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
16544 {
16545 if (NULL == wiphy->bands[i])
16546 {
16547 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
16548 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
16549 continue;
16550 }
16551
16552 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
16553 {
16554 struct ieee80211_supported_band *band = wiphy->bands[i];
16555
16556 if (band->channels[j].center_freq == (v_U16_t)freq)
16557 {
16558 survey->channel = &band->channels[j];
16559 /* The Rx BDs contain SNR values in dB for the received frames
16560 * while the supplicant expects noise. So we calculate and
16561 * return the value of noise (dBm)
16562 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
16563 */
16564 survey->noise = rssi - snr;
16565 survey->filled = SURVEY_INFO_NOISE_DBM;
16566 filled = 1;
16567 }
16568 }
16569 }
16570
16571 if (filled)
16572 pAdapter->survey_idx = 1;
16573 else
16574 {
16575 pAdapter->survey_idx = 0;
16576 return -ENONET;
16577 }
16578
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016579 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016580 return 0;
16581}
16582
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016583static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
16584 struct net_device *dev,
16585 int idx, struct survey_info *survey)
16586{
16587 int ret;
16588
16589 vos_ssr_protect(__func__);
16590 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
16591 vos_ssr_unprotect(__func__);
16592
16593 return ret;
16594}
16595
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016596/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016597 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016598 * this is called when cfg80211 driver resume
16599 * driver updates latest sched_scan scan result(if any) to cfg80211 database
16600 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016601int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016602{
16603 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16604 hdd_adapter_t *pAdapter;
16605 hdd_adapter_list_node_t *pAdapterNode, *pNext;
16606 VOS_STATUS status = VOS_STATUS_SUCCESS;
16607
16608 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016609
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016610 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016611 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016612 return 0;
16613 }
16614
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016615 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
16616 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016617 spin_lock(&pHddCtx->schedScan_lock);
16618 pHddCtx->isWiphySuspended = FALSE;
16619 if (TRUE != pHddCtx->isSchedScanUpdatePending)
16620 {
16621 spin_unlock(&pHddCtx->schedScan_lock);
16622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16623 "%s: Return resume is not due to PNO indication", __func__);
16624 return 0;
16625 }
16626 // Reset flag to avoid updatating cfg80211 data old results again
16627 pHddCtx->isSchedScanUpdatePending = FALSE;
16628 spin_unlock(&pHddCtx->schedScan_lock);
16629
16630 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
16631
16632 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
16633 {
16634 pAdapter = pAdapterNode->pAdapter;
16635 if ( (NULL != pAdapter) &&
16636 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
16637 {
16638 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016639 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16641 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016642 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016643 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016644 {
16645 /* Acquire wakelock to handle the case where APP's tries to
16646 * suspend immediately after updating the scan results. Whis
16647 * results in app's is in suspended state and not able to
16648 * process the connect request to AP
16649 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053016650 hdd_prevent_suspend_timeout(2000,
16651 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016652 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016653 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016654
16655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16656 "%s : cfg80211 scan result database updated", __func__);
16657
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016658 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016659 return 0;
16660
16661 }
16662 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16663 pAdapterNode = pNext;
16664 }
16665
16666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16667 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016668 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016669 return 0;
16670}
16671
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016672int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
16673{
16674 int ret;
16675
16676 vos_ssr_protect(__func__);
16677 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
16678 vos_ssr_unprotect(__func__);
16679
16680 return ret;
16681}
16682
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016683/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016684 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016685 * this is called when cfg80211 driver suspends
16686 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016687int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016688 struct cfg80211_wowlan *wow)
16689{
16690 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016691 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016692
16693 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016694
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016695 ret = wlan_hdd_validate_context(pHddCtx);
16696 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016697 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016698 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016699 }
16700
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016701
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016702 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16703 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
16704 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016705 pHddCtx->isWiphySuspended = TRUE;
16706
16707 EXIT();
16708
16709 return 0;
16710}
16711
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016712int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
16713 struct cfg80211_wowlan *wow)
16714{
16715 int ret;
16716
16717 vos_ssr_protect(__func__);
16718 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
16719 vos_ssr_unprotect(__func__);
16720
16721 return ret;
16722}
Jeff Johnson295189b2012-06-20 16:38:30 -070016723/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016724static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070016725{
16726 .add_virtual_intf = wlan_hdd_add_virtual_intf,
16727 .del_virtual_intf = wlan_hdd_del_virtual_intf,
16728 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
16729 .change_station = wlan_hdd_change_station,
16730#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
16731 .add_beacon = wlan_hdd_cfg80211_add_beacon,
16732 .del_beacon = wlan_hdd_cfg80211_del_beacon,
16733 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016734#else
16735 .start_ap = wlan_hdd_cfg80211_start_ap,
16736 .change_beacon = wlan_hdd_cfg80211_change_beacon,
16737 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070016738#endif
16739 .change_bss = wlan_hdd_cfg80211_change_bss,
16740 .add_key = wlan_hdd_cfg80211_add_key,
16741 .get_key = wlan_hdd_cfg80211_get_key,
16742 .del_key = wlan_hdd_cfg80211_del_key,
16743 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016744#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070016745 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016746#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016747 .scan = wlan_hdd_cfg80211_scan,
16748 .connect = wlan_hdd_cfg80211_connect,
16749 .disconnect = wlan_hdd_cfg80211_disconnect,
16750 .join_ibss = wlan_hdd_cfg80211_join_ibss,
16751 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
16752 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
16753 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
16754 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070016755 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
16756 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053016757 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070016758#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16759 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
16760 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
16761 .set_txq_params = wlan_hdd_set_txq_params,
16762#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016763 .get_station = wlan_hdd_cfg80211_get_station,
16764 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
16765 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016766 .add_station = wlan_hdd_cfg80211_add_station,
16767#ifdef FEATURE_WLAN_LFR
16768 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
16769 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
16770 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
16771#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016772#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
16773 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
16774#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016775#ifdef FEATURE_WLAN_TDLS
16776 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
16777 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
16778#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016779#ifdef WLAN_FEATURE_GTK_OFFLOAD
16780 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
16781#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016782#ifdef FEATURE_WLAN_SCAN_PNO
16783 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
16784 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
16785#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016786 .resume = wlan_hdd_cfg80211_resume_wlan,
16787 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016788 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070016789#ifdef WLAN_NL80211_TESTMODE
16790 .testmode_cmd = wlan_hdd_cfg80211_testmode,
16791#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016792 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070016793};
16794