blob: c738296be835da969907f8ca453f54f906089d0c [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,
622 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530623 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800624 GFP_KERNEL);
625 if (!vendor_event)
626 {
627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
628 "%s: cfg80211_vendor_event_alloc failed", __func__);
629 return -1;
630 }
631
632 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
633 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
634
635 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
636
637 EXIT();
638 return 0;
639}
640#endif /* FEATURE_WLAN_CH_AVOID */
641
Srinivas Dasari030bad32015-02-18 23:23:54 +0530642/*
643 * FUNCTION: __wlan_hdd_cfg80211_nan_request
644 * This is called when wlan driver needs to send vendor specific
645 * nan request event.
646 */
647static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
648 struct wireless_dev *wdev,
649 const void *data, int data_len)
650{
651 tNanRequestReq nan_req;
652 VOS_STATUS status;
653 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530654 struct net_device *dev = wdev->netdev;
655 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
656 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530657 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
658
659 if (0 == data_len)
660 {
661 hddLog(VOS_TRACE_LEVEL_ERROR,
662 FL("NAN - Invalid Request, length = 0"));
663 return ret_val;
664 }
665
666 if (NULL == data)
667 {
668 hddLog(VOS_TRACE_LEVEL_ERROR,
669 FL("NAN - Invalid Request, data is NULL"));
670 return ret_val;
671 }
672
673 status = wlan_hdd_validate_context(pHddCtx);
674 if (0 != status)
675 {
676 hddLog(VOS_TRACE_LEVEL_ERROR,
677 FL("HDD context is not valid"));
678 return -EINVAL;
679 }
680
681 hddLog(LOG1, FL("Received NAN command"));
682 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
683 (tANI_U8 *)data, data_len);
684
685 /* check the NAN Capability */
686 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
687 {
688 hddLog(VOS_TRACE_LEVEL_ERROR,
689 FL("NAN is not supported by Firmware"));
690 return -EINVAL;
691 }
692
693 nan_req.request_data_len = data_len;
694 nan_req.request_data = data;
695
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530696 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530697 if (VOS_STATUS_SUCCESS == status)
698 {
699 ret_val = 0;
700 }
701 return ret_val;
702}
703
704/*
705 * FUNCTION: wlan_hdd_cfg80211_nan_request
706 * Wrapper to protect the nan vendor command from ssr
707 */
708static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
709 struct wireless_dev *wdev,
710 const void *data, int data_len)
711{
712 int ret;
713
714 vos_ssr_protect(__func__);
715 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
716 vos_ssr_unprotect(__func__);
717
718 return ret;
719}
720
721/*
722 * FUNCTION: wlan_hdd_cfg80211_nan_callback
723 * This is a callback function and it gets called
724 * when we need to report nan response event to
725 * upper layers.
726 */
727static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
728{
729 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
730 struct sk_buff *vendor_event;
731 int status;
732 tSirNanEvent *data;
733
734 ENTER();
735 if (NULL == msg)
736 {
737 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
738 FL(" msg received here is null"));
739 return;
740 }
741 data = msg;
742
743 status = wlan_hdd_validate_context(pHddCtx);
744
745 if (0 != status)
746 {
747 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
748 FL("HDD context is not valid"));
749 return;
750 }
751
752 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
753 data->event_data_len +
754 NLMSG_HDRLEN,
755 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
756 GFP_KERNEL);
757
758 if (!vendor_event)
759 {
760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
761 FL("cfg80211_vendor_event_alloc failed"));
762 return;
763 }
764 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
765 data->event_data_len, data->event_data))
766 {
767 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
768 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
769 kfree_skb(vendor_event);
770 return;
771 }
772 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
773 EXIT();
774}
775
776/*
777 * FUNCTION: wlan_hdd_cfg80211_nan_init
778 * This function is called to register the callback to sme layer
779 */
780inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
781{
782 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
783}
784
785
Sunil Duttc69bccb2014-05-26 21:30:20 +0530786#ifdef WLAN_FEATURE_LINK_LAYER_STATS
787
788static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
789 struct sk_buff *vendor_event)
790{
791 if (nla_put_u8(vendor_event,
792 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
793 stats->rate.preamble) ||
794 nla_put_u8(vendor_event,
795 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
796 stats->rate.nss) ||
797 nla_put_u8(vendor_event,
798 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
799 stats->rate.bw) ||
800 nla_put_u8(vendor_event,
801 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
802 stats->rate.rateMcsIdx) ||
803 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
804 stats->rate.bitrate ) ||
805 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
806 stats->txMpdu ) ||
807 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
808 stats->rxMpdu ) ||
809 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
810 stats->mpduLost ) ||
811 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
812 stats->retries) ||
813 nla_put_u32(vendor_event,
814 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
815 stats->retriesShort ) ||
816 nla_put_u32(vendor_event,
817 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
818 stats->retriesLong))
819 {
820 hddLog(VOS_TRACE_LEVEL_ERROR,
821 FL("QCA_WLAN_VENDOR_ATTR put fail"));
822 return FALSE;
823 }
824 return TRUE;
825}
826
827static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
828 struct sk_buff *vendor_event)
829{
830 u32 i = 0;
831 struct nlattr *rateInfo;
832 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
833 stats->type) ||
834 nla_put(vendor_event,
835 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
836 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
837 nla_put_u32(vendor_event,
838 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
839 stats->capabilities) ||
840 nla_put_u32(vendor_event,
841 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
842 stats->numRate))
843 {
844 hddLog(VOS_TRACE_LEVEL_ERROR,
845 FL("QCA_WLAN_VENDOR_ATTR put fail"));
846 goto error;
847 }
848
849 rateInfo = nla_nest_start(vendor_event,
850 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530851 if(!rateInfo)
852 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530853 for (i = 0; i < stats->numRate; i++)
854 {
855 struct nlattr *rates;
856 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
857 stats->rateStats +
858 (i * sizeof(tSirWifiRateStat)));
859 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530860 if(!rates)
861 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530862
863 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
864 {
865 hddLog(VOS_TRACE_LEVEL_ERROR,
866 FL("QCA_WLAN_VENDOR_ATTR put fail"));
867 return FALSE;
868 }
869 nla_nest_end(vendor_event, rates);
870 }
871 nla_nest_end(vendor_event, rateInfo);
872
873 return TRUE;
874error:
875 return FALSE;
876}
877
878static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
879 struct sk_buff *vendor_event)
880{
881 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
882 stats->ac ) ||
883 nla_put_u32(vendor_event,
884 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
885 stats->txMpdu ) ||
886 nla_put_u32(vendor_event,
887 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
888 stats->rxMpdu ) ||
889 nla_put_u32(vendor_event,
890 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
891 stats->txMcast ) ||
892 nla_put_u32(vendor_event,
893 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
894 stats->rxMcast ) ||
895 nla_put_u32(vendor_event,
896 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
897 stats->rxAmpdu ) ||
898 nla_put_u32(vendor_event,
899 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
900 stats->txAmpdu ) ||
901 nla_put_u32(vendor_event,
902 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
903 stats->mpduLost )||
904 nla_put_u32(vendor_event,
905 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
906 stats->retries ) ||
907 nla_put_u32(vendor_event,
908 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
909 stats->retriesShort ) ||
910 nla_put_u32(vendor_event,
911 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
912 stats->retriesLong ) ||
913 nla_put_u32(vendor_event,
914 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
915 stats->contentionTimeMin ) ||
916 nla_put_u32(vendor_event,
917 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
918 stats->contentionTimeMax ) ||
919 nla_put_u32(vendor_event,
920 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
921 stats->contentionTimeAvg ) ||
922 nla_put_u32(vendor_event,
923 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
924 stats->contentionNumSamples ))
925 {
926 hddLog(VOS_TRACE_LEVEL_ERROR,
927 FL("QCA_WLAN_VENDOR_ATTR put fail") );
928 return FALSE;
929 }
930 return TRUE;
931}
932
933static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
934 struct sk_buff *vendor_event)
935{
Dino Myclec8f3f332014-07-21 16:48:27 +0530936 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530937 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
938 nla_put(vendor_event,
939 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
940 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
941 nla_put_u32(vendor_event,
942 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
943 stats->state ) ||
944 nla_put_u32(vendor_event,
945 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
946 stats->roaming ) ||
947 nla_put_u32(vendor_event,
948 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
949 stats->capabilities ) ||
950 nla_put(vendor_event,
951 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
952 strlen(stats->ssid), stats->ssid) ||
953 nla_put(vendor_event,
954 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
955 WNI_CFG_BSSID_LEN, stats->bssid) ||
956 nla_put(vendor_event,
957 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
958 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
959 nla_put(vendor_event,
960 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
961 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
962 )
963 {
964 hddLog(VOS_TRACE_LEVEL_ERROR,
965 FL("QCA_WLAN_VENDOR_ATTR put fail") );
966 return FALSE;
967 }
968 return TRUE;
969}
970
Dino Mycle3b9536d2014-07-09 22:05:24 +0530971static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
972 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530973 struct sk_buff *vendor_event)
974{
975 int i = 0;
976 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530977 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
978 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530979 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530980
Sunil Duttc69bccb2014-05-26 21:30:20 +0530981 if (FALSE == put_wifi_interface_info(
982 &pWifiIfaceStat->info,
983 vendor_event))
984 {
985 hddLog(VOS_TRACE_LEVEL_ERROR,
986 FL("QCA_WLAN_VENDOR_ATTR put fail") );
987 return FALSE;
988
989 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530990 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
991 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
992 if (NULL == pWifiIfaceStatTL)
993 {
994 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
995 return FALSE;
996 }
997
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530998 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
999 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1000 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1001 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1002
1003 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1004 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1005 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1006 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301007
1008 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1009 {
1010 if (VOS_STATUS_SUCCESS ==
1011 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1012 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1013 {
1014 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1015 * obtained from TL structure
1016 */
1017
1018 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1019 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301020 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1021
Srinivas Dasari98947432014-11-07 19:41:24 +05301022 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1023 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1024 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1025 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1026 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1027 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1028 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1029 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301030
Srinivas Dasari98947432014-11-07 19:41:24 +05301031 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1032 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1033 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1034 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1035 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1036 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1037 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1038 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301039
Srinivas Dasari98947432014-11-07 19:41:24 +05301040 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1041 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1042 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1043 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1044 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1045 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1046 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1047 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301048 }
1049 else
1050 {
1051 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1052 }
1053
Dino Mycle3b9536d2014-07-09 22:05:24 +05301054 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1055 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1056 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1057 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1058 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1059 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1060 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1061 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1062 }
1063 else
1064 {
1065 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1066 }
1067
1068
Sunil Duttc69bccb2014-05-26 21:30:20 +05301069
1070 if (nla_put_u32(vendor_event,
1071 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1072 pWifiIfaceStat->beaconRx) ||
1073 nla_put_u32(vendor_event,
1074 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1075 pWifiIfaceStat->mgmtRx) ||
1076 nla_put_u32(vendor_event,
1077 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1078 pWifiIfaceStat->mgmtActionRx) ||
1079 nla_put_u32(vendor_event,
1080 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1081 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301082 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301083 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1084 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301085 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301086 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1087 pWifiIfaceStat->rssiData) ||
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_ACK,
1090 pWifiIfaceStat->rssiAck))
1091 {
1092 hddLog(VOS_TRACE_LEVEL_ERROR,
1093 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301094 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301095 return FALSE;
1096 }
1097
1098 wmmInfo = nla_nest_start(vendor_event,
1099 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301100 if(!wmmInfo)
1101 {
1102 vos_mem_free(pWifiIfaceStatTL);
1103 return FALSE;
1104 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301105 for (i = 0; i < WIFI_AC_MAX; i++)
1106 {
1107 struct nlattr *wmmStats;
1108 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301109 if(!wmmStats)
1110 {
1111 vos_mem_free(pWifiIfaceStatTL);
1112 return FALSE;
1113 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301114 if (FALSE == put_wifi_wmm_ac_stat(
1115 &pWifiIfaceStat->AccessclassStats[i],
1116 vendor_event))
1117 {
1118 hddLog(VOS_TRACE_LEVEL_ERROR,
1119 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301120 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301121 return FALSE;
1122 }
1123
1124 nla_nest_end(vendor_event, wmmStats);
1125 }
1126 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301127 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301128 return TRUE;
1129}
1130
1131static tSirWifiInterfaceMode
1132 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1133{
1134 switch (deviceMode)
1135 {
1136 case WLAN_HDD_INFRA_STATION:
1137 return WIFI_INTERFACE_STA;
1138 case WLAN_HDD_SOFTAP:
1139 return WIFI_INTERFACE_SOFTAP;
1140 case WLAN_HDD_P2P_CLIENT:
1141 return WIFI_INTERFACE_P2P_CLIENT;
1142 case WLAN_HDD_P2P_GO:
1143 return WIFI_INTERFACE_P2P_GO;
1144 case WLAN_HDD_IBSS:
1145 return WIFI_INTERFACE_IBSS;
1146 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301147 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301148 }
1149}
1150
1151static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1152 tpSirWifiInterfaceInfo pInfo)
1153{
1154 v_U8_t *staMac = NULL;
1155 hdd_station_ctx_t *pHddStaCtx;
1156 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1157 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1158
1159 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1160
1161 vos_mem_copy(pInfo->macAddr,
1162 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1163
1164 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1165 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1166 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1167 {
1168 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1169 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1170 {
1171 pInfo->state = WIFI_DISCONNECTED;
1172 }
1173 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1174 {
1175 hddLog(VOS_TRACE_LEVEL_ERROR,
1176 "%s: Session ID %d, Connection is in progress", __func__,
1177 pAdapter->sessionId);
1178 pInfo->state = WIFI_ASSOCIATING;
1179 }
1180 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1181 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1182 {
1183 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1184 hddLog(VOS_TRACE_LEVEL_ERROR,
1185 "%s: client " MAC_ADDRESS_STR
1186 " is in the middle of WPS/EAPOL exchange.", __func__,
1187 MAC_ADDR_ARRAY(staMac));
1188 pInfo->state = WIFI_AUTHENTICATING;
1189 }
1190 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1191 {
1192 pInfo->state = WIFI_ASSOCIATED;
1193 vos_mem_copy(pInfo->bssid,
1194 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1195 vos_mem_copy(pInfo->ssid,
1196 pHddStaCtx->conn_info.SSID.SSID.ssId,
1197 pHddStaCtx->conn_info.SSID.SSID.length);
1198 //NULL Terminate the string.
1199 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1200 }
1201 }
1202 vos_mem_copy(pInfo->countryStr,
1203 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1204
1205 vos_mem_copy(pInfo->apCountryStr,
1206 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1207
1208 return TRUE;
1209}
1210
1211/*
1212 * hdd_link_layer_process_peer_stats () - This function is called after
1213 * receiving Link Layer Peer statistics from FW.This function converts
1214 * the firmware data to the NL data and sends the same to the kernel/upper
1215 * layers.
1216 */
1217static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1218 v_VOID_t *pData)
1219{
1220 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1221 tpSirWifiRateStat pWifiRateStat;
1222 tpSirWifiPeerStat pWifiPeerStat;
1223 tpSirWifiPeerInfo pWifiPeerInfo;
1224 struct nlattr *peerInfo;
1225 struct sk_buff *vendor_event;
1226 int status, i;
1227
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301228 ENTER();
1229
Sunil Duttc69bccb2014-05-26 21:30:20 +05301230 status = wlan_hdd_validate_context(pHddCtx);
1231 if (0 != status)
1232 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301233 return;
1234 }
1235
1236 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1237
1238 hddLog(VOS_TRACE_LEVEL_INFO,
1239 "LL_STATS_PEER_ALL : numPeers %u",
1240 pWifiPeerStat->numPeers);
1241 {
1242 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1243 {
1244 pWifiPeerInfo = (tpSirWifiPeerInfo)
1245 ((uint8 *)pWifiPeerStat->peerInfo +
1246 ( i * sizeof(tSirWifiPeerInfo)));
1247
Dasari Srinivas1be0c4e2014-10-19 13:03:41 +05301248 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) {
1249 pWifiPeerInfo->type = WIFI_PEER_AP;
1250 }
1251 if (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) {
1252 pWifiPeerInfo->type = WIFI_PEER_P2P_GO;
1253 }
1254
Sunil Duttc69bccb2014-05-26 21:30:20 +05301255 hddLog(VOS_TRACE_LEVEL_INFO,
1256 " %d) LL_STATS Channel Stats "
1257 " Peer Type %u "
1258 " peerMacAddress %pM "
1259 " capabilities 0x%x "
1260 " numRate %u ",
1261 i,
1262 pWifiPeerInfo->type,
1263 pWifiPeerInfo->peerMacAddress,
1264 pWifiPeerInfo->capabilities,
1265 pWifiPeerInfo->numRate);
1266 {
1267 int j;
1268 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1269 {
1270 pWifiRateStat = (tpSirWifiRateStat)
1271 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1272 ( j * sizeof(tSirWifiRateStat)));
1273
1274 hddLog(VOS_TRACE_LEVEL_INFO,
1275 " peer Rate Stats "
1276 " preamble %u "
1277 " nss %u "
1278 " bw %u "
1279 " rateMcsIdx %u "
1280 " reserved %u "
1281 " bitrate %u "
1282 " txMpdu %u "
1283 " rxMpdu %u "
1284 " mpduLost %u "
1285 " retries %u "
1286 " retriesShort %u "
1287 " retriesLong %u",
1288 pWifiRateStat->rate.preamble,
1289 pWifiRateStat->rate.nss,
1290 pWifiRateStat->rate.bw,
1291 pWifiRateStat->rate.rateMcsIdx,
1292 pWifiRateStat->rate.reserved,
1293 pWifiRateStat->rate.bitrate,
1294 pWifiRateStat->txMpdu,
1295 pWifiRateStat->rxMpdu,
1296 pWifiRateStat->mpduLost,
1297 pWifiRateStat->retries,
1298 pWifiRateStat->retriesShort,
1299 pWifiRateStat->retriesLong);
1300 }
1301 }
1302 }
1303 }
1304
1305 /*
1306 * Allocate a size of 4096 for the peer stats comprising
1307 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1308 * sizeof (tSirWifiRateStat).Each field is put with an
1309 * NL attribute.The size of 4096 is considered assuming
1310 * that number of rates shall not exceed beyond 50 with
1311 * the sizeof (tSirWifiRateStat) being 32.
1312 */
1313 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1314 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1315 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1316 GFP_KERNEL);
1317 if (!vendor_event)
1318 {
1319 hddLog(VOS_TRACE_LEVEL_ERROR,
1320 "%s: cfg80211_vendor_event_alloc failed",
1321 __func__);
1322 return;
1323 }
1324 if (nla_put_u32(vendor_event,
1325 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1326 pWifiPeerStat->numPeers))
1327 {
1328 hddLog(VOS_TRACE_LEVEL_ERROR,
1329 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1330 kfree_skb(vendor_event);
1331 return;
1332 }
1333
1334 peerInfo = nla_nest_start(vendor_event,
1335 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301336 if(!peerInfo)
1337 {
1338 hddLog(VOS_TRACE_LEVEL_ERROR,
1339 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1340 __func__);
1341 kfree_skb(vendor_event);
1342 return;
1343 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301344
1345 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1346 pWifiPeerStat->peerInfo);
1347
1348 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1349 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301350 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301351 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301352
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301353 if(!peers)
1354 {
1355 hddLog(VOS_TRACE_LEVEL_ERROR,
1356 "%s: peer stats put fail",
1357 __func__);
1358 kfree_skb(vendor_event);
1359 return;
1360 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301361 if (FALSE == put_wifi_peer_info(
1362 pWifiPeerInfo, vendor_event))
1363 {
1364 hddLog(VOS_TRACE_LEVEL_ERROR,
1365 "%s: put_wifi_peer_info put fail", __func__);
1366 kfree_skb(vendor_event);
1367 return;
1368 }
1369
1370 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1371 pWifiPeerStat->peerInfo +
1372 (i * sizeof(tSirWifiPeerInfo)) +
1373 (numRate * sizeof (tSirWifiRateStat)));
1374 nla_nest_end(vendor_event, peers);
1375 }
1376 nla_nest_end(vendor_event, peerInfo);
1377 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301378
1379 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301380}
1381
1382/*
1383 * hdd_link_layer_process_iface_stats () - This function is called after
1384 * receiving Link Layer Interface statistics from FW.This function converts
1385 * the firmware data to the NL data and sends the same to the kernel/upper
1386 * layers.
1387 */
1388static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1389 v_VOID_t *pData)
1390{
1391 tpSirWifiIfaceStat pWifiIfaceStat;
1392 struct sk_buff *vendor_event;
1393 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1394 int status;
1395
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301396 ENTER();
1397
Sunil Duttc69bccb2014-05-26 21:30:20 +05301398 status = wlan_hdd_validate_context(pHddCtx);
1399 if (0 != status)
1400 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301401 return;
1402 }
1403 /*
1404 * Allocate a size of 4096 for the interface stats comprising
1405 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1406 * assuming that all these fit with in the limit.Please take
1407 * a call on the limit based on the data requirements on
1408 * interface statistics.
1409 */
1410 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1411 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1412 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1413 GFP_KERNEL);
1414 if (!vendor_event)
1415 {
1416 hddLog(VOS_TRACE_LEVEL_ERROR,
1417 FL("cfg80211_vendor_event_alloc failed") );
1418 return;
1419 }
1420
1421 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1422
Dino Mycle3b9536d2014-07-09 22:05:24 +05301423
1424 if (FALSE == hdd_get_interface_info( pAdapter,
1425 &pWifiIfaceStat->info))
1426 {
1427 hddLog(VOS_TRACE_LEVEL_ERROR,
1428 FL("hdd_get_interface_info get fail") );
1429 kfree_skb(vendor_event);
1430 return;
1431 }
1432
1433 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1434 vendor_event))
1435 {
1436 hddLog(VOS_TRACE_LEVEL_ERROR,
1437 FL("put_wifi_iface_stats fail") );
1438 kfree_skb(vendor_event);
1439 return;
1440 }
1441
Sunil Duttc69bccb2014-05-26 21:30:20 +05301442 hddLog(VOS_TRACE_LEVEL_INFO,
1443 "WMI_LINK_STATS_IFACE Data");
1444
1445 hddLog(VOS_TRACE_LEVEL_INFO,
1446 "LL_STATS_IFACE: "
1447 " Mode %u "
1448 " MAC %pM "
1449 " State %u "
1450 " Roaming %u "
1451 " capabilities 0x%x "
1452 " SSID %s "
1453 " BSSID %pM",
1454 pWifiIfaceStat->info.mode,
1455 pWifiIfaceStat->info.macAddr,
1456 pWifiIfaceStat->info.state,
1457 pWifiIfaceStat->info.roaming,
1458 pWifiIfaceStat->info.capabilities,
1459 pWifiIfaceStat->info.ssid,
1460 pWifiIfaceStat->info.bssid);
1461
1462 hddLog(VOS_TRACE_LEVEL_INFO,
1463 " AP country str: %c%c%c",
1464 pWifiIfaceStat->info.apCountryStr[0],
1465 pWifiIfaceStat->info.apCountryStr[1],
1466 pWifiIfaceStat->info.apCountryStr[2]);
1467
1468
1469 hddLog(VOS_TRACE_LEVEL_INFO,
1470 " Country Str Association: %c%c%c",
1471 pWifiIfaceStat->info.countryStr[0],
1472 pWifiIfaceStat->info.countryStr[1],
1473 pWifiIfaceStat->info.countryStr[2]);
1474
1475 hddLog(VOS_TRACE_LEVEL_INFO,
1476 " beaconRx %u "
1477 " mgmtRx %u "
1478 " mgmtActionRx %u "
1479 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301480 " rssiMgmt %d "
1481 " rssiData %d "
1482 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301483 pWifiIfaceStat->beaconRx,
1484 pWifiIfaceStat->mgmtRx,
1485 pWifiIfaceStat->mgmtActionRx,
1486 pWifiIfaceStat->mgmtActionTx,
1487 pWifiIfaceStat->rssiMgmt,
1488 pWifiIfaceStat->rssiData,
1489 pWifiIfaceStat->rssiAck );
1490
1491
1492 {
1493 int i;
1494 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1495 {
1496 hddLog(VOS_TRACE_LEVEL_INFO,
1497
1498 " %d) LL_STATS IFACE: "
1499 " ac: %u txMpdu: %u "
1500 " rxMpdu: %u txMcast: %u "
1501 " rxMcast: %u rxAmpdu: %u "
1502 " txAmpdu: %u mpduLost: %u "
1503 " retries: %u retriesShort: %u "
1504 " retriesLong: %u contentionTimeMin: %u "
1505 " contentionTimeMax: %u contentionTimeAvg: %u "
1506 " contentionNumSamples: %u",
1507 i,
1508 pWifiIfaceStat->AccessclassStats[i].ac,
1509 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1510 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1511 pWifiIfaceStat->AccessclassStats[i].txMcast,
1512 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1513 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1514 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1515 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1516 pWifiIfaceStat->AccessclassStats[i].retries,
1517 pWifiIfaceStat->
1518 AccessclassStats[i].retriesShort,
1519 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1520 pWifiIfaceStat->
1521 AccessclassStats[i].contentionTimeMin,
1522 pWifiIfaceStat->
1523 AccessclassStats[i].contentionTimeMax,
1524 pWifiIfaceStat->
1525 AccessclassStats[i].contentionTimeAvg,
1526 pWifiIfaceStat->
1527 AccessclassStats[i].contentionNumSamples);
1528
1529 }
1530 }
1531
Sunil Duttc69bccb2014-05-26 21:30:20 +05301532 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301533
1534 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301535}
1536
1537/*
1538 * hdd_link_layer_process_radio_stats () - This function is called after
1539 * receiving Link Layer Radio statistics from FW.This function converts
1540 * the firmware data to the NL data and sends the same to the kernel/upper
1541 * layers.
1542 */
1543static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1544 v_VOID_t *pData)
1545{
1546 int status, i;
1547 tpSirWifiRadioStat pWifiRadioStat;
1548 tpSirWifiChannelStats pWifiChannelStats;
1549 struct sk_buff *vendor_event;
1550 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1551 struct nlattr *chList;
1552
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301553 ENTER();
1554
Sunil Duttc69bccb2014-05-26 21:30:20 +05301555 status = wlan_hdd_validate_context(pHddCtx);
1556 if (0 != status)
1557 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301558 return;
1559 }
1560 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1561
1562 hddLog(VOS_TRACE_LEVEL_INFO,
1563 "LL_STATS_RADIO"
1564 " radio is %d onTime is %u "
1565 " txTime is %u rxTime is %u "
1566 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301567 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301568 " onTimePnoScan is %u onTimeHs20 is %u "
1569 " numChannels is %u",
1570 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1571 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1572 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301573 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301574 pWifiRadioStat->onTimeRoamScan,
1575 pWifiRadioStat->onTimePnoScan,
1576 pWifiRadioStat->onTimeHs20,
1577 pWifiRadioStat->numChannels);
1578 /*
1579 * Allocate a size of 4096 for the Radio stats comprising
1580 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1581 * (tSirWifiChannelStats).Each channel data is put with an
1582 * NL attribute.The size of 4096 is considered assuming that
1583 * number of channels shall not exceed beyond 60 with the
1584 * sizeof (tSirWifiChannelStats) being 24 bytes.
1585 */
1586
1587 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1588 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1589 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1590 GFP_KERNEL);
1591
1592 if (!vendor_event)
1593 {
1594 hddLog(VOS_TRACE_LEVEL_ERROR,
1595 FL("cfg80211_vendor_event_alloc failed") );
1596 return;
1597 }
1598
1599 if (nla_put_u32(vendor_event,
1600 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1601 pWifiRadioStat->radio) ||
1602 nla_put_u32(vendor_event,
1603 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1604 pWifiRadioStat->onTime) ||
1605 nla_put_u32(vendor_event,
1606 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1607 pWifiRadioStat->txTime) ||
1608 nla_put_u32(vendor_event,
1609 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1610 pWifiRadioStat->rxTime) ||
1611 nla_put_u32(vendor_event,
1612 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1613 pWifiRadioStat->onTimeScan) ||
1614 nla_put_u32(vendor_event,
1615 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1616 pWifiRadioStat->onTimeNbd) ||
1617 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301618 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1619 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301620 nla_put_u32(vendor_event,
1621 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1622 pWifiRadioStat->onTimeRoamScan) ||
1623 nla_put_u32(vendor_event,
1624 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1625 pWifiRadioStat->onTimePnoScan) ||
1626 nla_put_u32(vendor_event,
1627 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1628 pWifiRadioStat->onTimeHs20) ||
1629 nla_put_u32(vendor_event,
1630 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1631 pWifiRadioStat->numChannels))
1632 {
1633 hddLog(VOS_TRACE_LEVEL_ERROR,
1634 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1635 kfree_skb(vendor_event);
1636 return ;
1637 }
1638
1639 chList = nla_nest_start(vendor_event,
1640 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301641 if(!chList)
1642 {
1643 hddLog(VOS_TRACE_LEVEL_ERROR,
1644 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1645 __func__);
1646 kfree_skb(vendor_event);
1647 return;
1648 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301649 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1650 {
1651 struct nlattr *chInfo;
1652
1653 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1654 pWifiRadioStat->channels +
1655 (i * sizeof(tSirWifiChannelStats)));
1656
1657 hddLog(VOS_TRACE_LEVEL_INFO,
1658 " %d) Channel Info"
1659 " width is %u "
1660 " CenterFreq %u "
1661 " CenterFreq0 %u "
1662 " CenterFreq1 %u "
1663 " onTime %u "
1664 " ccaBusyTime %u",
1665 i,
1666 pWifiChannelStats->channel.width,
1667 pWifiChannelStats->channel.centerFreq,
1668 pWifiChannelStats->channel.centerFreq0,
1669 pWifiChannelStats->channel.centerFreq1,
1670 pWifiChannelStats->onTime,
1671 pWifiChannelStats->ccaBusyTime);
1672
1673
1674 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301675 if(!chInfo)
1676 {
1677 hddLog(VOS_TRACE_LEVEL_ERROR,
1678 "%s: failed to put chInfo",
1679 __func__);
1680 kfree_skb(vendor_event);
1681 return;
1682 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301683
1684 if (nla_put_u32(vendor_event,
1685 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1686 pWifiChannelStats->channel.width) ||
1687 nla_put_u32(vendor_event,
1688 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1689 pWifiChannelStats->channel.centerFreq) ||
1690 nla_put_u32(vendor_event,
1691 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1692 pWifiChannelStats->channel.centerFreq0) ||
1693 nla_put_u32(vendor_event,
1694 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1695 pWifiChannelStats->channel.centerFreq1) ||
1696 nla_put_u32(vendor_event,
1697 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1698 pWifiChannelStats->onTime) ||
1699 nla_put_u32(vendor_event,
1700 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1701 pWifiChannelStats->ccaBusyTime))
1702 {
1703 hddLog(VOS_TRACE_LEVEL_ERROR,
1704 FL("cfg80211_vendor_event_alloc failed") );
1705 kfree_skb(vendor_event);
1706 return ;
1707 }
1708 nla_nest_end(vendor_event, chInfo);
1709 }
1710 nla_nest_end(vendor_event, chList);
1711
1712 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301713
1714 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301715 return;
1716}
1717
1718/*
1719 * hdd_link_layer_stats_ind_callback () - This function is called after
1720 * receiving Link Layer indications from FW.This callback converts the firmware
1721 * data to the NL data and send the same to the kernel/upper layers.
1722 */
1723static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1724 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301725 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301726{
Dino Mycled3d50022014-07-07 12:58:25 +05301727 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1728 hdd_adapter_t *pAdapter = NULL;
1729 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301730 int status;
1731
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301732 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301733
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301734 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301735 if (0 != status)
1736 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301737 return;
1738 }
1739
Dino Mycled3d50022014-07-07 12:58:25 +05301740 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1741 if (NULL == pAdapter)
1742 {
1743 hddLog(VOS_TRACE_LEVEL_ERROR,
1744 FL(" MAC address %pM does not exist with host"),
1745 macAddr);
1746 return;
1747 }
1748
Sunil Duttc69bccb2014-05-26 21:30:20 +05301749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301750 "%s: Interface: %s LLStats indType: %d", __func__,
1751 pAdapter->dev->name, indType);
1752
Sunil Duttc69bccb2014-05-26 21:30:20 +05301753 switch (indType)
1754 {
1755 case SIR_HAL_LL_STATS_RESULTS_RSP:
1756 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301757 hddLog(VOS_TRACE_LEVEL_INFO,
1758 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1759 hddLog(VOS_TRACE_LEVEL_INFO,
1760 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1761 linkLayerStatsResults->paramId);
1762 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301763 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1764 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301765 hddLog(VOS_TRACE_LEVEL_INFO,
1766 "LL_STATS RESULTS RESPONSE respId = %u",
1767 linkLayerStatsResults->respId);
1768 hddLog(VOS_TRACE_LEVEL_INFO,
1769 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1770 linkLayerStatsResults->moreResultToFollow);
1771 hddLog(VOS_TRACE_LEVEL_INFO,
1772 "LL_STATS RESULTS RESPONSE result = %p",
1773 linkLayerStatsResults->result);
1774 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1775 {
1776 hdd_link_layer_process_radio_stats(pAdapter,
1777 (v_VOID_t *)linkLayerStatsResults->result);
1778 }
1779 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1780 {
1781 hdd_link_layer_process_iface_stats(pAdapter,
1782 (v_VOID_t *)linkLayerStatsResults->result);
1783 }
1784 else if ( linkLayerStatsResults->paramId &
1785 WMI_LINK_STATS_ALL_PEER )
1786 {
1787 hdd_link_layer_process_peer_stats(pAdapter,
1788 (v_VOID_t *)linkLayerStatsResults->result);
1789 } /* WMI_LINK_STATS_ALL_PEER */
1790 else
1791 {
1792 hddLog(VOS_TRACE_LEVEL_ERROR,
1793 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1794 }
1795
1796 break;
1797 }
1798 default:
1799 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1800 break;
1801 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301802
1803 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301804 return;
1805}
1806
1807const struct
1808nla_policy
1809qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1810{
1811 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1812 { .type = NLA_U32 },
1813 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1814 { .type = NLA_U32 },
1815};
1816
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301817static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1818 struct wireless_dev *wdev,
1819 const void *data,
1820 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301821{
1822 int status;
1823 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301824 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301825 struct net_device *dev = wdev->netdev;
1826 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1827 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Srinivas Dasari98947432014-11-07 19:41:24 +05301828 hdd_station_ctx_t *pHddStaCtx;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301829
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301830 ENTER();
1831
Sunil Duttc69bccb2014-05-26 21:30:20 +05301832 status = wlan_hdd_validate_context(pHddCtx);
1833 if (0 != status)
1834 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301835 return -EINVAL;
1836 }
1837
1838 if (NULL == pAdapter)
1839 {
1840 hddLog(VOS_TRACE_LEVEL_ERROR,
1841 FL("HDD adapter is Null"));
1842 return -ENODEV;
1843 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301844 /* check the LLStats Capability */
1845 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1846 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1847 {
1848 hddLog(VOS_TRACE_LEVEL_ERROR,
1849 FL("Link Layer Statistics not supported by Firmware"));
1850 return -EINVAL;
1851 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301852
1853 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1854 (struct nlattr *)data,
1855 data_len, qca_wlan_vendor_ll_set_policy))
1856 {
1857 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1858 return -EINVAL;
1859 }
1860 if (!tb_vendor
1861 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1862 {
1863 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1864 return -EINVAL;
1865 }
1866 if (!tb_vendor[
1867 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1868 {
1869 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1870 return -EINVAL;
1871 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301872 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301873 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301874
Dino Mycledf0a5d92014-07-04 09:41:55 +05301875 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301876 nla_get_u32(
1877 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1878
Dino Mycledf0a5d92014-07-04 09:41:55 +05301879 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301880 nla_get_u32(
1881 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1882
Dino Mycled3d50022014-07-07 12:58:25 +05301883 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1884 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301885
1886
1887 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301888 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301889 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301890 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301891 hddLog(VOS_TRACE_LEVEL_INFO,
1892 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301893 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301894 hddLog(VOS_TRACE_LEVEL_INFO,
1895 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301896 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301897
1898 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1899 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301900 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301901 {
1902 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1903 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301904 return -EINVAL;
1905
1906 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301907
1908 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1909 if (VOS_STATUS_SUCCESS !=
1910 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1911 pHddStaCtx->conn_info.staId[0], WIFI_STATS_IFACE))
1912 {
1913 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1914 "WLANTL_ClearInterfaceStats Failed", __func__);
1915 return -EINVAL;
1916 }
1917
1918 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
1919 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
1920 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
1921 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
1922
Sunil Duttc69bccb2014-05-26 21:30:20 +05301923 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301924 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301925 {
1926 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1927 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301928 return -EINVAL;
1929 }
1930
1931 pAdapter->isLinkLayerStatsSet = 1;
1932
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301933 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301934 return 0;
1935}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301936static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1937 struct wireless_dev *wdev,
1938 const void *data,
1939 int data_len)
1940{
1941 int ret = 0;
1942
1943 vos_ssr_protect(__func__);
1944 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1945 vos_ssr_unprotect(__func__);
1946
1947 return ret;
1948}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301949
1950const struct
1951nla_policy
1952qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1953{
1954 /* Unsigned 32bit value provided by the caller issuing the GET stats
1955 * command. When reporting
1956 * the stats results, the driver uses the same value to indicate
1957 * which GET request the results
1958 * correspond to.
1959 */
1960 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1961
1962 /* Unsigned 32bit value . bit mask to identify what statistics are
1963 requested for retrieval */
1964 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1965};
1966
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301967static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1968 struct wireless_dev *wdev,
1969 const void *data,
1970 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301971{
1972 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1973 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301974 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301975 struct net_device *dev = wdev->netdev;
1976 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1977 int status;
1978
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301979 ENTER();
1980
Sunil Duttc69bccb2014-05-26 21:30:20 +05301981 status = wlan_hdd_validate_context(pHddCtx);
1982 if (0 != status)
1983 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301984 return -EINVAL ;
1985 }
1986
1987 if (NULL == pAdapter)
1988 {
1989 hddLog(VOS_TRACE_LEVEL_FATAL,
1990 "%s: HDD adapter is Null", __func__);
1991 return -ENODEV;
1992 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301993 /* check the LLStats Capability */
1994 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1995 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1996 {
1997 hddLog(VOS_TRACE_LEVEL_ERROR,
1998 FL("Link Layer Statistics not supported by Firmware"));
1999 return -EINVAL;
2000 }
2001
Sunil Duttc69bccb2014-05-26 21:30:20 +05302002
2003 if (!pAdapter->isLinkLayerStatsSet)
2004 {
2005 hddLog(VOS_TRACE_LEVEL_FATAL,
2006 "%s: isLinkLayerStatsSet : %d",
2007 __func__, pAdapter->isLinkLayerStatsSet);
2008 return -EINVAL;
2009 }
2010
2011 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2012 (struct nlattr *)data,
2013 data_len, qca_wlan_vendor_ll_get_policy))
2014 {
2015 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2016 return -EINVAL;
2017 }
2018
2019 if (!tb_vendor
2020 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2021 {
2022 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2023 return -EINVAL;
2024 }
2025
2026 if (!tb_vendor
2027 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2028 {
2029 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2030 return -EINVAL;
2031 }
2032
Sunil Duttc69bccb2014-05-26 21:30:20 +05302033
Dino Mycledf0a5d92014-07-04 09:41:55 +05302034 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302035 nla_get_u32( tb_vendor[
2036 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302037 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302038 nla_get_u32( tb_vendor[
2039 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2040
Dino Mycled3d50022014-07-07 12:58:25 +05302041 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2042 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302043
2044 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302045 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302046 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302047 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302048 hddLog(VOS_TRACE_LEVEL_INFO,
2049 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302050 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302051
2052 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302053 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302054 {
2055 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2056 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302057 return -EINVAL;
2058 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302059
2060 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302061 return 0;
2062}
2063
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302064static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2065 struct wireless_dev *wdev,
2066 const void *data,
2067 int data_len)
2068{
2069 int ret = 0;
2070
2071 vos_ssr_protect(__func__);
2072 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
2073 vos_ssr_unprotect(__func__);
2074
2075 return ret;
2076}
2077
Sunil Duttc69bccb2014-05-26 21:30:20 +05302078const struct
2079nla_policy
2080qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2081{
2082 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2083 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2084 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2085 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2086};
2087
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302088static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2089 struct wireless_dev *wdev,
2090 const void *data,
2091 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302092{
2093 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2094 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302095 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302096 struct net_device *dev = wdev->netdev;
2097 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2098 u32 statsClearReqMask;
2099 u8 stopReq;
2100 int status;
2101
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302102 ENTER();
2103
Sunil Duttc69bccb2014-05-26 21:30:20 +05302104 status = wlan_hdd_validate_context(pHddCtx);
2105 if (0 != status)
2106 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302107 return -EINVAL;
2108 }
2109
2110 if (NULL == pAdapter)
2111 {
2112 hddLog(VOS_TRACE_LEVEL_FATAL,
2113 "%s: HDD adapter is Null", __func__);
2114 return -ENODEV;
2115 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302116 /* check the LLStats Capability */
2117 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2118 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2119 {
2120 hddLog(VOS_TRACE_LEVEL_ERROR,
2121 FL("Enable LLStats Capability"));
2122 return -EINVAL;
2123 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302124
2125 if (!pAdapter->isLinkLayerStatsSet)
2126 {
2127 hddLog(VOS_TRACE_LEVEL_FATAL,
2128 "%s: isLinkLayerStatsSet : %d",
2129 __func__, pAdapter->isLinkLayerStatsSet);
2130 return -EINVAL;
2131 }
2132
2133 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2134 (struct nlattr *)data,
2135 data_len, qca_wlan_vendor_ll_clr_policy))
2136 {
2137 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2138 return -EINVAL;
2139 }
2140
2141 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2142
2143 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2144 {
2145 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2146 return -EINVAL;
2147
2148 }
2149
Sunil Duttc69bccb2014-05-26 21:30:20 +05302150
Dino Mycledf0a5d92014-07-04 09:41:55 +05302151 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302152 nla_get_u32(
2153 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2154
Dino Mycledf0a5d92014-07-04 09:41:55 +05302155 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302156 nla_get_u8(
2157 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2158
2159 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302160 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302161
Dino Mycled3d50022014-07-07 12:58:25 +05302162 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2163 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302164
2165 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302166 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302167 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302168 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302169 hddLog(VOS_TRACE_LEVEL_INFO,
2170 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302171 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302172 hddLog(VOS_TRACE_LEVEL_INFO,
2173 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302174 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302175
2176 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302177 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302178 {
2179 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302180 hdd_station_ctx_t *pHddStaCtx;
2181
2182 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2183 if (VOS_STATUS_SUCCESS !=
2184 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2185 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2186 {
2187 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2188 "WLANTL_ClearInterfaceStats Failed", __func__);
2189 return -EINVAL;
2190 }
2191 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2192 (statsClearReqMask & WIFI_STATS_IFACE)) {
2193 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2194 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2195 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2196 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2197 }
2198
Sunil Duttc69bccb2014-05-26 21:30:20 +05302199 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2200 2 * sizeof(u32) +
2201 NLMSG_HDRLEN);
2202
2203 if (temp_skbuff != NULL)
2204 {
2205
2206 if (nla_put_u32(temp_skbuff,
2207 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2208 statsClearReqMask) ||
2209 nla_put_u32(temp_skbuff,
2210 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2211 stopReq))
2212 {
2213 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2214 kfree_skb(temp_skbuff);
2215 return -EINVAL;
2216 }
2217 /* If the ask is to stop the stats collection as part of clear
2218 * (stopReq = 1) , ensure that no further requests of get
2219 * go to the firmware by having isLinkLayerStatsSet set to 0.
2220 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302221 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302222 * case the firmware is just asked to clear the statistics.
2223 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302224 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302225 pAdapter->isLinkLayerStatsSet = 0;
2226 return cfg80211_vendor_cmd_reply(temp_skbuff);
2227 }
2228 return -ENOMEM;
2229 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302230
2231 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302232 return -EINVAL;
2233}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302234static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2235 struct wireless_dev *wdev,
2236 const void *data,
2237 int data_len)
2238{
2239 int ret = 0;
2240
2241 vos_ssr_protect(__func__);
2242 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2243 vos_ssr_unprotect(__func__);
2244
2245 return ret;
2246
2247
2248}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302249#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2250
Dino Mycle6fb96c12014-06-10 11:52:40 +05302251#ifdef WLAN_FEATURE_EXTSCAN
2252static const struct nla_policy
2253wlan_hdd_extscan_config_policy
2254 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2255{
2256 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2257 { .type = NLA_U32 },
2258 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2259 { .type = NLA_U32 },
2260 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2261 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2262 { .type = NLA_U32 },
2263 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2264 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2265
2266 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2267 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2268 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2269 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2270 { .type = NLA_U8 },
2271 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2272 { .type = NLA_U32 },
2273 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2274 { .type = NLA_U32 },
2275 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2276 { .type = NLA_U32 },
2277 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
2278 { .type = NLA_U8 },
2279 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2280 { .type = NLA_U8 },
2281 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2282 { .type = NLA_U8 },
2283
2284 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2285 { .type = NLA_U32 },
2286 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2287 { .type = NLA_UNSPEC },
2288 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2289 { .type = NLA_S32 },
2290 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2291 { .type = NLA_S32 },
2292 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2293 { .type = NLA_U32 },
2294 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2295 { .type = NLA_U32 },
2296 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2297 { .type = NLA_U32 },
2298 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2299 = { .type = NLA_U32 },
2300 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2301 { .type = NLA_U32 },
2302 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2303 NLA_U32 },
2304};
2305
2306static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
2307{
2308 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2309 struct sk_buff *skb = NULL;
2310 tpSirEXTScanCapabilitiesEvent pData =
2311 (tpSirEXTScanCapabilitiesEvent) pMsg;
2312
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302313 ENTER();
2314
2315 if (wlan_hdd_validate_context(pHddCtx))
2316 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302317 return;
2318 }
2319
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302320 if (!pMsg)
2321 {
2322 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2323 return;
2324 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302325 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2326 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2327 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
2328 GFP_KERNEL);
2329
2330 if (!skb) {
2331 hddLog(VOS_TRACE_LEVEL_ERROR,
2332 FL("cfg80211_vendor_event_alloc failed"));
2333 return;
2334 }
2335
2336 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2337 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
2338 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
2339 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
2340 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
2341 pData->maxRssiSampleSize);
2342 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
2343 pData->maxScanReportingThreshold);
2344 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
2345 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
2346 pData->maxSignificantWifiChangeAPs);
2347 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
2348 pData->maxBsidHistoryEntries);
2349
2350 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2351 pData->requestId) ||
2352 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
2353 nla_put_u32(skb,
2354 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
2355 pData->scanCacheSize) ||
2356 nla_put_u32(skb,
2357 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
2358 pData->scanBuckets) ||
2359 nla_put_u32(skb,
2360 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
2361 pData->maxApPerScan) ||
2362 nla_put_u32(skb,
2363 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
2364 pData->maxRssiSampleSize) ||
2365 nla_put_u32(skb,
2366 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
2367 pData->maxScanReportingThreshold) ||
2368 nla_put_u32(skb,
2369 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
2370 pData->maxHotlistAPs) ||
2371 nla_put_u32(skb,
2372 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
2373 pData->maxSignificantWifiChangeAPs) ||
2374 nla_put_u32(skb,
2375 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2376 pData->maxBsidHistoryEntries)) {
2377 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2378 goto nla_put_failure;
2379 }
2380
2381 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302382 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302383 return;
2384
2385nla_put_failure:
2386 kfree_skb(skb);
2387 return;
2388}
2389
2390
2391static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2392{
2393 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2394 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2395 struct sk_buff *skb = NULL;
2396 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2397
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302398 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302399
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302400 if (wlan_hdd_validate_context(pHddCtx)){
2401 return;
2402 }
2403 if (!pMsg)
2404 {
2405 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302406 return;
2407 }
2408
2409 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2410 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2411 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2412 GFP_KERNEL);
2413
2414 if (!skb) {
2415 hddLog(VOS_TRACE_LEVEL_ERROR,
2416 FL("cfg80211_vendor_event_alloc failed"));
2417 return;
2418 }
2419 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2420 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2421 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2422
2423 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2424 pData->requestId) ||
2425 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2426 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2427 goto nla_put_failure;
2428 }
2429
2430 /*
2431 * Store the Request ID for comparing with the requestID obtained
2432 * in other requests.HDD shall return a failure is the extscan_stop
2433 * request is issued with a different requestId as that of the
2434 * extscan_start request. Also, This requestId shall be used while
2435 * indicating the full scan results to the upper layers.
2436 * The requestId is stored with the assumption that the firmware
2437 * shall return the ext scan start request's requestId in ext scan
2438 * start response.
2439 */
2440 if (pData->status == 0)
2441 pMac->sme.extScanStartReqId = pData->requestId;
2442
2443
2444 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302445 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302446 return;
2447
2448nla_put_failure:
2449 kfree_skb(skb);
2450 return;
2451}
2452
2453
2454static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2455{
2456 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2457 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2458 struct sk_buff *skb = NULL;
2459
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302460 ENTER();
2461
2462 if (wlan_hdd_validate_context(pHddCtx)){
2463 return;
2464 }
2465 if (!pMsg)
2466 {
2467 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302468 return;
2469 }
2470
2471 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2472 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2473 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2474 GFP_KERNEL);
2475
2476 if (!skb) {
2477 hddLog(VOS_TRACE_LEVEL_ERROR,
2478 FL("cfg80211_vendor_event_alloc failed"));
2479 return;
2480 }
2481 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2482 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2483
2484 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2485 pData->requestId) ||
2486 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2487 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2488 goto nla_put_failure;
2489 }
2490
2491 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302492 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302493 return;
2494
2495nla_put_failure:
2496 kfree_skb(skb);
2497 return;
2498}
2499
2500
2501static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2502 void *pMsg)
2503{
2504 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2505 struct sk_buff *skb = NULL;
2506 tpSirEXTScanSetBssidHotListRspParams pData =
2507 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2508
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302509 ENTER();
2510
2511 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302512 return;
2513 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302514 if (!pMsg)
2515 {
2516 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2517 return;
2518 }
2519
Dino Mycle6fb96c12014-06-10 11:52:40 +05302520 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2521 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2522 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2523 GFP_KERNEL);
2524
2525 if (!skb) {
2526 hddLog(VOS_TRACE_LEVEL_ERROR,
2527 FL("cfg80211_vendor_event_alloc failed"));
2528 return;
2529 }
2530 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2531 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2532 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2533
2534 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2535 pData->requestId) ||
2536 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2537 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2538 goto nla_put_failure;
2539 }
2540
2541 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302542 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302543 return;
2544
2545nla_put_failure:
2546 kfree_skb(skb);
2547 return;
2548}
2549
2550static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2551 void *pMsg)
2552{
2553 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2554 struct sk_buff *skb = NULL;
2555 tpSirEXTScanResetBssidHotlistRspParams pData =
2556 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2557
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302558 ENTER();
2559
2560 if (wlan_hdd_validate_context(pHddCtx)) {
2561 return;
2562 }
2563 if (!pMsg)
2564 {
2565 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302566 return;
2567 }
2568
2569 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2570 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2571 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2572 GFP_KERNEL);
2573
2574 if (!skb) {
2575 hddLog(VOS_TRACE_LEVEL_ERROR,
2576 FL("cfg80211_vendor_event_alloc failed"));
2577 return;
2578 }
2579 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2580 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2581
2582 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2583 pData->requestId) ||
2584 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2585 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2586 goto nla_put_failure;
2587 }
2588
2589 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302590 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302591 return;
2592
2593nla_put_failure:
2594 kfree_skb(skb);
2595 return;
2596}
2597
2598
2599static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2600 void *pMsg)
2601{
2602 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2603 struct sk_buff *skb = NULL;
2604 tpSirEXTScanSetSignificantChangeRspParams pData =
2605 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2606
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302607 ENTER();
2608
2609 if (wlan_hdd_validate_context(pHddCtx)) {
2610 return;
2611 }
2612 if (!pMsg)
2613 {
2614 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302615 return;
2616 }
2617
2618 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2619 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2620 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2621 GFP_KERNEL);
2622
2623 if (!skb) {
2624 hddLog(VOS_TRACE_LEVEL_ERROR,
2625 FL("cfg80211_vendor_event_alloc failed"));
2626 return;
2627 }
2628 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2629 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2630 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2631
2632 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2633 pData->requestId) ||
2634 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2635 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2636 goto nla_put_failure;
2637 }
2638
2639 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302640 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302641 return;
2642
2643nla_put_failure:
2644 kfree_skb(skb);
2645 return;
2646}
2647
2648
2649static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2650 void *pMsg)
2651{
2652 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2653 struct sk_buff *skb = NULL;
2654 tpSirEXTScanResetSignificantChangeRspParams pData =
2655 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2656
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302657 ENTER();
2658
2659 if (wlan_hdd_validate_context(pHddCtx)) {
2660 return;
2661 }
2662 if (!pMsg)
2663 {
2664 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302665 return;
2666 }
2667
2668 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2669 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2670 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2671 GFP_KERNEL);
2672
2673 if (!skb) {
2674 hddLog(VOS_TRACE_LEVEL_ERROR,
2675 FL("cfg80211_vendor_event_alloc failed"));
2676 return;
2677 }
2678 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2679 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2680 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2681
2682 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2683 pData->requestId) ||
2684 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2686 goto nla_put_failure;
2687 }
2688
2689 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302690 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302691 return;
2692
2693nla_put_failure:
2694 kfree_skb(skb);
2695 return;
2696}
2697
2698static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2699 void *pMsg)
2700{
2701 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2702 struct sk_buff *skb = NULL;
2703 tANI_U32 i = 0, j, resultsPerEvent;
2704 tANI_S32 totalResults;
2705 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2706 tpSirWifiScanResult pSirWifiScanResult;
2707
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302708 ENTER();
2709
2710 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302711 return;
2712 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302713 if (!pMsg)
2714 {
2715 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2716 return;
2717 }
2718
Dino Mycle6fb96c12014-06-10 11:52:40 +05302719 totalResults = pData->numOfAps;
2720 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2721 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2722 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2723
2724 do{
2725 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2726 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2727 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2728
2729 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2730 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2731 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2732 GFP_KERNEL);
2733
2734 if (!skb) {
2735 hddLog(VOS_TRACE_LEVEL_ERROR,
2736 FL("cfg80211_vendor_event_alloc failed"));
2737 return;
2738 }
2739
2740 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2741
2742 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2743 pData->requestId) ||
2744 nla_put_u32(skb,
2745 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2746 resultsPerEvent)) {
2747 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2748 goto fail;
2749 }
2750 if (nla_put_u8(skb,
2751 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2752 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2753 {
2754 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2755 goto fail;
2756 }
2757
2758 if (resultsPerEvent) {
2759 struct nlattr *aps;
2760
2761 aps = nla_nest_start(skb,
2762 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2763 if (!aps)
2764 {
2765 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2766 goto fail;
2767 }
2768
2769 for (j = 0; j < resultsPerEvent; j++, i++) {
2770 struct nlattr *ap;
2771 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2772 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2773
2774 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2775 "Ssid (%s)"
2776 "Bssid: %pM "
2777 "Channel (%u)"
2778 "Rssi (%d)"
2779 "RTT (%u)"
2780 "RTT_SD (%u)",
2781 i,
2782 pSirWifiScanResult->ts,
2783 pSirWifiScanResult->ssid,
2784 pSirWifiScanResult->bssid,
2785 pSirWifiScanResult->channel,
2786 pSirWifiScanResult->rssi,
2787 pSirWifiScanResult->rtt,
2788 pSirWifiScanResult->rtt_sd);
2789
2790 ap = nla_nest_start(skb, j + 1);
2791 if (!ap)
2792 {
2793 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2794 goto fail;
2795 }
2796
2797 if (nla_put_u64(skb,
2798 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2799 pSirWifiScanResult->ts) )
2800 {
2801 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2802 goto fail;
2803 }
2804 if (nla_put(skb,
2805 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2806 sizeof(pSirWifiScanResult->ssid),
2807 pSirWifiScanResult->ssid) )
2808 {
2809 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2810 goto fail;
2811 }
2812 if (nla_put(skb,
2813 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2814 sizeof(pSirWifiScanResult->bssid),
2815 pSirWifiScanResult->bssid) )
2816 {
2817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2818 goto fail;
2819 }
2820 if (nla_put_u32(skb,
2821 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2822 pSirWifiScanResult->channel) )
2823 {
2824 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2825 goto fail;
2826 }
Dasari Srinivas90747d72014-10-08 12:16:15 +05302827 if (nla_put_s32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302828 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2829 pSirWifiScanResult->rssi) )
2830 {
2831 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2832 goto fail;
2833 }
2834 if (nla_put_u32(skb,
2835 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2836 pSirWifiScanResult->rtt) )
2837 {
2838 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2839 goto fail;
2840 }
2841 if (nla_put_u32(skb,
2842 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2843 pSirWifiScanResult->rtt_sd))
2844 {
2845 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2846 goto fail;
2847 }
2848
2849 nla_nest_end(skb, ap);
2850 }
2851 nla_nest_end(skb, aps);
2852
2853 }
2854 cfg80211_vendor_event(skb, GFP_KERNEL);
2855 } while (totalResults > 0);
2856
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302857 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302858 return;
2859fail:
2860 kfree_skb(skb);
2861 return;
2862}
2863
2864static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2865 void *pMsg)
2866{
2867 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2868 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2869 struct sk_buff *skb = NULL;
2870 tANI_U32 i;
2871
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302872 ENTER();
2873
2874 if (wlan_hdd_validate_context(pHddCtx)) {
2875 return;
2876 }
2877 if (!pMsg)
2878 {
2879 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302880 return;
2881 }
2882
2883 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2884 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2885 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2886 GFP_KERNEL);
2887
2888 if (!skb) {
2889 hddLog(VOS_TRACE_LEVEL_ERROR,
2890 FL("cfg80211_vendor_event_alloc failed"));
2891 return;
2892 }
2893 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2894 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2895 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2896 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2897
2898 for (i = 0; i < pData->numOfAps; i++) {
2899 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2900 "Ssid (%s) "
2901 "Bssid (" MAC_ADDRESS_STR ") "
2902 "Channel (%u) "
2903 "Rssi (%d) "
2904 "RTT (%u) "
2905 "RTT_SD (%u) ",
2906 i,
2907 pData->ap[i].ts,
2908 pData->ap[i].ssid,
2909 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2910 pData->ap[i].channel,
2911 pData->ap[i].rssi,
2912 pData->ap[i].rtt,
2913 pData->ap[i].rtt_sd);
2914 }
2915
2916 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2917 pData->requestId) ||
2918 nla_put_u32(skb,
2919 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2920 pData->numOfAps)) {
2921 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2922 goto fail;
2923 }
2924 if (pData->numOfAps) {
2925 struct nlattr *aps;
2926
2927 aps = nla_nest_start(skb,
2928 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2929 if (!aps)
2930 goto fail;
2931
2932 for (i = 0; i < pData->numOfAps; i++) {
2933 struct nlattr *ap;
2934
2935 ap = nla_nest_start(skb, i + 1);
2936 if (!ap)
2937 goto fail;
2938
2939 if (nla_put_u64(skb,
2940 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2941 pData->ap[i].ts) ||
2942 nla_put(skb,
2943 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2944 sizeof(pData->ap[i].ssid),
2945 pData->ap[i].ssid) ||
2946 nla_put(skb,
2947 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2948 sizeof(pData->ap[i].bssid),
2949 pData->ap[i].bssid) ||
2950 nla_put_u32(skb,
2951 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2952 pData->ap[i].channel) ||
2953 nla_put_s32(skb,
2954 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2955 pData->ap[i].rssi) ||
2956 nla_put_u32(skb,
2957 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2958 pData->ap[i].rtt) ||
2959 nla_put_u32(skb,
2960 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2961 pData->ap[i].rtt_sd))
2962 goto fail;
2963
2964 nla_nest_end(skb, ap);
2965 }
2966 nla_nest_end(skb, aps);
2967
2968 if (nla_put_u8(skb,
2969 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2970 pData->moreData))
2971 goto fail;
2972 }
2973
2974 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302975 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302976 return;
2977
2978fail:
2979 kfree_skb(skb);
2980 return;
2981
2982}
2983static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2984 void *pMsg)
2985{
2986 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2987 struct sk_buff *skb = NULL;
2988 tANI_U32 i, j;
2989 tpSirWifiSignificantChangeEvent pData =
2990 (tpSirWifiSignificantChangeEvent) pMsg;
2991
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302992 ENTER();
2993
2994 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302995 return;
2996 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302997 if (!pMsg)
2998 {
2999 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3000 return;
3001 }
3002
Dino Mycle6fb96c12014-06-10 11:52:40 +05303003 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
3004 EXTSCAN_EVENT_BUF_SIZE,
3005 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
3006 GFP_KERNEL);
3007
3008 if (!skb) {
3009 hddLog(VOS_TRACE_LEVEL_ERROR,
3010 FL("cfg80211_vendor_event_alloc failed"));
3011 return;
3012 }
3013 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3014 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3015 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
3016 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
3017 pData->numSigRssiBss);
3018 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
3019
3020 for (i = 0; i < pData->numSigRssiBss; i++) {
3021 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
3022 " num RSSI %u ",
3023 i, pData->sigRssiResult[i].bssid,
3024 pData->sigRssiResult[i].channel,
3025 pData->sigRssiResult[i].numRssi);
3026
3027 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
3028
3029 hddLog(VOS_TRACE_LEVEL_INFO,
3030 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05303031 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303032
3033 }
3034 }
3035
3036
3037 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3038 pData->requestId) ||
3039 nla_put_u32(skb,
3040 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3041 pData->numSigRssiBss)) {
3042 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3043 goto fail;
3044 }
3045
3046 if (pData->numSigRssiBss) {
3047 struct nlattr *aps;
3048 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3049 if (!aps)
3050 goto fail;
3051 for (i = 0; i < pData->numSigRssiBss; i++) {
3052 struct nlattr *ap;
3053
3054 ap = nla_nest_start(skb, i);
3055 if (!ap)
3056 goto fail;
3057 if (nla_put(skb,
3058 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
3059 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
3060 nla_put_u32(skb,
3061 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
3062 pData->sigRssiResult[i].channel) ||
3063 nla_put_u32(skb,
3064 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
3065 pData->sigRssiResult[i].numRssi) ||
3066 nla_put(skb,
3067 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
3068 sizeof(s32) * pData->sigRssiResult[i].numRssi,
3069 pData->sigRssiResult[i].rssi))
3070 goto fail;
3071 nla_nest_end(skb, ap);
3072 }
3073 nla_nest_end(skb, aps);
3074 if (nla_put_u8(skb,
3075 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3076 pData->moreData))
3077 goto fail;
3078 }
3079 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303080 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303081 return;
3082fail:
3083 kfree_skb(skb);
3084 return;
3085}
3086
3087static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3088 void *pMsg)
3089{
3090 struct sk_buff *skb;
3091 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3092 tpSirWifiFullScanResultEvent pData =
3093 (tpSirWifiFullScanResultEvent) (pMsg);
3094
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303095 ENTER();
3096
3097 if (wlan_hdd_validate_context(pHddCtx)) {
3098 return;
3099 }
3100 if (!pMsg)
3101 {
3102 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303103 return;
3104 }
3105
3106 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
3107 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3108 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3109 GFP_KERNEL);
3110
3111 if (!skb) {
3112 hddLog(VOS_TRACE_LEVEL_ERROR,
3113 FL("cfg80211_vendor_event_alloc failed"));
3114 return;
3115 }
3116
3117 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3118 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3119 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3120 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3121 "Ssid (%s)"
3122 "Bssid (" MAC_ADDRESS_STR ")"
3123 "Channel (%u)"
3124 "Rssi (%d)"
3125 "RTT (%u)"
3126 "RTT_SD (%u)"),
3127 pData->ap.ts,
3128 pData->ap.ssid,
3129 MAC_ADDR_ARRAY(pData->ap.bssid),
3130 pData->ap.channel,
3131 pData->ap.rssi,
3132 pData->ap.rtt,
3133 pData->ap.rtt_sd);
3134 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3135 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3136 pData->requestId) ||
3137 nla_put_u64(skb,
3138 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3139 pData->ap.ts) ||
3140 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3141 sizeof(pData->ap.ssid),
3142 pData->ap.ssid) ||
3143 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3144 WNI_CFG_BSSID_LEN,
3145 pData->ap.bssid) ||
3146 nla_put_u32(skb,
3147 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3148 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303149 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303150 pData->ap.rssi) ||
3151 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3152 pData->ap.rtt) ||
3153 nla_put_u32(skb,
3154 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3155 pData->ap.rtt_sd) ||
3156 nla_put_u16(skb,
3157 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3158 pData->ap.beaconPeriod) ||
3159 nla_put_u16(skb,
3160 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3161 pData->ap.capability) ||
3162 nla_put_u32(skb,
3163 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3164 pData->ieLength))
3165 {
3166 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3167 goto nla_put_failure;
3168 }
3169 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3170 pData->ieLength,
3171 pData->ie))
3172 {
3173 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3174 goto nla_put_failure;
3175 }
3176
3177 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303178 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303179 return;
3180
3181nla_put_failure:
3182 kfree_skb(skb);
3183 return;
3184}
3185
3186static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3187 void *pMsg)
3188{
3189 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3190 struct sk_buff *skb = NULL;
3191 tpSirEXTScanResultsAvailableIndParams pData =
3192 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3193
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303194 ENTER();
3195
3196 if (wlan_hdd_validate_context(pHddCtx)){
3197 return;
3198 }
3199 if (!pMsg)
3200 {
3201 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303202 return;
3203 }
3204
3205 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
3206 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3207 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3208 GFP_KERNEL);
3209
3210 if (!skb) {
3211 hddLog(VOS_TRACE_LEVEL_ERROR,
3212 FL("cfg80211_vendor_event_alloc failed"));
3213 return;
3214 }
3215
3216 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3217 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3218 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3219 pData->numResultsAvailable);
3220 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3221 pData->requestId) ||
3222 nla_put_u32(skb,
3223 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3224 pData->numResultsAvailable)) {
3225 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3226 goto nla_put_failure;
3227 }
3228
3229 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303230 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303231 return;
3232
3233nla_put_failure:
3234 kfree_skb(skb);
3235 return;
3236}
3237
3238static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3239{
3240 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3241 struct sk_buff *skb = NULL;
3242 tpSirEXTScanProgressIndParams pData =
3243 (tpSirEXTScanProgressIndParams) pMsg;
3244
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303245 ENTER();
3246
3247 if (wlan_hdd_validate_context(pHddCtx)){
3248 return;
3249 }
3250 if (!pMsg)
3251 {
3252 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303253 return;
3254 }
3255
3256 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
3257 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3258 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3259 GFP_KERNEL);
3260
3261 if (!skb) {
3262 hddLog(VOS_TRACE_LEVEL_ERROR,
3263 FL("cfg80211_vendor_event_alloc failed"));
3264 return;
3265 }
3266 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3267 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3268 pData->extScanEventType);
3269 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3270 pData->status);
3271
3272 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3273 pData->extScanEventType) ||
3274 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303275 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3276 pData->requestId) ||
3277 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303278 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3279 pData->status)) {
3280 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3281 goto nla_put_failure;
3282 }
3283
3284 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303285 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303286 return;
3287
3288nla_put_failure:
3289 kfree_skb(skb);
3290 return;
3291}
3292
3293void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3294 void *pMsg)
3295{
3296 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3297
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303298 ENTER();
3299
Dino Mycle6fb96c12014-06-10 11:52:40 +05303300 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303301 return;
3302 }
3303
3304 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3305
3306
3307 switch(evType) {
3308 case SIR_HAL_EXTSCAN_START_RSP:
3309 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3310 break;
3311
3312 case SIR_HAL_EXTSCAN_STOP_RSP:
3313 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3314 break;
3315 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3316 /* There is no need to send this response to upper layer
3317 Just log the message */
3318 hddLog(VOS_TRACE_LEVEL_INFO,
3319 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3320 break;
3321 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3322 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3323 break;
3324
3325 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3326 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3327 break;
3328
3329 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
3330 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
3331 break;
3332
3333 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
3334 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
3335 break;
3336 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
3337 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
3338 break;
3339 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3340 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3341 break;
3342 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3343 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3344 break;
3345 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3346 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3347 break;
3348 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3349 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3350 break;
3351 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
3352 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
3353 break;
3354 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3355 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3356 break;
3357 default:
3358 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3359 break;
3360 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303361 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303362}
3363
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303364static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3365 struct wireless_dev *wdev,
3366 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303367{
Dino Myclee8843b32014-07-04 14:21:45 +05303368 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303369 struct net_device *dev = wdev->netdev;
3370 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3371 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3372 struct nlattr
3373 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3374 eHalStatus status;
3375
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303376 ENTER();
3377
Dino Mycle6fb96c12014-06-10 11:52:40 +05303378 status = wlan_hdd_validate_context(pHddCtx);
3379 if (0 != status)
3380 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303381 return -EINVAL;
3382 }
Dino Myclee8843b32014-07-04 14:21:45 +05303383 /* check the EXTScan Capability */
3384 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3385 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3386 {
3387 hddLog(VOS_TRACE_LEVEL_ERROR,
3388 FL("EXTScan not enabled/supported by Firmware"));
3389 return -EINVAL;
3390 }
3391
Dino Mycle6fb96c12014-06-10 11:52:40 +05303392 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3393 data, dataLen,
3394 wlan_hdd_extscan_config_policy)) {
3395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3396 return -EINVAL;
3397 }
3398
3399 /* Parse and fetch request Id */
3400 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3401 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3402 return -EINVAL;
3403 }
3404
Dino Mycle6fb96c12014-06-10 11:52:40 +05303405
Dino Myclee8843b32014-07-04 14:21:45 +05303406 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303407 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303408 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303409
Dino Myclee8843b32014-07-04 14:21:45 +05303410 reqMsg.sessionId = pAdapter->sessionId;
3411 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303412
Dino Myclee8843b32014-07-04 14:21:45 +05303413 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303414 if (!HAL_STATUS_SUCCESS(status)) {
3415 hddLog(VOS_TRACE_LEVEL_ERROR,
3416 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303417 return -EINVAL;
3418 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303419 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303420 return 0;
3421}
3422
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303423static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3424 struct wireless_dev *wdev,
3425 const void *data, int dataLen)
3426{
3427 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303428
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303429 vos_ssr_protect(__func__);
3430 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3431 vos_ssr_unprotect(__func__);
3432
3433 return ret;
3434}
3435
3436static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3437 struct wireless_dev *wdev,
3438 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303439{
Dino Myclee8843b32014-07-04 14:21:45 +05303440 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303441 struct net_device *dev = wdev->netdev;
3442 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3443 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3444 struct nlattr
3445 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3446 eHalStatus status;
3447
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303448 ENTER();
3449
Dino Mycle6fb96c12014-06-10 11:52:40 +05303450 status = wlan_hdd_validate_context(pHddCtx);
3451 if (0 != status)
3452 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303453 return -EINVAL;
3454 }
Dino Myclee8843b32014-07-04 14:21:45 +05303455 /* check the EXTScan Capability */
3456 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3457 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3458 {
3459 hddLog(VOS_TRACE_LEVEL_ERROR,
3460 FL("EXTScan not enabled/supported by Firmware"));
3461 return -EINVAL;
3462 }
3463
Dino Mycle6fb96c12014-06-10 11:52:40 +05303464 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3465 data, dataLen,
3466 wlan_hdd_extscan_config_policy)) {
3467 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3468 return -EINVAL;
3469 }
3470 /* Parse and fetch request Id */
3471 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3472 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3473 return -EINVAL;
3474 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303475
Dino Myclee8843b32014-07-04 14:21:45 +05303476 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303477 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3478
Dino Myclee8843b32014-07-04 14:21:45 +05303479 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303480
Dino Myclee8843b32014-07-04 14:21:45 +05303481 reqMsg.sessionId = pAdapter->sessionId;
3482 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303483
3484 /* Parse and fetch flush parameter */
3485 if (!tb
3486 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3487 {
3488 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3489 goto failed;
3490 }
Dino Myclee8843b32014-07-04 14:21:45 +05303491 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303492 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3493
Dino Myclee8843b32014-07-04 14:21:45 +05303494 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303495
Dino Myclee8843b32014-07-04 14:21:45 +05303496 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303497 if (!HAL_STATUS_SUCCESS(status)) {
3498 hddLog(VOS_TRACE_LEVEL_ERROR,
3499 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303500 return -EINVAL;
3501 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303502 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303503 return 0;
3504
3505failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303506 return -EINVAL;
3507}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303508static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3509 struct wireless_dev *wdev,
3510 const void *data, int dataLen)
3511{
3512 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303513
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303514 vos_ssr_protect(__func__);
3515 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3516 vos_ssr_unprotect(__func__);
3517
3518 return ret;
3519}
3520
3521static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303522 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303523 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303524{
3525 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3526 struct net_device *dev = wdev->netdev;
3527 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3528 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3529 struct nlattr
3530 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3531 struct nlattr
3532 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3533 struct nlattr *apTh;
3534 eHalStatus status;
3535 tANI_U8 i = 0;
3536 int rem;
3537
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303538 ENTER();
3539
Dino Mycle6fb96c12014-06-10 11:52:40 +05303540 status = wlan_hdd_validate_context(pHddCtx);
3541 if (0 != status)
3542 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303543 return -EINVAL;
3544 }
Dino Myclee8843b32014-07-04 14:21:45 +05303545 /* check the EXTScan Capability */
3546 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3547 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3548 {
3549 hddLog(VOS_TRACE_LEVEL_ERROR,
3550 FL("EXTScan not enabled/supported by Firmware"));
3551 return -EINVAL;
3552 }
3553
Dino Mycle6fb96c12014-06-10 11:52:40 +05303554 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3555 data, dataLen,
3556 wlan_hdd_extscan_config_policy)) {
3557 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3558 return -EINVAL;
3559 }
3560
3561 /* Parse and fetch request Id */
3562 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3563 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3564 return -EINVAL;
3565 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303566 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3567 vos_mem_malloc(sizeof(*pReqMsg));
3568 if (!pReqMsg) {
3569 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3570 return -ENOMEM;
3571 }
3572
Dino Myclee8843b32014-07-04 14:21:45 +05303573
Dino Mycle6fb96c12014-06-10 11:52:40 +05303574 pReqMsg->requestId = nla_get_u32(
3575 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3576 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3577
3578 /* Parse and fetch number of APs */
3579 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3580 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3581 goto fail;
3582 }
3583
3584 pReqMsg->sessionId = pAdapter->sessionId;
3585 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3586
3587 pReqMsg->numAp = nla_get_u32(
3588 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3589 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3590
3591 nla_for_each_nested(apTh,
3592 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3593 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3594 nla_data(apTh), nla_len(apTh),
3595 NULL)) {
3596 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3597 goto fail;
3598 }
3599
3600 /* Parse and fetch MAC address */
3601 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3602 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3603 goto fail;
3604 }
3605 memcpy(pReqMsg->ap[i].bssid, nla_data(
3606 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3607 sizeof(tSirMacAddr));
3608 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3609
3610 /* Parse and fetch low RSSI */
3611 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3612 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3613 goto fail;
3614 }
3615 pReqMsg->ap[i].low = nla_get_s32(
3616 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3617 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3618
3619 /* Parse and fetch high RSSI */
3620 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3621 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3622 goto fail;
3623 }
3624 pReqMsg->ap[i].high = nla_get_s32(
3625 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3626 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3627 pReqMsg->ap[i].high);
3628
3629 /* Parse and fetch channel */
3630 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3631 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3632 goto fail;
3633 }
3634 pReqMsg->ap[i].channel = nla_get_u32(
3635 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3636 hddLog(VOS_TRACE_LEVEL_INFO,
3637 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3638 i++;
3639 }
3640 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3641 if (!HAL_STATUS_SUCCESS(status)) {
3642 hddLog(VOS_TRACE_LEVEL_ERROR,
3643 FL("sme_SetBssHotlist failed(err=%d)"), status);
3644 vos_mem_free(pReqMsg);
3645 return -EINVAL;
3646 }
3647
Dino Myclee8843b32014-07-04 14:21:45 +05303648 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303649 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303650 return 0;
3651
3652fail:
3653 vos_mem_free(pReqMsg);
3654 return -EINVAL;
3655}
3656
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303657static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3658 struct wireless_dev *wdev,
3659 const void *data, int dataLen)
3660{
3661 int ret = 0;
3662
3663 vos_ssr_protect(__func__);
3664 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3665 dataLen);
3666 vos_ssr_unprotect(__func__);
3667
3668 return ret;
3669}
3670
3671static int __wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303672 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303673 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303674{
3675 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3676 struct net_device *dev = wdev->netdev;
3677 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3678 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3679 struct nlattr
3680 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3681 struct nlattr
3682 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3683 struct nlattr *apTh;
3684 eHalStatus status;
3685 int i = 0;
3686 int rem;
3687
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303688 ENTER();
3689
Dino Mycle6fb96c12014-06-10 11:52:40 +05303690 status = wlan_hdd_validate_context(pHddCtx);
3691 if (0 != status)
3692 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303693 return -EINVAL;
3694 }
Dino Myclee8843b32014-07-04 14:21:45 +05303695 /* check the EXTScan Capability */
3696 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3697 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3698 {
3699 hddLog(VOS_TRACE_LEVEL_ERROR,
3700 FL("EXTScan not enabled/supported by Firmware"));
3701 return -EINVAL;
3702 }
3703
Dino Mycle6fb96c12014-06-10 11:52:40 +05303704 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3705 data, dataLen,
3706 wlan_hdd_extscan_config_policy)) {
3707 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3708 return -EINVAL;
3709 }
3710
3711 /* Parse and fetch request Id */
3712 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3713 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3714 return -EINVAL;
3715 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303716 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303717 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303718 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303719 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3720 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303721 }
3722
Dino Myclee8843b32014-07-04 14:21:45 +05303723
3724
Dino Mycle6fb96c12014-06-10 11:52:40 +05303725 pReqMsg->requestId = nla_get_u32(
3726 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3727 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3728
3729 /* Parse and fetch RSSI sample size */
3730 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3731 {
3732 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3733 goto fail;
3734 }
3735 pReqMsg->rssiSampleSize = nla_get_u32(
3736 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3737 hddLog(VOS_TRACE_LEVEL_INFO,
3738 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3739
3740 /* Parse and fetch lost AP sample size */
3741 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3742 {
3743 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3744 goto fail;
3745 }
3746 pReqMsg->lostApSampleSize = nla_get_u32(
3747 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3748 hddLog(VOS_TRACE_LEVEL_INFO,
3749 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3750 /* Parse and fetch minimum Breaching */
3751 if (!tb
3752 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3753 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3754 goto fail;
3755 }
3756 pReqMsg->minBreaching = nla_get_u32(
3757 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3758 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3759
3760 /* Parse and fetch number of APs */
3761 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3762 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3763 goto fail;
3764 }
3765 pReqMsg->numAp = nla_get_u32(
3766 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3767 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3768
3769 pReqMsg->sessionId = pAdapter->sessionId;
3770 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3771
3772 nla_for_each_nested(apTh,
3773 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3774 if(nla_parse(tb2,
3775 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3776 nla_data(apTh), nla_len(apTh),
3777 NULL)) {
3778 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3779 goto fail;
3780 }
3781
3782 /* Parse and fetch MAC address */
3783 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3785 goto fail;
3786 }
3787 memcpy(pReqMsg->ap[i].bssid, nla_data(
3788 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3789 sizeof(tSirMacAddr));
3790
3791 /* Parse and fetch low RSSI */
3792 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3793 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3794 goto fail;
3795 }
3796 pReqMsg->ap[i].low = nla_get_s32(
3797 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3798 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3799
3800 /* Parse and fetch high RSSI */
3801 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3802 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3803 goto fail;
3804 }
3805 pReqMsg->ap[i].high = nla_get_s32(
3806 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3807 hddLog(VOS_TRACE_LEVEL_INFO,
3808 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3809
3810 /* Parse and fetch channel */
3811 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3812 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3813 goto fail;
3814 }
3815 pReqMsg->ap[i].channel = nla_get_u32(
3816 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3817 hddLog(VOS_TRACE_LEVEL_INFO,
3818 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3819 i++;
3820 }
3821
3822 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3823 if (!HAL_STATUS_SUCCESS(status)) {
3824 hddLog(VOS_TRACE_LEVEL_ERROR,
3825 FL("sme_SetSignificantChange failed(err=%d)"), status);
3826 vos_mem_free(pReqMsg);
3827 return -EINVAL;
3828 }
Dino Myclee8843b32014-07-04 14:21:45 +05303829 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303830 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303831 return 0;
3832
3833fail:
3834 vos_mem_free(pReqMsg);
3835 return -EINVAL;
3836}
3837
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303838static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3839 struct wireless_dev *wdev,
3840 const void *data, int dataLen)
3841{
3842 int ret = 0;
3843
3844 vos_ssr_protect(__func__);
3845 ret = __wlan_hdd_cfg80211_extscan_set_significant_change(wiphy, wdev, data,
3846 dataLen);
3847 vos_ssr_unprotect(__func__);
3848
3849 return ret;
3850}
3851
3852static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303853 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303854 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303855{
3856 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3857 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3858 tANI_U8 numChannels = 0;
3859 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3860 tANI_U32 requestId;
3861 tWifiBand wifiBand;
3862 eHalStatus status;
3863 struct sk_buff *replySkb;
3864 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303865 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303866
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303867 ENTER();
3868
Dino Mycle6fb96c12014-06-10 11:52:40 +05303869 status = wlan_hdd_validate_context(pHddCtx);
3870 if (0 != status)
3871 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303872 return -EINVAL;
3873 }
Dino Myclee8843b32014-07-04 14:21:45 +05303874
Dino Mycle6fb96c12014-06-10 11:52:40 +05303875 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3876 data, dataLen,
3877 wlan_hdd_extscan_config_policy)) {
3878 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3879 return -EINVAL;
3880 }
3881
3882 /* Parse and fetch request Id */
3883 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3884 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3885 return -EINVAL;
3886 }
3887 requestId = nla_get_u32(
3888 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3889 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3890
3891 /* Parse and fetch wifi band */
3892 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3893 {
3894 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3895 return -EINVAL;
3896 }
3897 wifiBand = nla_get_u32(
3898 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3899 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3900
3901 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3902 wifiBand, ChannelList,
3903 &numChannels);
3904 if (eHAL_STATUS_SUCCESS != status) {
3905 hddLog(VOS_TRACE_LEVEL_ERROR,
3906 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3907 return -EINVAL;
3908 }
3909 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3910 for (i = 0; i < numChannels; i++)
3911 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3912
3913 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3914 sizeof(u32) * numChannels +
3915 NLMSG_HDRLEN);
3916
3917 if (!replySkb) {
3918 hddLog(VOS_TRACE_LEVEL_ERROR,
3919 FL("valid channels: buffer alloc fail"));
3920 return -EINVAL;
3921 }
3922 if (nla_put_u32(replySkb,
3923 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3924 numChannels) ||
3925 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3926 sizeof(u32) * numChannels, ChannelList)) {
3927
3928 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3929 kfree_skb(replySkb);
3930 return -EINVAL;
3931 }
3932
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303933 ret = cfg80211_vendor_cmd_reply(replySkb);
3934
3935 EXIT();
3936 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303937}
3938
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303939static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3940 struct wireless_dev *wdev,
3941 const void *data, int dataLen)
3942{
3943 int ret = 0;
3944
3945 vos_ssr_protect(__func__);
3946 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
3947 dataLen);
3948 vos_ssr_unprotect(__func__);
3949
3950 return ret;
3951}
3952
3953static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303954 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303955 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303956{
Dino Myclee8843b32014-07-04 14:21:45 +05303957 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303958 struct net_device *dev = wdev->netdev;
3959 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3960 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3961 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3962 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3963 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3964 struct nlattr *buckets;
3965 struct nlattr *channels;
3966 int rem1;
3967 int rem2;
3968 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303969 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303970
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303971 ENTER();
3972
Dino Mycle6fb96c12014-06-10 11:52:40 +05303973 status = wlan_hdd_validate_context(pHddCtx);
3974 if (0 != status)
3975 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303976 return -EINVAL;
3977 }
Dino Myclee8843b32014-07-04 14:21:45 +05303978 /* check the EXTScan Capability */
3979 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3980 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3981 {
3982 hddLog(VOS_TRACE_LEVEL_ERROR,
3983 FL("EXTScan not enabled/supported by Firmware"));
3984 return -EINVAL;
3985 }
3986
Dino Mycle6fb96c12014-06-10 11:52:40 +05303987 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3988 data, dataLen,
3989 wlan_hdd_extscan_config_policy)) {
3990 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3991 return -EINVAL;
3992 }
3993
3994 /* Parse and fetch request Id */
3995 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3996 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3997 return -EINVAL;
3998 }
3999
Dino Myclee8843b32014-07-04 14:21:45 +05304000 pReqMsg = (tpSirEXTScanStartReqParams)
4001 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304002 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4004 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304005 }
4006
4007 pReqMsg->requestId = nla_get_u32(
4008 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4009 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4010
4011 pReqMsg->sessionId = pAdapter->sessionId;
4012 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4013
4014 /* Parse and fetch base period */
4015 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
4016 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4017 goto fail;
4018 }
4019 pReqMsg->basePeriod = nla_get_u32(
4020 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
4021 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4022 pReqMsg->basePeriod);
4023
4024 /* Parse and fetch max AP per scan */
4025 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
4026 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4027 goto fail;
4028 }
4029 pReqMsg->maxAPperScan = nla_get_u32(
4030 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
4031 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4032 pReqMsg->maxAPperScan);
4033
4034 /* Parse and fetch report threshold */
4035 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
4036 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4037 goto fail;
4038 }
4039 pReqMsg->reportThreshold = nla_get_u8(
4040 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
4041 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
4042 pReqMsg->reportThreshold);
4043
4044 /* Parse and fetch number of buckets */
4045 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
4046 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4047 goto fail;
4048 }
4049 pReqMsg->numBuckets = nla_get_u8(
4050 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
4051 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4052 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4053 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4054 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4055 }
4056 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4057 pReqMsg->numBuckets);
4058 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4059 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4060 goto fail;
4061 }
4062
4063 nla_for_each_nested(buckets,
4064 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4065 if(nla_parse(bucket,
4066 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4067 nla_data(buckets), nla_len(buckets), NULL)) { //policy
4068 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4069 goto fail;
4070 }
4071
4072 /* Parse and fetch bucket spec */
4073 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4074 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
4075 goto fail;
4076 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304077
4078 pReqMsg->buckets[index].bucket = nla_get_u8(
4079 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4080
4081 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
4082 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304083
4084 /* Parse and fetch wifi band */
4085 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4086 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4087 goto fail;
4088 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304089 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304090 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4091 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304092 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304093
4094 /* Parse and fetch period */
4095 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4096 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
4097 goto fail;
4098 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304099 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304100 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4101 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304102 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304103
4104 /* Parse and fetch report events */
4105 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4106 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
4107 goto fail;
4108 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304109 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304110 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4111 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304112 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304113
4114 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304115 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
4116 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304117 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
4118 goto fail;
4119 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304120 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304121 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4122 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304123 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304124
4125 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4126 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
4127 goto fail;
4128 }
4129
4130 j = 0;
4131 nla_for_each_nested(channels,
4132 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4133 if(nla_parse(channel,
4134 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4135 nla_data(channels), nla_len(channels),
4136 NULL)) { //wlan_hdd_extscan_config_policy here
4137 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4138 goto fail;
4139 }
4140
4141 /* Parse and fetch channel */
4142 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4143 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4144 goto fail;
4145 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304146 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304147 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4148 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304149 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304150
4151 /* Parse and fetch dwell time */
4152 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4153 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
4154 goto fail;
4155 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304156 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304157 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4158 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304159 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304160
4161 /* Parse and fetch channel spec passive */
4162 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4163 hddLog(VOS_TRACE_LEVEL_ERROR,
4164 FL("attr channel spec passive failed"));
4165 goto fail;
4166 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304167 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304168 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4169 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304170 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304171 j++;
4172 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304173 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304174 }
4175 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4176 if (!HAL_STATUS_SUCCESS(status)) {
4177 hddLog(VOS_TRACE_LEVEL_ERROR,
4178 FL("sme_EXTScanStart failed(err=%d)"), status);
4179 vos_mem_free(pReqMsg);
4180 return -EINVAL;
4181 }
4182
Dino Myclee8843b32014-07-04 14:21:45 +05304183 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304184 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304185 return 0;
4186
4187fail:
4188 vos_mem_free(pReqMsg);
4189 return -EINVAL;
4190}
4191
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304192static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4193 struct wireless_dev *wdev,
4194 const void *data, int dataLen)
4195{
4196 int ret = 0;
4197
4198 vos_ssr_protect(__func__);
4199 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4200 vos_ssr_unprotect(__func__);
4201
4202 return ret;
4203}
4204
4205static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304206 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304207 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304208{
Dino Myclee8843b32014-07-04 14:21:45 +05304209 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304210 struct net_device *dev = wdev->netdev;
4211 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4212 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4213 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4214 eHalStatus status;
4215
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304216 ENTER();
4217
Dino Mycle6fb96c12014-06-10 11:52:40 +05304218 status = wlan_hdd_validate_context(pHddCtx);
4219 if (0 != status)
4220 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304221 return -EINVAL;
4222 }
Dino Myclee8843b32014-07-04 14:21:45 +05304223 /* check the EXTScan Capability */
4224 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4225 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4226 {
4227 hddLog(VOS_TRACE_LEVEL_ERROR,
4228 FL("EXTScan not enabled/supported by Firmware"));
4229 return -EINVAL;
4230 }
4231
Dino Mycle6fb96c12014-06-10 11:52:40 +05304232 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4233 data, dataLen,
4234 wlan_hdd_extscan_config_policy)) {
4235 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4236 return -EINVAL;
4237 }
4238
4239 /* Parse and fetch request Id */
4240 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4241 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4242 return -EINVAL;
4243 }
4244
Dino Myclee8843b32014-07-04 14:21:45 +05304245 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304246 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304247 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304248
Dino Myclee8843b32014-07-04 14:21:45 +05304249 reqMsg.sessionId = pAdapter->sessionId;
4250 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304251
Dino Myclee8843b32014-07-04 14:21:45 +05304252 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304253 if (!HAL_STATUS_SUCCESS(status)) {
4254 hddLog(VOS_TRACE_LEVEL_ERROR,
4255 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304256 return -EINVAL;
4257 }
4258
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304259 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304260 return 0;
4261}
4262
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304263static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4264 struct wireless_dev *wdev,
4265 const void *data, int dataLen)
4266{
4267 int ret = 0;
4268
4269 vos_ssr_protect(__func__);
4270 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4271 vos_ssr_unprotect(__func__);
4272
4273 return ret;
4274}
4275
4276static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304277 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304278 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304279{
Dino Myclee8843b32014-07-04 14:21:45 +05304280 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304281 struct net_device *dev = wdev->netdev;
4282 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4283 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4284 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4285 eHalStatus status;
4286
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304287 ENTER();
4288
Dino Mycle6fb96c12014-06-10 11:52:40 +05304289 status = wlan_hdd_validate_context(pHddCtx);
4290 if (0 != status)
4291 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304292 return -EINVAL;
4293 }
Dino Myclee8843b32014-07-04 14:21:45 +05304294 /* check the EXTScan Capability */
4295 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4296 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4297 {
4298 hddLog(VOS_TRACE_LEVEL_ERROR,
4299 FL("EXTScan not enabled/supported by Firmware"));
4300 return -EINVAL;
4301 }
4302
Dino Mycle6fb96c12014-06-10 11:52:40 +05304303 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4304 data, dataLen,
4305 wlan_hdd_extscan_config_policy)) {
4306 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4307 return -EINVAL;
4308 }
4309
4310 /* Parse and fetch request Id */
4311 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4312 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4313 return -EINVAL;
4314 }
4315
Dino Myclee8843b32014-07-04 14:21:45 +05304316 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304317 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304318 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304319
Dino Myclee8843b32014-07-04 14:21:45 +05304320 reqMsg.sessionId = pAdapter->sessionId;
4321 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304322
Dino Myclee8843b32014-07-04 14:21:45 +05304323 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304324 if (!HAL_STATUS_SUCCESS(status)) {
4325 hddLog(VOS_TRACE_LEVEL_ERROR,
4326 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304327 return -EINVAL;
4328 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304329 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304330 return 0;
4331}
4332
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304333static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4334 struct wireless_dev *wdev,
4335 const void *data, int dataLen)
4336{
4337 int ret = 0;
4338
4339 vos_ssr_protect(__func__);
4340 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4341 vos_ssr_unprotect(__func__);
4342
4343 return ret;
4344}
4345
4346static int __wlan_hdd_cfg80211_extscan_reset_significant_change(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304347 struct wiphy *wiphy,
4348 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304349 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304350{
Dino Myclee8843b32014-07-04 14:21:45 +05304351 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304352 struct net_device *dev = wdev->netdev;
4353 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4354 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4355 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4356 eHalStatus status;
4357
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304358 ENTER();
4359
Dino Mycle6fb96c12014-06-10 11:52:40 +05304360 status = wlan_hdd_validate_context(pHddCtx);
4361 if (0 != status)
4362 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304363 return -EINVAL;
4364 }
Dino Myclee8843b32014-07-04 14:21:45 +05304365 /* check the EXTScan Capability */
4366 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4367 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4368 {
4369 hddLog(VOS_TRACE_LEVEL_ERROR,
4370 FL("EXTScan not enabled/supported by Firmware"));
4371 return -EINVAL;
4372 }
4373
Dino Mycle6fb96c12014-06-10 11:52:40 +05304374 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4375 data, dataLen,
4376 wlan_hdd_extscan_config_policy)) {
4377 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4378 return -EINVAL;
4379 }
4380
4381 /* Parse and fetch request Id */
4382 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4383 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4384 return -EINVAL;
4385 }
4386
Dino Mycle6fb96c12014-06-10 11:52:40 +05304387
Dino Myclee8843b32014-07-04 14:21:45 +05304388 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304389 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304390 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304391
Dino Myclee8843b32014-07-04 14:21:45 +05304392 reqMsg.sessionId = pAdapter->sessionId;
4393 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304394
Dino Myclee8843b32014-07-04 14:21:45 +05304395 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304396 if (!HAL_STATUS_SUCCESS(status)) {
4397 hddLog(VOS_TRACE_LEVEL_ERROR,
4398 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304399 return -EINVAL;
4400 }
4401
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304402 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304403 return 0;
4404}
4405
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304406static int wlan_hdd_cfg80211_extscan_reset_significant_change(
4407 struct wiphy *wiphy,
4408 struct wireless_dev *wdev,
4409 const void *data, int dataLen)
4410{
4411 int ret = 0;
4412
4413 vos_ssr_protect(__func__);
4414 ret = __wlan_hdd_cfg80211_extscan_reset_significant_change(wiphy,
4415 wdev, data,
4416 dataLen);
4417 vos_ssr_unprotect(__func__);
4418
4419 return ret;
4420}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304421#endif /* WLAN_FEATURE_EXTSCAN */
4422
Atul Mittal115287b2014-07-08 13:26:33 +05304423/*EXT TDLS*/
4424static const struct nla_policy
4425wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4426{
4427 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4428 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4429 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4430 {.type = NLA_S32 },
4431 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4432 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4433
4434};
4435
4436static const struct nla_policy
4437wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4438{
4439 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4440
4441};
4442
4443static const struct nla_policy
4444wlan_hdd_tdls_config_state_change_policy[
4445 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4446{
4447 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4448 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4449 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304450 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4451 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4452 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304453
4454};
4455
4456static const struct nla_policy
4457wlan_hdd_tdls_config_get_status_policy[
4458 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4459{
4460 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4461 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4462 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304463 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4464 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4465 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304466
4467};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304468
4469static const struct nla_policy
4470wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4471{
4472 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4473};
4474
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304475static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304476 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304477 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304478 int data_len)
4479{
4480
4481 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4482 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4483
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304484 ENTER();
4485
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304486 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304487 return -EINVAL;
4488 }
4489 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
4490 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN disabled in ini"));
4491 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304492 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304493 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
4494 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN not supported by FW"));
4495 return -ENOTSUPP;
4496 }
4497
4498 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4499 data, data_len, wlan_hdd_mac_config)) {
4500 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4501 return -EINVAL;
4502 }
4503
4504 /* Parse and fetch mac address */
4505 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4506 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4507 return -EINVAL;
4508 }
4509
4510 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4511 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4512 VOS_MAC_ADDR_LAST_3_BYTES);
4513
Siddharth Bhal76972212014-10-15 16:22:51 +05304514 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4515
4516 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304517 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4518 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304519 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4520 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4521 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4522 {
4523 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4524 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4525 VOS_MAC_ADDRESS_LEN);
4526 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304527 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304528
Siddharth Bhal76972212014-10-15 16:22:51 +05304529 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
4530 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304531 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4532 }
4533
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304534 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304535 return 0;
4536}
4537
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304538static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
4539 struct wireless_dev *wdev,
4540 const void *data,
4541 int data_len)
4542{
4543 int ret = 0;
4544
4545 vos_ssr_protect(__func__);
4546 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
4547 vos_ssr_unprotect(__func__);
4548
4549 return ret;
4550}
4551
4552static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304553 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304554 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304555 int data_len)
4556{
4557 u8 peer[6] = {0};
4558 struct net_device *dev = wdev->netdev;
4559 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4560 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4561 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4562 eHalStatus ret;
4563 tANI_S32 state;
4564 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304565 tANI_S32 global_operating_class = 0;
4566 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304567 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304568 int retVal;
4569
4570 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304571
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304572 if (!pAdapter) {
4573 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4574 return -EINVAL;
4575 }
4576
Atul Mittal115287b2014-07-08 13:26:33 +05304577 ret = wlan_hdd_validate_context(pHddCtx);
4578 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304579 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304580 return -EINVAL;
4581 }
4582 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304583 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304584 return -ENOTSUPP;
4585 }
4586 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4587 data, data_len,
4588 wlan_hdd_tdls_config_get_status_policy)) {
4589 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4590 return -EINVAL;
4591 }
4592
4593 /* Parse and fetch mac address */
4594 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4595 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4596 return -EINVAL;
4597 }
4598
4599 memcpy(peer, nla_data(
4600 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4601 sizeof(peer));
4602 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4603
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05304604 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05304605
Atul Mittal115287b2014-07-08 13:26:33 +05304606 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304607 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304608 NLMSG_HDRLEN);
4609
4610 if (!skb) {
4611 hddLog(VOS_TRACE_LEVEL_ERROR,
4612 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4613 return -EINVAL;
4614 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304615 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 +05304616 reason,
4617 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304618 global_operating_class,
4619 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304620 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304621 if (nla_put_s32(skb,
4622 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4623 state) ||
4624 nla_put_s32(skb,
4625 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4626 reason) ||
4627 nla_put_s32(skb,
4628 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4629 global_operating_class) ||
4630 nla_put_s32(skb,
4631 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4632 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304633
4634 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4635 goto nla_put_failure;
4636 }
4637
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304638 retVal = cfg80211_vendor_cmd_reply(skb);
4639 EXIT();
4640 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05304641
4642nla_put_failure:
4643 kfree_skb(skb);
4644 return -EINVAL;
4645}
4646
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304647static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4648 struct wireless_dev *wdev,
4649 const void *data,
4650 int data_len)
4651{
4652 int ret = 0;
4653
4654 vos_ssr_protect(__func__);
4655 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
4656 vos_ssr_unprotect(__func__);
4657
4658 return ret;
4659}
4660
Atul Mittal115287b2014-07-08 13:26:33 +05304661static int wlan_hdd_cfg80211_exttdls_callback(tANI_U8* mac,
4662 tANI_S32 state,
4663 tANI_S32 reason,
4664 void *ctx)
4665{
4666 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05304667 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304668 tANI_S32 global_operating_class = 0;
4669 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304670 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05304671
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304672 ENTER();
4673
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304674 if (!pAdapter) {
4675 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4676 return -EINVAL;
4677 }
4678
4679 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05304680 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304681 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304682 return -EINVAL;
4683 }
4684
4685 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304686 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304687 return -ENOTSUPP;
4688 }
4689 skb = cfg80211_vendor_event_alloc(
4690 pHddCtx->wiphy,
4691 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4692 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4693 GFP_KERNEL);
4694
4695 if (!skb) {
4696 hddLog(VOS_TRACE_LEVEL_ERROR,
4697 FL("cfg80211_vendor_event_alloc failed"));
4698 return -EINVAL;
4699 }
4700 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304701 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4702 reason,
4703 state,
4704 global_operating_class,
4705 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304706 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4707 MAC_ADDR_ARRAY(mac));
4708
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304709 if (nla_put(skb,
4710 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4711 VOS_MAC_ADDR_SIZE, mac) ||
4712 nla_put_s32(skb,
4713 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4714 state) ||
4715 nla_put_s32(skb,
4716 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4717 reason) ||
4718 nla_put_s32(skb,
4719 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4720 channel) ||
4721 nla_put_s32(skb,
4722 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4723 global_operating_class)
4724 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4726 goto nla_put_failure;
4727 }
4728
4729 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304730 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05304731 return (0);
4732
4733nla_put_failure:
4734 kfree_skb(skb);
4735 return -EINVAL;
4736}
4737
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304738static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304739 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304740 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304741 int data_len)
4742{
4743 u8 peer[6] = {0};
4744 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304745 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4746 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4747 eHalStatus status;
4748 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304749 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304750 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304751
4752 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304753
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304754 if (!dev) {
4755 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4756 return -EINVAL;
4757 }
4758
4759 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4760 if (!pAdapter) {
4761 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4762 return -EINVAL;
4763 }
4764
Atul Mittal115287b2014-07-08 13:26:33 +05304765 status = wlan_hdd_validate_context(pHddCtx);
4766 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304767 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304768 return -EINVAL;
4769 }
4770 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304771 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304772 return -ENOTSUPP;
4773 }
4774 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4775 data, data_len,
4776 wlan_hdd_tdls_config_enable_policy)) {
4777 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4778 return -EINVAL;
4779 }
4780
4781 /* Parse and fetch mac address */
4782 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4784 return -EINVAL;
4785 }
4786
4787 memcpy(peer, nla_data(
4788 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4789 sizeof(peer));
4790 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4791
4792 /* Parse and fetch channel */
4793 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4795 return -EINVAL;
4796 }
4797 pReqMsg.channel = nla_get_s32(
4798 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4799 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4800
4801 /* Parse and fetch global operating class */
4802 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4803 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4804 return -EINVAL;
4805 }
4806 pReqMsg.global_operating_class = nla_get_s32(
4807 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4808 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4809 pReqMsg.global_operating_class);
4810
4811 /* Parse and fetch latency ms */
4812 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4813 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4814 return -EINVAL;
4815 }
4816 pReqMsg.max_latency_ms = nla_get_s32(
4817 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4818 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4819 pReqMsg.max_latency_ms);
4820
4821 /* Parse and fetch required bandwidth kbps */
4822 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4823 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4824 return -EINVAL;
4825 }
4826
4827 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4828 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4829 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4830 pReqMsg.min_bandwidth_kbps);
4831
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304832 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05304833 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05304834 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304835 wlan_hdd_cfg80211_exttdls_callback);
4836
4837 EXIT();
4838 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304839}
4840
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304841static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4842 struct wireless_dev *wdev,
4843 const void *data,
4844 int data_len)
4845{
4846 int ret = 0;
4847
4848 vos_ssr_protect(__func__);
4849 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
4850 vos_ssr_unprotect(__func__);
4851
4852 return ret;
4853}
4854
4855static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304856 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304857 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304858 int data_len)
4859{
4860 u8 peer[6] = {0};
4861 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304862 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4863 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4864 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304865 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304866 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304867
4868 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304869
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304870 if (!dev) {
4871 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4872 return -EINVAL;
4873 }
4874
4875 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4876 if (!pAdapter) {
4877 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
4878 return -EINVAL;
4879 }
4880
Atul Mittal115287b2014-07-08 13:26:33 +05304881 status = wlan_hdd_validate_context(pHddCtx);
4882 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304884 return -EINVAL;
4885 }
4886 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304888 return -ENOTSUPP;
4889 }
4890 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4891 data, data_len,
4892 wlan_hdd_tdls_config_disable_policy)) {
4893 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4894 return -EINVAL;
4895 }
4896 /* Parse and fetch mac address */
4897 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4898 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4899 return -EINVAL;
4900 }
4901
4902 memcpy(peer, nla_data(
4903 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4904 sizeof(peer));
4905 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4906
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304907 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
4908
4909 EXIT();
4910 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304911}
4912
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304913static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4914 struct wireless_dev *wdev,
4915 const void *data,
4916 int data_len)
4917{
4918 int ret = 0;
4919
4920 vos_ssr_protect(__func__);
4921 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
4922 vos_ssr_unprotect(__func__);
4923
4924 return ret;
4925}
4926
Dasari Srinivas7875a302014-09-26 17:50:57 +05304927static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304928__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05304929 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304930 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05304931{
4932 struct net_device *dev = wdev->netdev;
4933 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4934 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4935 struct sk_buff *skb = NULL;
4936 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304937 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05304938
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304939 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304940
4941 ret = wlan_hdd_validate_context(pHddCtx);
4942 if (0 != ret)
4943 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304944 return ret;
4945 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05304946 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
4947 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
4948 fset |= WIFI_FEATURE_INFRA;
4949 }
4950
4951 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
4952 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
4953 fset |= WIFI_FEATURE_INFRA_5G;
4954 }
4955
4956#ifdef WLAN_FEATURE_P2P
4957 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
4958 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
4959 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
4960 fset |= WIFI_FEATURE_P2P;
4961 }
4962#endif
4963
4964 /* Soft-AP is supported currently by default */
4965 fset |= WIFI_FEATURE_SOFT_AP;
4966
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05304967 /* HOTSPOT is a supplicant feature, enable it by default */
4968 fset |= WIFI_FEATURE_HOTSPOT;
4969
Dasari Srinivas7875a302014-09-26 17:50:57 +05304970#ifdef WLAN_FEATURE_EXTSCAN
4971 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
4972 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
4973 hddLog(LOG1, FL("EXTScan is supported by firmware"));
4974 fset |= WIFI_FEATURE_EXTSCAN;
4975 }
4976#endif
4977
Dasari Srinivas7875a302014-09-26 17:50:57 +05304978 if (sme_IsFeatureSupportedByFW(NAN)) {
4979 hddLog(LOG1, FL("NAN is supported by firmware"));
4980 fset |= WIFI_FEATURE_NAN;
4981 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05304982
4983 /* D2D RTT is not supported currently by default */
4984 if (sme_IsFeatureSupportedByFW(RTT)) {
4985 hddLog(LOG1, FL("RTT is supported by firmware"));
4986 fset |= WIFI_FEATURE_D2AP_RTT;
4987 }
4988
4989#ifdef FEATURE_WLAN_BATCH_SCAN
4990 if (fset & WIFI_FEATURE_EXTSCAN) {
4991 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
4992 fset &= ~WIFI_FEATURE_BATCH_SCAN;
4993 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
4994 hddLog(LOG1, FL("Batch scan is supported by firmware"));
4995 fset |= WIFI_FEATURE_BATCH_SCAN;
4996 }
4997#endif
4998
4999#ifdef FEATURE_WLAN_SCAN_PNO
5000 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5001 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5002 hddLog(LOG1, FL("PNO is supported by firmware"));
5003 fset |= WIFI_FEATURE_PNO;
5004 }
5005#endif
5006
5007 /* STA+STA is supported currently by default */
5008 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5009
5010#ifdef FEATURE_WLAN_TDLS
5011 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5012 sme_IsFeatureSupportedByFW(TDLS)) {
5013 hddLog(LOG1, FL("TDLS is supported by firmware"));
5014 fset |= WIFI_FEATURE_TDLS;
5015 }
5016
5017 /* TDLS_OFFCHANNEL is not supported currently by default */
5018#endif
5019
5020#ifdef WLAN_AP_STA_CONCURRENCY
5021 /* AP+STA concurrency is supported currently by default */
5022 fset |= WIFI_FEATURE_AP_STA;
5023#endif
5024
5025 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5026 NLMSG_HDRLEN);
5027
5028 if (!skb) {
5029 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5030 return -EINVAL;
5031 }
5032 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5033
5034 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5035 hddLog(LOGE, FL("nla put fail"));
5036 goto nla_put_failure;
5037 }
5038
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305039 ret = cfg80211_vendor_cmd_reply(skb);
5040 EXIT();
5041 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305042
5043nla_put_failure:
5044 kfree_skb(skb);
5045 return -EINVAL;
5046}
5047
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305048static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305049wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5050 struct wireless_dev *wdev,
5051 const void *data, int data_len)
5052{
5053 int ret = 0;
5054
5055 vos_ssr_protect(__func__);
5056 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5057 vos_ssr_unprotect(__func__);
5058
5059 return ret;
5060}
5061
5062static int
5063__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305064 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305065 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305066{
5067 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5068 uint8_t i, feature_sets, max_feature_sets;
5069 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5070 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305071 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5072 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305073
5074 ENTER();
5075
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305076 ret = wlan_hdd_validate_context(pHddCtx);
5077 if (0 != ret)
5078 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305079 return ret;
5080 }
5081
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305082 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5083 data, data_len, NULL)) {
5084 hddLog(LOGE, FL("Invalid ATTR"));
5085 return -EINVAL;
5086 }
5087
5088 /* Parse and fetch max feature set */
5089 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5090 hddLog(LOGE, FL("Attr max feature set size failed"));
5091 return -EINVAL;
5092 }
5093 max_feature_sets = nla_get_u32(
5094 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5095 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5096
5097 /* Fill feature combination matrix */
5098 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305099 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5100 WIFI_FEATURE_P2P;
5101
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305102 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5103 WIFI_FEATURE_SOFT_AP;
5104
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305105 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5106 WIFI_FEATURE_SOFT_AP;
5107
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305108 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5109 WIFI_FEATURE_SOFT_AP |
5110 WIFI_FEATURE_P2P;
5111
5112 /* Add more feature combinations here */
5113
5114 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5115 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5116 hddLog(LOG1, "Feature set matrix");
5117 for (i = 0; i < feature_sets; i++)
5118 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5119
5120 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5121 sizeof(u32) * feature_sets +
5122 NLMSG_HDRLEN);
5123
5124 if (reply_skb) {
5125 if (nla_put_u32(reply_skb,
5126 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5127 feature_sets) ||
5128 nla_put(reply_skb,
5129 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5130 sizeof(u32) * feature_sets, feature_set_matrix)) {
5131 hddLog(LOGE, FL("nla put fail"));
5132 kfree_skb(reply_skb);
5133 return -EINVAL;
5134 }
5135
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305136 ret = cfg80211_vendor_cmd_reply(reply_skb);
5137 EXIT();
5138 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305139 }
5140 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5141 return -ENOMEM;
5142
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305143}
5144
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305145static int
5146wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5147 struct wireless_dev *wdev,
5148 const void *data, int data_len)
5149{
5150 int ret = 0;
5151
5152 vos_ssr_protect(__func__);
5153 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5154 data_len);
5155 vos_ssr_unprotect(__func__);
5156
5157 return ret;
5158}
5159
Agarwal Ashish738843c2014-09-25 12:27:56 +05305160static const struct nla_policy
5161wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5162 +1] =
5163{
5164 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5165};
5166
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305167static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305168 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305169 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305170 int data_len)
5171{
5172 struct net_device *dev = wdev->netdev;
5173 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5174 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5175 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5176 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5177 eHalStatus status;
5178 u32 dfsFlag = 0;
5179
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305180 ENTER();
5181
Agarwal Ashish738843c2014-09-25 12:27:56 +05305182 status = wlan_hdd_validate_context(pHddCtx);
5183 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305184 return -EINVAL;
5185 }
5186 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5187 data, data_len,
5188 wlan_hdd_set_no_dfs_flag_config_policy)) {
5189 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5190 return -EINVAL;
5191 }
5192
5193 /* Parse and fetch required bandwidth kbps */
5194 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5195 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5196 return -EINVAL;
5197 }
5198
5199 dfsFlag = nla_get_u32(
5200 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5201 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5202 dfsFlag);
5203
5204 pHddCtx->disable_dfs_flag = dfsFlag;
5205
5206 sme_disable_dfs_channel(hHal, dfsFlag);
5207 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305208
5209 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305210 return 0;
5211}
Atul Mittal115287b2014-07-08 13:26:33 +05305212
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305213static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5214 struct wireless_dev *wdev,
5215 const void *data,
5216 int data_len)
5217{
5218 int ret = 0;
5219
5220 vos_ssr_protect(__func__);
5221 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5222 vos_ssr_unprotect(__func__);
5223
5224 return ret;
5225
5226}
5227
Mukul Sharma2a271632014-10-13 14:59:01 +05305228const struct
5229nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5230{
5231 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5232 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5233};
5234
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305235static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305236 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305237{
5238
5239 u8 bssid[6] = {0};
5240 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5241 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5242 eHalStatus status = eHAL_STATUS_SUCCESS;
5243 v_U32_t isFwrRoamEnabled = FALSE;
5244 int ret;
5245
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305246 ENTER();
5247
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305248 ret = wlan_hdd_validate_context(pHddCtx);
5249 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305250 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305251 }
5252
5253 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5254 data, data_len,
5255 qca_wlan_vendor_attr);
5256 if (ret){
5257 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5258 return -EINVAL;
5259 }
5260
5261 /* Parse and fetch Enable flag */
5262 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5263 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5264 return -EINVAL;
5265 }
5266
5267 isFwrRoamEnabled = nla_get_u32(
5268 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5269
5270 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5271
5272 /* Parse and fetch bssid */
5273 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5274 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5275 return -EINVAL;
5276 }
5277
5278 memcpy(bssid, nla_data(
5279 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5280 sizeof(bssid));
5281 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5282
5283 //Update roaming
5284 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305285 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305286 return status;
5287}
5288
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305289static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5290 struct wireless_dev *wdev, const void *data, int data_len)
5291{
5292 int ret = 0;
5293
5294 vos_ssr_protect(__func__);
5295 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5296 vos_ssr_unprotect(__func__);
5297
5298 return ret;
5299}
5300
Sunil Duttc69bccb2014-05-26 21:30:20 +05305301const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
5302{
Mukul Sharma2a271632014-10-13 14:59:01 +05305303 {
5304 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5305 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
5306 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5307 WIPHY_VENDOR_CMD_NEED_NETDEV |
5308 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305309 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05305310 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305311
5312 {
5313 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5314 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
5315 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5316 WIPHY_VENDOR_CMD_NEED_NETDEV |
5317 WIPHY_VENDOR_CMD_NEED_RUNNING,
5318 .doit = wlan_hdd_cfg80211_nan_request
5319 },
5320
Sunil Duttc69bccb2014-05-26 21:30:20 +05305321#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5322 {
5323 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5324 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
5325 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5326 WIPHY_VENDOR_CMD_NEED_NETDEV |
5327 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305328 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05305329 },
5330
5331 {
5332 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5333 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
5334 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5335 WIPHY_VENDOR_CMD_NEED_NETDEV |
5336 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305337 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05305338 },
5339
5340 {
5341 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5342 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
5343 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5344 WIPHY_VENDOR_CMD_NEED_NETDEV |
5345 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305346 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05305347 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305348#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305349#ifdef WLAN_FEATURE_EXTSCAN
5350 {
5351 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5352 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
5353 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5354 WIPHY_VENDOR_CMD_NEED_NETDEV |
5355 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305356 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05305357 },
5358 {
5359 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5360 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
5361 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5362 WIPHY_VENDOR_CMD_NEED_NETDEV |
5363 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305364 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05305365 },
5366 {
5367 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5368 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
5369 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5370 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305371 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05305372 },
5373 {
5374 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5375 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
5376 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5377 WIPHY_VENDOR_CMD_NEED_NETDEV |
5378 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305379 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05305380 },
5381 {
5382 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5383 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
5384 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5385 WIPHY_VENDOR_CMD_NEED_NETDEV |
5386 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305387 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05305388 },
5389 {
5390 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5391 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
5392 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5393 WIPHY_VENDOR_CMD_NEED_NETDEV |
5394 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305395 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305396 },
5397 {
5398 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5399 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
5400 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5401 WIPHY_VENDOR_CMD_NEED_NETDEV |
5402 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305403 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305404 },
5405 {
5406 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5407 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
5408 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5409 WIPHY_VENDOR_CMD_NEED_NETDEV |
5410 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305411 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305412 },
5413 {
5414 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5415 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
5416 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5417 WIPHY_VENDOR_CMD_NEED_NETDEV |
5418 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305419 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305420 },
5421#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305422/*EXT TDLS*/
5423 {
5424 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5425 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
5426 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5427 WIPHY_VENDOR_CMD_NEED_NETDEV |
5428 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305429 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05305430 },
5431 {
5432 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5433 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
5434 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5435 WIPHY_VENDOR_CMD_NEED_NETDEV |
5436 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305437 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05305438 },
5439 {
5440 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5441 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
5442 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5443 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305444 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05305445 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05305446 {
5447 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5448 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
5449 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5450 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305451 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05305452 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05305453 {
5454 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5455 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
5456 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5457 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305458 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05305459 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305460 {
5461 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5462 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
5463 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5464 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305465 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305466 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305467 {
5468 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5469 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
5470 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5471 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305472 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305473 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305474};
5475
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005476/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05305477static const
5478struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005479{
5480#ifdef FEATURE_WLAN_CH_AVOID
5481 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05305482 .vendor_id = QCA_NL80211_VENDOR_ID,
5483 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005484 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305485#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
5486#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5487 {
5488 /* Index = 1*/
5489 .vendor_id = QCA_NL80211_VENDOR_ID,
5490 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
5491 },
5492 {
5493 /* Index = 2*/
5494 .vendor_id = QCA_NL80211_VENDOR_ID,
5495 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
5496 },
5497 {
5498 /* Index = 3*/
5499 .vendor_id = QCA_NL80211_VENDOR_ID,
5500 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
5501 },
5502 {
5503 /* Index = 4*/
5504 .vendor_id = QCA_NL80211_VENDOR_ID,
5505 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
5506 },
5507 {
5508 /* Index = 5*/
5509 .vendor_id = QCA_NL80211_VENDOR_ID,
5510 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
5511 },
5512 {
5513 /* Index = 6*/
5514 .vendor_id = QCA_NL80211_VENDOR_ID,
5515 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
5516 },
5517#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305518#ifdef WLAN_FEATURE_EXTSCAN
5519 {
5520 .vendor_id = QCA_NL80211_VENDOR_ID,
5521 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
5522 },
5523 {
5524 .vendor_id = QCA_NL80211_VENDOR_ID,
5525 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
5526 },
5527 {
5528 .vendor_id = QCA_NL80211_VENDOR_ID,
5529 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
5530 },
5531 {
5532 .vendor_id = QCA_NL80211_VENDOR_ID,
5533 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
5534 },
5535 {
5536 .vendor_id = QCA_NL80211_VENDOR_ID,
5537 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
5538 },
5539 {
5540 .vendor_id = QCA_NL80211_VENDOR_ID,
5541 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
5542 },
5543 {
5544 .vendor_id = QCA_NL80211_VENDOR_ID,
5545 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
5546 },
5547 {
5548 .vendor_id = QCA_NL80211_VENDOR_ID,
5549 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
5550 },
5551 {
5552 .vendor_id = QCA_NL80211_VENDOR_ID,
5553 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
5554 },
5555 {
5556 .vendor_id = QCA_NL80211_VENDOR_ID,
5557 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
5558 },
5559 {
5560 .vendor_id = QCA_NL80211_VENDOR_ID,
5561 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
5562 },
5563 {
5564 .vendor_id = QCA_NL80211_VENDOR_ID,
5565 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
5566 },
5567 {
5568 .vendor_id = QCA_NL80211_VENDOR_ID,
5569 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
5570 },
5571#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305572/*EXT TDLS*/
5573 {
5574 .vendor_id = QCA_NL80211_VENDOR_ID,
5575 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
5576 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305577
5578 {
5579 .vendor_id = QCA_NL80211_VENDOR_ID,
5580 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
5581 },
5582
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005583};
5584
Jeff Johnson295189b2012-06-20 16:38:30 -07005585/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305586 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305587 * This function is called by hdd_wlan_startup()
5588 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305589 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07005590 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305591struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07005592{
5593 struct wiphy *wiphy;
5594 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305595 /*
5596 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07005597 */
5598 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
5599
5600 if (!wiphy)
5601 {
5602 /* Print error and jump into err label and free the memory */
5603 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
5604 return NULL;
5605 }
5606
Sunil Duttc69bccb2014-05-26 21:30:20 +05305607
Jeff Johnson295189b2012-06-20 16:38:30 -07005608 return wiphy;
5609}
5610
5611/*
5612 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305613 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07005614 * private ioctl to change the band value
5615 */
5616int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
5617{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305618 int i, j;
5619 eNVChannelEnabledType channelEnabledState;
5620
Jeff Johnsone7245742012-09-05 17:12:55 -07005621 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305622
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305623 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005624 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305625
5626 if (NULL == wiphy->bands[i])
5627 {
5628 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5629 __func__, i);
5630 continue;
5631 }
5632
5633 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5634 {
5635 struct ieee80211_supported_band *band = wiphy->bands[i];
5636
5637 channelEnabledState = vos_nv_getChannelEnabledState(
5638 band->channels[j].hw_value);
5639
5640 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
5641 {
Abhishek Singh678227a2014-11-04 10:52:38 +05305642 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305643 continue;
5644 }
5645 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
5646 {
5647 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5648 continue;
5649 }
5650
5651 if (NV_CHANNEL_DISABLE == channelEnabledState ||
5652 NV_CHANNEL_INVALID == channelEnabledState)
5653 {
5654 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5655 }
5656 else if (NV_CHANNEL_DFS == channelEnabledState)
5657 {
5658 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5659 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
5660 }
5661 else
5662 {
5663 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
5664 |IEEE80211_CHAN_RADAR);
5665 }
5666 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005667 }
5668 return 0;
5669}
5670/*
5671 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305672 * This function is called by hdd_wlan_startup()
5673 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005674 * This function is used to initialize and register wiphy structure.
5675 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305676int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005677 struct wiphy *wiphy,
5678 hdd_config_t *pCfg
5679 )
5680{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305681 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305682 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5683
Jeff Johnsone7245742012-09-05 17:12:55 -07005684 ENTER();
5685
Jeff Johnson295189b2012-06-20 16:38:30 -07005686 /* Now bind the underlying wlan device with wiphy */
5687 set_wiphy_dev(wiphy, dev);
5688
5689 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005690
Kiet Lam6c583332013-10-14 05:37:09 +05305691#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005692 /* the flag for the other case would be initialzed in
5693 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005694 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305695#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005696
Amar Singhalfddc28c2013-09-05 13:03:40 -07005697 /* This will disable updating of NL channels from passive to
5698 * active if a beacon is received on passive channel. */
5699 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07005700
Amar Singhalfddc28c2013-09-05 13:03:40 -07005701
Amar Singhala49cbc52013-10-08 18:37:44 -07005702
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005703#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005704 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5705 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5706 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005707 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05305708 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005709#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005710
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005711#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005712 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005713#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005714 || pCfg->isFastRoamIniFeatureEnabled
5715#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005716#ifdef FEATURE_WLAN_ESE
5717 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005718#endif
5719 )
5720 {
5721 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5722 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005723#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005724#ifdef FEATURE_WLAN_TDLS
5725 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5726 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5727#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305728#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305729 if (pCfg->configPNOScanSupport)
5730 {
5731 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5732 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5733 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5734 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5735 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305736#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005737
Abhishek Singh10d85972015-04-17 10:27:23 +05305738#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5739 wiphy->features |= NL80211_FEATURE_HT_IBSS;
5740#endif
5741
Amar Singhalfddc28c2013-09-05 13:03:40 -07005742#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005743 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5744 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005745 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005746 driver need to determine what to do with both
5747 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005748
5749 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005750#else
5751 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005752#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005753
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305754 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5755
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05305756 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005757
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305758 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5759
Jeff Johnson295189b2012-06-20 16:38:30 -07005760 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305761 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07005762 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07005763 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5764 | BIT(NL80211_IFTYPE_P2P_GO)
Katya Nigame7b69a82015-04-28 15:24:06 +05305765 | BIT(NL80211_IFTYPE_AP)
5766 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07005767
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305768 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005769 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305770#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5771 if( pCfg->enableMCC )
5772 {
5773 /* Currently, supports up to two channels */
5774 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005775
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305776 if( !pCfg->allowMCCGODiffBI )
5777 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005778
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305779 }
5780 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5781 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005782#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305783 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005784
Jeff Johnson295189b2012-06-20 16:38:30 -07005785 /* Before registering we need to update the ht capabilitied based
5786 * on ini values*/
5787 if( !pCfg->ShortGI20MhzEnable )
5788 {
5789 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5790 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5791 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5792 }
5793
5794 if( !pCfg->ShortGI40MhzEnable )
5795 {
5796 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5797 }
5798
5799 if( !pCfg->nChannelBondingMode5GHz )
5800 {
5801 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5802 }
5803
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305804 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305805 if (true == hdd_is_5g_supported(pHddCtx))
5806 {
5807 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5808 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305809
5810 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5811 {
5812
5813 if (NULL == wiphy->bands[i])
5814 {
5815 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5816 __func__, i);
5817 continue;
5818 }
5819
5820 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5821 {
5822 struct ieee80211_supported_band *band = wiphy->bands[i];
5823
5824 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5825 {
5826 // Enable social channels for P2P
5827 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5828 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5829 else
5830 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5831 continue;
5832 }
5833 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5834 {
5835 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5836 continue;
5837 }
5838 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005839 }
5840 /*Initialise the supported cipher suite details*/
5841 wiphy->cipher_suites = hdd_cipher_suites;
5842 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5843
5844 /*signal strength in mBm (100*dBm) */
5845 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5846
5847#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305848 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005849#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005850
Sunil Duttc69bccb2014-05-26 21:30:20 +05305851 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
5852 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005853 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
5854 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
5855
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305856 EXIT();
5857 return 0;
5858}
5859
5860/* In this function we are registering wiphy. */
5861int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
5862{
5863 ENTER();
5864 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005865 if (0 > wiphy_register(wiphy))
5866 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305867 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07005868 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
5869 return -EIO;
5870 }
5871
5872 EXIT();
5873 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305874}
Jeff Johnson295189b2012-06-20 16:38:30 -07005875
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305876/* In this function we are updating channel list when,
5877 regulatory domain is FCC and country code is US.
5878 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
5879 As per FCC smart phone is not a indoor device.
5880 GO should not opeate on indoor channels */
5881void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
5882{
5883 int j;
5884 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5885 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
5886 //Default counrtycode from NV at the time of wiphy initialization.
5887 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
5888 &defaultCountryCode[0]))
5889 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005890 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305891 }
5892 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
5893 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305894 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
5895 {
5896 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
5897 return;
5898 }
5899 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
5900 {
5901 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
5902 // Mark UNII -1 band channel as passive
5903 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
5904 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
5905 }
5906 }
5907}
5908
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305909/* This function registers for all frame which supplicant is interested in */
5910void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005911{
Jeff Johnson295189b2012-06-20 16:38:30 -07005912 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5913 /* Register for all P2P action, public action etc frames */
5914 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5915
Jeff Johnsone7245742012-09-05 17:12:55 -07005916 ENTER();
5917
Jeff Johnson295189b2012-06-20 16:38:30 -07005918 /* Right now we are registering these frame when driver is getting
5919 initialized. Once we will move to 2.6.37 kernel, in which we have
5920 frame register ops, we will move this code as a part of that */
5921 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305922 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07005923 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5924
5925 /* GAS Initial Response */
5926 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5927 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305928
Jeff Johnson295189b2012-06-20 16:38:30 -07005929 /* GAS Comeback Request */
5930 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5931 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5932
5933 /* GAS Comeback Response */
5934 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5935 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5936
5937 /* P2P Public Action */
5938 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305939 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005940 P2P_PUBLIC_ACTION_FRAME_SIZE );
5941
5942 /* P2P Action */
5943 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5944 (v_U8_t*)P2P_ACTION_FRAME,
5945 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07005946
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05305947 /* WNM BSS Transition Request frame */
5948 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5949 (v_U8_t*)WNM_BSS_ACTION_FRAME,
5950 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005951
5952 /* WNM-Notification */
5953 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5954 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5955 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005956}
5957
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305958void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005959{
Jeff Johnson295189b2012-06-20 16:38:30 -07005960 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5961 /* Register for all P2P action, public action etc frames */
5962 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5963
Jeff Johnsone7245742012-09-05 17:12:55 -07005964 ENTER();
5965
Jeff Johnson295189b2012-06-20 16:38:30 -07005966 /* Right now we are registering these frame when driver is getting
5967 initialized. Once we will move to 2.6.37 kernel, in which we have
5968 frame register ops, we will move this code as a part of that */
5969 /* GAS Initial Request */
5970
5971 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5972 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5973
5974 /* GAS Initial Response */
5975 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5976 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305977
Jeff Johnson295189b2012-06-20 16:38:30 -07005978 /* GAS Comeback Request */
5979 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5980 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5981
5982 /* GAS Comeback Response */
5983 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5984 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5985
5986 /* P2P Public Action */
5987 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305988 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005989 P2P_PUBLIC_ACTION_FRAME_SIZE );
5990
5991 /* P2P Action */
5992 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5993 (v_U8_t*)P2P_ACTION_FRAME,
5994 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005995 /* WNM-Notification */
5996 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5997 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5998 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005999}
6000
6001#ifdef FEATURE_WLAN_WAPI
6002void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
6003 const u8 *mac_addr, u8 *key , int key_Len)
6004{
6005 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6006 tCsrRoamSetKey setKey;
6007 v_BOOL_t isConnected = TRUE;
6008 int status = 0;
6009 v_U32_t roamId= 0xFF;
6010 tANI_U8 *pKeyPtr = NULL;
6011 int n = 0;
6012
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306013 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6014 __func__, hdd_device_modetoString(pAdapter->device_mode),
6015 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006016
Gopichand Nakkalae7480202013-02-11 15:24:22 +05306017 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006018 setKey.keyId = key_index; // Store Key ID
6019 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
6020 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
6021 setKey.paeRole = 0 ; // the PAE role
6022 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
6023 {
6024 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
6025 }
6026 else
6027 {
6028 isConnected = hdd_connIsConnected(pHddStaCtx);
6029 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
6030 }
6031 setKey.keyLength = key_Len;
6032 pKeyPtr = setKey.Key;
6033 memcpy( pKeyPtr, key, key_Len);
6034
Arif Hussain6d2a3322013-11-17 19:50:10 -08006035 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07006036 __func__, key_Len);
6037 for (n = 0 ; n < key_Len; n++)
6038 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
6039 __func__,n,setKey.Key[n]);
6040
6041 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
6042 if ( isConnected )
6043 {
6044 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
6045 pAdapter->sessionId, &setKey, &roamId );
6046 }
6047 if ( status != 0 )
6048 {
6049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6050 "[%4d] sme_RoamSetKey returned ERROR status= %d",
6051 __LINE__, status );
6052 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
6053 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05306054 /* Need to clear any trace of key value in the memory.
6055 * Thus zero out the memory even though it is local
6056 * variable.
6057 */
6058 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006059}
6060#endif /* FEATURE_WLAN_WAPI*/
6061
6062#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306063int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006064 beacon_data_t **ppBeacon,
6065 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006066#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306067int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006068 beacon_data_t **ppBeacon,
6069 struct cfg80211_beacon_data *params,
6070 int dtim_period)
6071#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306072{
Jeff Johnson295189b2012-06-20 16:38:30 -07006073 int size;
6074 beacon_data_t *beacon = NULL;
6075 beacon_data_t *old = NULL;
6076 int head_len,tail_len;
6077
Jeff Johnsone7245742012-09-05 17:12:55 -07006078 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006079 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306080 {
6081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6082 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006083 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306084 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006085
6086 old = pAdapter->sessionCtx.ap.beacon;
6087
6088 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306089 {
6090 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6091 FL("session(%d) old and new heads points to NULL"),
6092 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006093 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306094 }
6095
6096 if (params->tail && !params->tail_len)
6097 {
6098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6099 FL("tail_len is zero but tail is not NULL"));
6100 return -EINVAL;
6101 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006102
Jeff Johnson295189b2012-06-20 16:38:30 -07006103#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
6104 /* Kernel 3.0 is not updating dtim_period for set beacon */
6105 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306106 {
6107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6108 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006109 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306110 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006111#endif
6112
6113 if(params->head)
6114 head_len = params->head_len;
6115 else
6116 head_len = old->head_len;
6117
6118 if(params->tail || !old)
6119 tail_len = params->tail_len;
6120 else
6121 tail_len = old->tail_len;
6122
6123 size = sizeof(beacon_data_t) + head_len + tail_len;
6124
6125 beacon = kzalloc(size, GFP_KERNEL);
6126
6127 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306128 {
6129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6130 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006131 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306132 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006133
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006134#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006135 if(params->dtim_period || !old )
6136 beacon->dtim_period = params->dtim_period;
6137 else
6138 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006139#else
6140 if(dtim_period || !old )
6141 beacon->dtim_period = dtim_period;
6142 else
6143 beacon->dtim_period = old->dtim_period;
6144#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306145
Jeff Johnson295189b2012-06-20 16:38:30 -07006146 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6147 beacon->tail = beacon->head + head_len;
6148 beacon->head_len = head_len;
6149 beacon->tail_len = tail_len;
6150
6151 if(params->head) {
6152 memcpy (beacon->head,params->head,beacon->head_len);
6153 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306154 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07006155 if(old)
6156 memcpy (beacon->head,old->head,beacon->head_len);
6157 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306158
Jeff Johnson295189b2012-06-20 16:38:30 -07006159 if(params->tail) {
6160 memcpy (beacon->tail,params->tail,beacon->tail_len);
6161 }
6162 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306163 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07006164 memcpy (beacon->tail,old->tail,beacon->tail_len);
6165 }
6166
6167 *ppBeacon = beacon;
6168
6169 kfree(old);
6170
6171 return 0;
6172
6173}
Jeff Johnson295189b2012-06-20 16:38:30 -07006174
6175v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
6176{
6177 int left = length;
6178 v_U8_t *ptr = pIes;
6179 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306180
Jeff Johnson295189b2012-06-20 16:38:30 -07006181 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306182 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006183 elem_id = ptr[0];
6184 elem_len = ptr[1];
6185 left -= 2;
6186 if(elem_len > left)
6187 {
6188 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006189 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006190 eid,elem_len,left);
6191 return NULL;
6192 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306193 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006194 {
6195 return ptr;
6196 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306197
Jeff Johnson295189b2012-06-20 16:38:30 -07006198 left -= elem_len;
6199 ptr += (elem_len + 2);
6200 }
6201 return NULL;
6202}
6203
Jeff Johnson295189b2012-06-20 16:38:30 -07006204/* Check if rate is 11g rate or not */
6205static int wlan_hdd_rate_is_11g(u8 rate)
6206{
Sanjay Devnani28322e22013-06-21 16:13:40 -07006207 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006208 u8 i;
6209 for (i = 0; i < 8; i++)
6210 {
6211 if(rate == gRateArray[i])
6212 return TRUE;
6213 }
6214 return FALSE;
6215}
6216
6217/* Check for 11g rate and set proper 11g only mode */
6218static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
6219 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
6220{
6221 u8 i, num_rates = pIe[0];
6222
6223 pIe += 1;
6224 for ( i = 0; i < num_rates; i++)
6225 {
6226 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
6227 {
6228 /* If rate set have 11g rate than change the mode to 11G */
6229 *pSapHw_mode = eSAP_DOT11_MODE_11g;
6230 if (pIe[i] & BASIC_RATE_MASK)
6231 {
6232 /* If we have 11g rate as basic rate, it means mode
6233 is 11g only mode.
6234 */
6235 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
6236 *pCheckRatesfor11g = FALSE;
6237 }
6238 }
6239 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6240 {
6241 *require_ht = TRUE;
6242 }
6243 }
6244 return;
6245}
6246
6247static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
6248{
6249 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6250 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6251 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6252 u8 checkRatesfor11g = TRUE;
6253 u8 require_ht = FALSE;
6254 u8 *pIe=NULL;
6255
6256 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
6257
6258 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6259 pBeacon->head_len, WLAN_EID_SUPP_RATES);
6260 if (pIe != NULL)
6261 {
6262 pIe += 1;
6263 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6264 &pConfig->SapHw_mode);
6265 }
6266
6267 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6268 WLAN_EID_EXT_SUPP_RATES);
6269 if (pIe != NULL)
6270 {
6271
6272 pIe += 1;
6273 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6274 &pConfig->SapHw_mode);
6275 }
6276
6277 if( pConfig->channel > 14 )
6278 {
6279 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
6280 }
6281
6282 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6283 WLAN_EID_HT_CAPABILITY);
6284
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306285 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006286 {
6287 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
6288 if(require_ht)
6289 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
6290 }
6291}
6292
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306293static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
6294 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
6295{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006296 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306297 v_U8_t *pIe = NULL;
6298 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6299
6300 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6301 pBeacon->tail, pBeacon->tail_len);
6302
6303 if (pIe)
6304 {
6305 ielen = pIe[1] + 2;
6306 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6307 {
6308 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
6309 }
6310 else
6311 {
6312 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
6313 return -EINVAL;
6314 }
6315 *total_ielen += ielen;
6316 }
6317 return 0;
6318}
6319
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006320static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
6321 v_U8_t *genie, v_U8_t *total_ielen)
6322{
6323 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6324 int left = pBeacon->tail_len;
6325 v_U8_t *ptr = pBeacon->tail;
6326 v_U8_t elem_id, elem_len;
6327 v_U16_t ielen = 0;
6328
6329 if ( NULL == ptr || 0 == left )
6330 return;
6331
6332 while (left >= 2)
6333 {
6334 elem_id = ptr[0];
6335 elem_len = ptr[1];
6336 left -= 2;
6337 if (elem_len > left)
6338 {
6339 hddLog( VOS_TRACE_LEVEL_ERROR,
6340 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
6341 elem_id, elem_len, left);
6342 return;
6343 }
6344 if (IE_EID_VENDOR == elem_id)
6345 {
6346 /* skipping the VSIE's which we don't want to include or
6347 * it will be included by existing code
6348 */
6349 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
6350#ifdef WLAN_FEATURE_WFD
6351 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
6352#endif
6353 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6354 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6355 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
6356 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6357 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
6358 {
6359 ielen = ptr[1] + 2;
6360 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6361 {
6362 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
6363 *total_ielen += ielen;
6364 }
6365 else
6366 {
6367 hddLog( VOS_TRACE_LEVEL_ERROR,
6368 "IE Length is too big "
6369 "IEs eid=%d elem_len=%d total_ie_lent=%d",
6370 elem_id, elem_len, *total_ielen);
6371 }
6372 }
6373 }
6374
6375 left -= elem_len;
6376 ptr += (elem_len + 2);
6377 }
6378 return;
6379}
6380
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006381#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006382static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6383 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006384#else
6385static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6386 struct cfg80211_beacon_data *params)
6387#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006388{
6389 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306390 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006391 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07006392 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006393
6394 genie = vos_mem_malloc(MAX_GENIE_LEN);
6395
6396 if(genie == NULL) {
6397
6398 return -ENOMEM;
6399 }
6400
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306401 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6402 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006403 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306404 hddLog(LOGE,
6405 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306406 ret = -EINVAL;
6407 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006408 }
6409
6410#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306411 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6412 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
6413 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306414 hddLog(LOGE,
6415 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306416 ret = -EINVAL;
6417 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006418 }
6419#endif
6420
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306421 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6422 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006423 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306424 hddLog(LOGE,
6425 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306426 ret = -EINVAL;
6427 goto done;
6428 }
6429
6430 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
6431 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006432 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07006433 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006434
6435 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6436 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
6437 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6438 {
6439 hddLog(LOGE,
6440 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006441 ret = -EINVAL;
6442 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 }
6444
6445 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6446 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6447 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6448 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6449 ==eHAL_STATUS_FAILURE)
6450 {
6451 hddLog(LOGE,
6452 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006453 ret = -EINVAL;
6454 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006455 }
6456
6457 // Added for ProResp IE
6458 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
6459 {
6460 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
6461 u8 probe_rsp_ie_len[3] = {0};
6462 u8 counter = 0;
6463 /* Check Probe Resp Length if it is greater then 255 then Store
6464 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
6465 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
6466 Store More then 255 bytes into One Variable.
6467 */
6468 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6469 {
6470 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6471 {
6472 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6473 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6474 }
6475 else
6476 {
6477 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6478 rem_probe_resp_ie_len = 0;
6479 }
6480 }
6481
6482 rem_probe_resp_ie_len = 0;
6483
6484 if (probe_rsp_ie_len[0] > 0)
6485 {
6486 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6487 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6488 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6489 probe_rsp_ie_len[0], NULL,
6490 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6491 {
6492 hddLog(LOGE,
6493 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006494 ret = -EINVAL;
6495 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006496 }
6497 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6498 }
6499
6500 if (probe_rsp_ie_len[1] > 0)
6501 {
6502 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6503 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6504 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6505 probe_rsp_ie_len[1], NULL,
6506 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6507 {
6508 hddLog(LOGE,
6509 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006510 ret = -EINVAL;
6511 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006512 }
6513 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6514 }
6515
6516 if (probe_rsp_ie_len[2] > 0)
6517 {
6518 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6519 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6520 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6521 probe_rsp_ie_len[2], NULL,
6522 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6523 {
6524 hddLog(LOGE,
6525 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006526 ret = -EINVAL;
6527 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006528 }
6529 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6530 }
6531
6532 if (probe_rsp_ie_len[1] == 0 )
6533 {
6534 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6535 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6536 eANI_BOOLEAN_FALSE) )
6537 {
6538 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006539 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006540 }
6541 }
6542
6543 if (probe_rsp_ie_len[2] == 0 )
6544 {
6545 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6546 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6547 eANI_BOOLEAN_FALSE) )
6548 {
6549 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006550 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006551 }
6552 }
6553
6554 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6555 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6556 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6557 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6558 == eHAL_STATUS_FAILURE)
6559 {
6560 hddLog(LOGE,
6561 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006562 ret = -EINVAL;
6563 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006564 }
6565 }
6566 else
6567 {
6568 // Reset WNI_CFG_PROBE_RSP Flags
6569 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
6570
6571 hddLog(VOS_TRACE_LEVEL_INFO,
6572 "%s: No Probe Response IE received in set beacon",
6573 __func__);
6574 }
6575
6576 // Added for AssocResp IE
6577 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
6578 {
6579 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6580 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
6581 params->assocresp_ies_len, NULL,
6582 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6583 {
6584 hddLog(LOGE,
6585 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006586 ret = -EINVAL;
6587 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006588 }
6589
6590 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6591 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
6592 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6593 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6594 == eHAL_STATUS_FAILURE)
6595 {
6596 hddLog(LOGE,
6597 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006598 ret = -EINVAL;
6599 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006600 }
6601 }
6602 else
6603 {
6604 hddLog(VOS_TRACE_LEVEL_INFO,
6605 "%s: No Assoc Response IE received in set beacon",
6606 __func__);
6607
6608 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6609 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6610 eANI_BOOLEAN_FALSE) )
6611 {
6612 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006613 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006614 }
6615 }
6616
Jeff Johnsone7245742012-09-05 17:12:55 -07006617done:
Jeff Johnson295189b2012-06-20 16:38:30 -07006618 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306619 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006620}
Jeff Johnson295189b2012-06-20 16:38:30 -07006621
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306622/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006623 * FUNCTION: wlan_hdd_validate_operation_channel
6624 * called by wlan_hdd_cfg80211_start_bss() and
6625 * wlan_hdd_cfg80211_set_channel()
6626 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306627 * channel list.
6628 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006629VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006630{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306631
Jeff Johnson295189b2012-06-20 16:38:30 -07006632 v_U32_t num_ch = 0;
6633 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6634 u32 indx = 0;
6635 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306636 v_U8_t fValidChannel = FALSE, count = 0;
6637 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306638
Jeff Johnson295189b2012-06-20 16:38:30 -07006639 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6640
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306641 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006642 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306643 /* Validate the channel */
6644 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006645 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306646 if ( channel == rfChannels[count].channelNum )
6647 {
6648 fValidChannel = TRUE;
6649 break;
6650 }
6651 }
6652 if (fValidChannel != TRUE)
6653 {
6654 hddLog(VOS_TRACE_LEVEL_ERROR,
6655 "%s: Invalid Channel [%d]", __func__, channel);
6656 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006657 }
6658 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306659 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006660 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306661 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6662 valid_ch, &num_ch))
6663 {
6664 hddLog(VOS_TRACE_LEVEL_ERROR,
6665 "%s: failed to get valid channel list", __func__);
6666 return VOS_STATUS_E_FAILURE;
6667 }
6668 for (indx = 0; indx < num_ch; indx++)
6669 {
6670 if (channel == valid_ch[indx])
6671 {
6672 break;
6673 }
6674 }
6675
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306676 if (indx >= num_ch)
6677 {
6678 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6679 {
6680 eCsrBand band;
6681 unsigned int freq;
6682
6683 sme_GetFreqBand(hHal, &band);
6684
6685 if (eCSR_BAND_5G == band)
6686 {
6687#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6688 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6689 {
6690 freq = ieee80211_channel_to_frequency(channel,
6691 IEEE80211_BAND_2GHZ);
6692 }
6693 else
6694 {
6695 freq = ieee80211_channel_to_frequency(channel,
6696 IEEE80211_BAND_5GHZ);
6697 }
6698#else
6699 freq = ieee80211_channel_to_frequency(channel);
6700#endif
6701 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6702 return VOS_STATUS_SUCCESS;
6703 }
6704 }
6705
6706 hddLog(VOS_TRACE_LEVEL_ERROR,
6707 "%s: Invalid Channel [%d]", __func__, channel);
6708 return VOS_STATUS_E_FAILURE;
6709 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006710 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306711
Jeff Johnson295189b2012-06-20 16:38:30 -07006712 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306713
Jeff Johnson295189b2012-06-20 16:38:30 -07006714}
6715
Viral Modi3a32cc52013-02-08 11:14:52 -08006716/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306717 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08006718 * This function is used to set the channel number
6719 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306720static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08006721 struct ieee80211_channel *chan,
6722 enum nl80211_channel_type channel_type
6723 )
6724{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306725 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006726 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006727 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006728 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306729 hdd_context_t *pHddCtx;
6730 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006731
6732 ENTER();
6733
6734 if( NULL == dev )
6735 {
6736 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006737 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006738 return -ENODEV;
6739 }
6740 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306741
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306742 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6743 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6744 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006745 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306746 "%s: device_mode = %s (%d) freq = %d", __func__,
6747 hdd_device_modetoString(pAdapter->device_mode),
6748 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306749
6750 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6751 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306752 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006753 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306754 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006755 }
6756
6757 /*
6758 * Do freq to chan conversion
6759 * TODO: for 11a
6760 */
6761
6762 channel = ieee80211_frequency_to_channel(freq);
6763
6764 /* Check freq range */
6765 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6766 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6767 {
6768 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006769 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006770 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6771 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6772 return -EINVAL;
6773 }
6774
6775 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6776
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306777 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6778 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006779 {
6780 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6781 {
6782 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006783 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006784 return -EINVAL;
6785 }
6786 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6787 "%s: set channel to [%d] for device mode =%d",
6788 __func__, channel,pAdapter->device_mode);
6789 }
6790 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006791 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006792 )
6793 {
6794 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6795 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6796 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6797
6798 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6799 {
6800 /* Link is up then return cant set channel*/
6801 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006802 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006803 return -EINVAL;
6804 }
6805
6806 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6807 pHddStaCtx->conn_info.operationChannel = channel;
6808 pRoamProfile->ChannelInfo.ChannelList =
6809 &pHddStaCtx->conn_info.operationChannel;
6810 }
6811 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006812 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006813 )
6814 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306815 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6816 {
6817 if(VOS_STATUS_SUCCESS !=
6818 wlan_hdd_validate_operation_channel(pAdapter,channel))
6819 {
6820 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006821 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306822 return -EINVAL;
6823 }
6824 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6825 }
6826 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006827 {
6828 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6829
6830 /* If auto channel selection is configured as enable/ 1 then ignore
6831 channel set by supplicant
6832 */
6833 if ( cfg_param->apAutoChannelSelection )
6834 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306835 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6836 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006837 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306838 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6839 __func__, hdd_device_modetoString(pAdapter->device_mode),
6840 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006841 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306842 else
6843 {
6844 if(VOS_STATUS_SUCCESS !=
6845 wlan_hdd_validate_operation_channel(pAdapter,channel))
6846 {
6847 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006848 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306849 return -EINVAL;
6850 }
6851 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6852 }
Viral Modi3a32cc52013-02-08 11:14:52 -08006853 }
6854 }
6855 else
6856 {
6857 hddLog(VOS_TRACE_LEVEL_FATAL,
6858 "%s: Invalid device mode failed to set valid channel", __func__);
6859 return -EINVAL;
6860 }
6861 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306862 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006863}
6864
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306865static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
6866 struct net_device *dev,
6867 struct ieee80211_channel *chan,
6868 enum nl80211_channel_type channel_type
6869 )
6870{
6871 int ret;
6872
6873 vos_ssr_protect(__func__);
6874 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
6875 vos_ssr_unprotect(__func__);
6876
6877 return ret;
6878}
6879
Jeff Johnson295189b2012-06-20 16:38:30 -07006880#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6881static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6882 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006883#else
6884static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6885 struct cfg80211_beacon_data *params,
6886 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05306887 enum nl80211_hidden_ssid hidden_ssid,
6888 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006889#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006890{
6891 tsap_Config_t *pConfig;
6892 beacon_data_t *pBeacon = NULL;
6893 struct ieee80211_mgmt *pMgmt_frame;
6894 v_U8_t *pIe=NULL;
6895 v_U16_t capab_info;
6896 eCsrAuthType RSNAuthType;
6897 eCsrEncryptionType RSNEncryptType;
6898 eCsrEncryptionType mcRSNEncryptType;
6899 int status = VOS_STATUS_SUCCESS;
6900 tpWLAN_SAPEventCB pSapEventCallback;
6901 hdd_hostapd_state_t *pHostapdState;
6902 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
6903 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306904 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006905 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306906 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07006907 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08006908 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05306909 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07006910 v_BOOL_t MFPCapable = VOS_FALSE;
6911 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05306912 v_BOOL_t sapEnable11AC =
6913 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07006914 ENTER();
6915
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306916 iniConfig = pHddCtx->cfg_ini;
6917
Jeff Johnson295189b2012-06-20 16:38:30 -07006918 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
6919
6920 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6921
6922 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6923
6924 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6925
6926 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
6927
6928 //channel is already set in the set_channel Call back
6929 //pConfig->channel = pCommitConfig->channel;
6930
6931 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306932 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07006933 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
6934
6935 pConfig->dtim_period = pBeacon->dtim_period;
6936
Arif Hussain6d2a3322013-11-17 19:50:10 -08006937 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07006938 pConfig->dtim_period);
6939
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08006940 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07006941 {
6942 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006943 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05306944 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
6945 {
6946 tANI_BOOLEAN restartNeeded;
6947 pConfig->ieee80211d = 1;
6948 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
6949 sme_setRegInfo(hHal, pConfig->countryCode);
6950 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
6951 }
6952 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006953 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07006954 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07006955 pConfig->ieee80211d = 1;
6956 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
6957 sme_setRegInfo(hHal, pConfig->countryCode);
6958 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07006959 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006960 else
6961 {
6962 pConfig->ieee80211d = 0;
6963 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306964 /*
6965 * If auto channel is configured i.e. channel is 0,
6966 * so skip channel validation.
6967 */
6968 if( AUTO_CHANNEL_SELECT != pConfig->channel )
6969 {
6970 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
6971 {
6972 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006973 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306974 return -EINVAL;
6975 }
6976 }
6977 else
6978 {
6979 if(1 != pHddCtx->is_dynamic_channel_range_set)
6980 {
6981 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
6982 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
6983 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
6984 }
6985 pHddCtx->is_dynamic_channel_range_set = 0;
6986 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006987 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006988 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006989 {
6990 pConfig->ieee80211d = 0;
6991 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05306992
6993#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6994 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
6995 pConfig->authType = eSAP_OPEN_SYSTEM;
6996 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
6997 pConfig->authType = eSAP_SHARED_KEY;
6998 else
6999 pConfig->authType = eSAP_AUTO_SWITCH;
7000#else
7001 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7002 pConfig->authType = eSAP_OPEN_SYSTEM;
7003 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7004 pConfig->authType = eSAP_SHARED_KEY;
7005 else
7006 pConfig->authType = eSAP_AUTO_SWITCH;
7007#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007008
7009 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307010
7011 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07007012 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
7013
7014 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7015
7016 /*Set wps station to configured*/
7017 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7018
7019 if(pIe)
7020 {
7021 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
7022 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007023 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07007024 return -EINVAL;
7025 }
7026 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
7027 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007028 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07007029 /* Check 15 bit of WPS IE as it contain information for wps state
7030 * WPS state
7031 */
7032 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
7033 {
7034 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
7035 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
7036 {
7037 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7038 }
7039 }
7040 }
7041 else
7042 {
7043 pConfig->wps_state = SAP_WPS_DISABLED;
7044 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307045 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07007046
c_hpothufe599e92014-06-16 11:38:55 +05307047 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7048 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7049 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7050 eCSR_ENCRYPT_TYPE_NONE;
7051
Jeff Johnson295189b2012-06-20 16:38:30 -07007052 pConfig->RSNWPAReqIELength = 0;
7053 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307054 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007055 WLAN_EID_RSN);
7056 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307057 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007058 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7059 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7060 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307061 /* The actual processing may eventually be more extensive than
7062 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07007063 * by the app.
7064 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307065 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007066 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7067 &RSNEncryptType,
7068 &mcRSNEncryptType,
7069 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007070 &MFPCapable,
7071 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007072 pConfig->pRSNWPAReqIE[1]+2,
7073 pConfig->pRSNWPAReqIE );
7074
7075 if( VOS_STATUS_SUCCESS == status )
7076 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307077 /* Now copy over all the security attributes you have
7078 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007079 * */
7080 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7081 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7082 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7083 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307084 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007085 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007086 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7087 }
7088 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307089
Jeff Johnson295189b2012-06-20 16:38:30 -07007090 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7091 pBeacon->tail, pBeacon->tail_len);
7092
7093 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
7094 {
7095 if (pConfig->pRSNWPAReqIE)
7096 {
7097 /*Mixed mode WPA/WPA2*/
7098 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
7099 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7100 }
7101 else
7102 {
7103 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7104 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7105 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307106 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007107 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7108 &RSNEncryptType,
7109 &mcRSNEncryptType,
7110 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007111 &MFPCapable,
7112 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007113 pConfig->pRSNWPAReqIE[1]+2,
7114 pConfig->pRSNWPAReqIE );
7115
7116 if( VOS_STATUS_SUCCESS == status )
7117 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307118 /* Now copy over all the security attributes you have
7119 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007120 * */
7121 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7122 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7123 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7124 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307125 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007126 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007127 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7128 }
7129 }
7130 }
7131
Jeff Johnson4416a782013-03-25 14:17:50 -07007132 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
7133 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
7134 return -EINVAL;
7135 }
7136
Jeff Johnson295189b2012-06-20 16:38:30 -07007137 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
7138
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007139#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007140 if (params->ssid != NULL)
7141 {
7142 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
7143 pConfig->SSIDinfo.ssid.length = params->ssid_len;
7144 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7145 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7146 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007147#else
7148 if (ssid != NULL)
7149 {
7150 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
7151 pConfig->SSIDinfo.ssid.length = ssid_len;
7152 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7153 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7154 }
7155#endif
7156
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307157 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07007158 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307159
Jeff Johnson295189b2012-06-20 16:38:30 -07007160 /* default value */
7161 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7162 pConfig->num_accept_mac = 0;
7163 pConfig->num_deny_mac = 0;
7164
7165 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7166 pBeacon->tail, pBeacon->tail_len);
7167
7168 /* pIe for black list is following form:
7169 type : 1 byte
7170 length : 1 byte
7171 OUI : 4 bytes
7172 acl type : 1 byte
7173 no of mac addr in black list: 1 byte
7174 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307175 */
7176 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007177 {
7178 pConfig->SapMacaddr_acl = pIe[6];
7179 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007180 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007181 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307182 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7183 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007184 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7185 for (i = 0; i < pConfig->num_deny_mac; i++)
7186 {
7187 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7188 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307189 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007190 }
7191 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7192 pBeacon->tail, pBeacon->tail_len);
7193
7194 /* pIe for white list is following form:
7195 type : 1 byte
7196 length : 1 byte
7197 OUI : 4 bytes
7198 acl type : 1 byte
7199 no of mac addr in white list: 1 byte
7200 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307201 */
7202 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007203 {
7204 pConfig->SapMacaddr_acl = pIe[6];
7205 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007206 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007207 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307208 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7209 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007210 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7211 for (i = 0; i < pConfig->num_accept_mac; i++)
7212 {
7213 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7214 acl_entry++;
7215 }
7216 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307217
Jeff Johnson295189b2012-06-20 16:38:30 -07007218 wlan_hdd_set_sapHwmode(pHostapdAdapter);
7219
Jeff Johnsone7245742012-09-05 17:12:55 -07007220#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007221 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307222 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
7223 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05307224 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
7225 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007226 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
7227 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307228 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
7229 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07007230 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307231 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07007232 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307233 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007234
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307235 /* If ACS disable and selected channel <= 14
7236 * OR
7237 * ACS enabled and ACS operating band is choosen as 2.4
7238 * AND
7239 * VHT in 2.4G Disabled
7240 * THEN
7241 * Fallback to 11N mode
7242 */
7243 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
7244 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05307245 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307246 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007247 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307248 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
7249 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007250 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
7251 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007252 }
7253#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307254
Jeff Johnson295189b2012-06-20 16:38:30 -07007255 // ht_capab is not what the name conveys,this is used for protection bitmap
7256 pConfig->ht_capab =
7257 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
7258
7259 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
7260 {
7261 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7262 return -EINVAL;
7263 }
7264
7265 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307266 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07007267 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
7268 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307269 pConfig->obssProtEnabled =
7270 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07007271
Chet Lanctot8cecea22014-02-11 19:09:36 -08007272#ifdef WLAN_FEATURE_11W
7273 pConfig->mfpCapable = MFPCapable;
7274 pConfig->mfpRequired = MFPRequired;
7275 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
7276 pConfig->mfpCapable, pConfig->mfpRequired);
7277#endif
7278
Arif Hussain6d2a3322013-11-17 19:50:10 -08007279 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07007280 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007281 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
7282 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7283 (int)pConfig->channel);
7284 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
7285 pConfig->SapHw_mode, pConfig->privacy,
7286 pConfig->authType);
7287 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
7288 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7289 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7290 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07007291
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307292 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007293 {
7294 //Bss already started. just return.
7295 //TODO Probably it should update some beacon params.
7296 hddLog( LOGE, "Bss Already started...Ignore the request");
7297 EXIT();
7298 return 0;
7299 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307300
Agarwal Ashish51325b52014-06-16 16:50:49 +05307301 if (vos_max_concurrent_connections_reached()) {
7302 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7303 return -EINVAL;
7304 }
7305
Jeff Johnson295189b2012-06-20 16:38:30 -07007306 pConfig->persona = pHostapdAdapter->device_mode;
7307
Peng Xu2446a892014-09-05 17:21:18 +05307308 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
7309 if ( NULL != psmeConfig)
7310 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307311 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05307312 sme_GetConfigParam(hHal, psmeConfig);
7313 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307314#ifdef WLAN_FEATURE_AP_HT40_24G
7315 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7316 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
7317 && pHddCtx->cfg_ini->apHT40_24GEnabled)
7318 {
7319 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
7320 sme_UpdateConfig (hHal, psmeConfig);
7321 }
7322#endif
Peng Xu2446a892014-09-05 17:21:18 +05307323 vos_mem_free(psmeConfig);
7324 }
Peng Xuafc34e32014-09-25 13:23:55 +05307325 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05307326
Jeff Johnson295189b2012-06-20 16:38:30 -07007327 pSapEventCallback = hdd_hostapd_SAPEventCB;
7328 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
7329 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
7330 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007331 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007332 return -EINVAL;
7333 }
7334
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307335 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07007336 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7337
7338 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307339
Jeff Johnson295189b2012-06-20 16:38:30 -07007340 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307341 {
7342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007343 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07007344 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07007345 VOS_ASSERT(0);
7346 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307347
Jeff Johnson295189b2012-06-20 16:38:30 -07007348 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05307349 /* Initialize WMM configuation */
7350 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307351 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007352
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007353#ifdef WLAN_FEATURE_P2P_DEBUG
7354 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
7355 {
7356 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
7357 {
7358 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7359 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007360 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007361 }
7362 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
7363 {
7364 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7365 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007366 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007367 }
7368 }
7369#endif
7370
Jeff Johnson295189b2012-06-20 16:38:30 -07007371 pHostapdState->bCommit = TRUE;
7372 EXIT();
7373
7374 return 0;
7375}
7376
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007377#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307378static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307379 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007380 struct beacon_parameters *params)
7381{
7382 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307383 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307384 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007385
7386 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307387
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307388 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7389 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
7390 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307391 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
7392 hdd_device_modetoString(pAdapter->device_mode),
7393 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007394
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307395 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7396 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307397 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007398 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307399 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007400 }
7401
Agarwal Ashish51325b52014-06-16 16:50:49 +05307402 if (vos_max_concurrent_connections_reached()) {
7403 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7404 return -EINVAL;
7405 }
7406
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307407 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007408 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007409 )
7410 {
7411 beacon_data_t *old,*new;
7412
7413 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307414
Jeff Johnson295189b2012-06-20 16:38:30 -07007415 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307416 {
7417 hddLog(VOS_TRACE_LEVEL_WARN,
7418 FL("already beacon info added to session(%d)"),
7419 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007420 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307421 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007422
7423 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7424
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307425 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07007426 {
7427 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007428 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007429 return -EINVAL;
7430 }
7431
7432 pAdapter->sessionCtx.ap.beacon = new;
7433
7434 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7435 }
7436
7437 EXIT();
7438 return status;
7439}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307440
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307441static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
7442 struct net_device *dev,
7443 struct beacon_parameters *params)
7444{
7445 int ret;
7446
7447 vos_ssr_protect(__func__);
7448 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
7449 vos_ssr_unprotect(__func__);
7450
7451 return ret;
7452}
7453
7454static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007455 struct net_device *dev,
7456 struct beacon_parameters *params)
7457{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307458 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307459 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7460 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307461 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007462
7463 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307464
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307465 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7466 TRACE_CODE_HDD_CFG80211_SET_BEACON,
7467 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
7468 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7469 __func__, hdd_device_modetoString(pAdapter->device_mode),
7470 pAdapter->device_mode);
7471
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307472 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7473 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307474 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007475 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307476 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007477 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307478
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307479 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007480 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307481 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007482 {
7483 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307484
Jeff Johnson295189b2012-06-20 16:38:30 -07007485 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307486
Jeff Johnson295189b2012-06-20 16:38:30 -07007487 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307488 {
7489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7490 FL("session(%d) old and new heads points to NULL"),
7491 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007492 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307493 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007494
7495 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7496
7497 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307498 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007499 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007500 return -EINVAL;
7501 }
7502
7503 pAdapter->sessionCtx.ap.beacon = new;
7504
7505 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7506 }
7507
7508 EXIT();
7509 return status;
7510}
7511
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307512static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
7513 struct net_device *dev,
7514 struct beacon_parameters *params)
7515{
7516 int ret;
7517
7518 vos_ssr_protect(__func__);
7519 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
7520 vos_ssr_unprotect(__func__);
7521
7522 return ret;
7523}
7524
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007525#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7526
7527#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307528static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007529 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007530#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307531static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007532 struct net_device *dev)
7533#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007534{
7535 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07007536 hdd_context_t *pHddCtx = NULL;
7537 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307538 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307539 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007540
7541 ENTER();
7542
7543 if (NULL == pAdapter)
7544 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007546 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007547 return -ENODEV;
7548 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007549
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307550 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7551 TRACE_CODE_HDD_CFG80211_STOP_AP,
7552 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307553 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7554 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307555 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007556 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307557 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07007558 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007559
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007560 pScanInfo = &pHddCtx->scan_info;
7561
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307562 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7563 __func__, hdd_device_modetoString(pAdapter->device_mode),
7564 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007565
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307566 ret = wlan_hdd_scan_abort(pAdapter);
7567
Girish Gowli4bf7a632014-06-12 13:42:11 +05307568 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07007569 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7571 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307572
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307573 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07007574 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307575 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7576 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08007577
Jeff Johnsone7245742012-09-05 17:12:55 -07007578 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307579 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07007580 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307581 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07007582 }
7583
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05307584 /* Delete all associated STAs before stopping AP/P2P GO */
7585 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05307586 hdd_hostapd_stop(dev);
7587
Jeff Johnson295189b2012-06-20 16:38:30 -07007588 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007589 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007590 )
7591 {
7592 beacon_data_t *old;
7593
7594 old = pAdapter->sessionCtx.ap.beacon;
7595
7596 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307597 {
7598 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7599 FL("session(%d) beacon data points to NULL"),
7600 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007601 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307602 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007603
Jeff Johnson295189b2012-06-20 16:38:30 -07007604 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007605
7606 mutex_lock(&pHddCtx->sap_lock);
7607 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7608 {
Jeff Johnson4416a782013-03-25 14:17:50 -07007609 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007610 {
7611 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7612
7613 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7614
7615 if (!VOS_IS_STATUS_SUCCESS(status))
7616 {
7617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007618 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007619 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307620 }
7621 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007622 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307623 /* BSS stopped, clear the active sessions for this device mode */
7624 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007625 }
7626 mutex_unlock(&pHddCtx->sap_lock);
7627
7628 if(status != VOS_STATUS_SUCCESS)
7629 {
7630 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007631 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007632 return -EINVAL;
7633 }
7634
Jeff Johnson4416a782013-03-25 14:17:50 -07007635 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007636 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
7637 ==eHAL_STATUS_FAILURE)
7638 {
7639 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007640 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007641 }
7642
Jeff Johnson4416a782013-03-25 14:17:50 -07007643 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007644 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7645 eANI_BOOLEAN_FALSE) )
7646 {
7647 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007648 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007649 }
7650
7651 // Reset WNI_CFG_PROBE_RSP Flags
7652 wlan_hdd_reset_prob_rspies(pAdapter);
7653
7654 pAdapter->sessionCtx.ap.beacon = NULL;
7655 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007656#ifdef WLAN_FEATURE_P2P_DEBUG
7657 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7658 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
7659 {
7660 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
7661 "GO got removed");
7662 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
7663 }
7664#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007665 }
7666 EXIT();
7667 return status;
7668}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007669
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307670#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7671static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
7672 struct net_device *dev)
7673{
7674 int ret;
7675
7676 vos_ssr_protect(__func__);
7677 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
7678 vos_ssr_unprotect(__func__);
7679
7680 return ret;
7681}
7682#else
7683static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7684 struct net_device *dev)
7685{
7686 int ret;
7687
7688 vos_ssr_protect(__func__);
7689 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7690 vos_ssr_unprotect(__func__);
7691
7692 return ret;
7693}
7694#endif
7695
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007696#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7697
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307698static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307699 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007700 struct cfg80211_ap_settings *params)
7701{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307702 hdd_adapter_t *pAdapter;
7703 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307704 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007705
7706 ENTER();
7707
Girish Gowlib143d7a2015-02-18 19:39:55 +05307708 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007709 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05307711 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307712 return -ENODEV;
7713 }
7714
7715 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7716 if (NULL == pAdapter)
7717 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307719 "%s: HDD adapter is Null", __func__);
7720 return -ENODEV;
7721 }
7722
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307723 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7724 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
7725 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307726 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7727 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307729 "%s: HDD adapter magic is invalid", __func__);
7730 return -ENODEV;
7731 }
7732
7733 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307734 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307735 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307736 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307737 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307738 }
7739
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307740 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7741 __func__, hdd_device_modetoString(pAdapter->device_mode),
7742 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307743
7744 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007745 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007746 )
7747 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307748 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007749
7750 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307751
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007752 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307753 {
7754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7755 FL("already beacon info added to session(%d)"),
7756 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007757 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307758 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007759
Girish Gowlib143d7a2015-02-18 19:39:55 +05307760#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7761 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7762 &new,
7763 &params->beacon);
7764#else
7765 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7766 &new,
7767 &params->beacon,
7768 params->dtim_period);
7769#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007770
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307771 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007772 {
7773 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307774 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007775 return -EINVAL;
7776 }
7777 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007778#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007779 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7780#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7781 params->channel, params->channel_type);
7782#else
7783 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7784#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007785#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007786 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307787 params->ssid_len, params->hidden_ssid,
7788 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007789 }
7790
7791 EXIT();
7792 return status;
7793}
7794
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307795static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7796 struct net_device *dev,
7797 struct cfg80211_ap_settings *params)
7798{
7799 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007800
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307801 vos_ssr_protect(__func__);
7802 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
7803 vos_ssr_unprotect(__func__);
7804
7805 return ret;
7806}
7807
7808static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007809 struct net_device *dev,
7810 struct cfg80211_beacon_data *params)
7811{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307812 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307813 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307814 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007815
7816 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307817
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307818 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7819 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7820 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007821 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007822 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307823
7824 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7825 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307826 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007827 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307828 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007829 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007830
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307831 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007832 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307833 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007834 {
7835 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307836
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007837 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307838
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007839 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307840 {
7841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7842 FL("session(%d) beacon data points to NULL"),
7843 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007844 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307845 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007846
7847 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
7848
7849 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307850 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007851 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007852 return -EINVAL;
7853 }
7854
7855 pAdapter->sessionCtx.ap.beacon = new;
7856
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307857 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
7858 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007859 }
7860
7861 EXIT();
7862 return status;
7863}
7864
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307865static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
7866 struct net_device *dev,
7867 struct cfg80211_beacon_data *params)
7868{
7869 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007870
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307871 vos_ssr_protect(__func__);
7872 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
7873 vos_ssr_unprotect(__func__);
7874
7875 return ret;
7876}
7877
7878#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007879
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307880static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007881 struct net_device *dev,
7882 struct bss_parameters *params)
7883{
7884 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307885 hdd_context_t *pHddCtx;
7886 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007887
7888 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307889
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307890 if (NULL == pAdapter)
7891 {
7892 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7893 "%s: HDD adapter is Null", __func__);
7894 return -ENODEV;
7895 }
7896 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307897 ret = wlan_hdd_validate_context(pHddCtx);
7898 if (0 != ret)
7899 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307900 return ret;
7901 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307902 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7903 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
7904 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307905 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7906 __func__, hdd_device_modetoString(pAdapter->device_mode),
7907 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007908
7909 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007910 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307911 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007912 {
7913 /* ap_isolate == -1 means that in change bss, upper layer doesn't
7914 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307915 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07007916 {
7917 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307918 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007919 }
7920
7921 EXIT();
7922 return 0;
7923}
7924
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307925static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
7926 struct net_device *dev,
7927 struct bss_parameters *params)
7928{
7929 int ret;
7930
7931 vos_ssr_protect(__func__);
7932 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
7933 vos_ssr_unprotect(__func__);
7934
7935 return ret;
7936}
Kiet Lam10841362013-11-01 11:36:50 +05307937/* FUNCTION: wlan_hdd_change_country_code_cd
7938* to wait for contry code completion
7939*/
7940void* wlan_hdd_change_country_code_cb(void *pAdapter)
7941{
7942 hdd_adapter_t *call_back_pAdapter = pAdapter;
7943 complete(&call_back_pAdapter->change_country_code);
7944 return NULL;
7945}
7946
Jeff Johnson295189b2012-06-20 16:38:30 -07007947/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307948 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07007949 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
7950 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307951int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007952 struct net_device *ndev,
7953 enum nl80211_iftype type,
7954 u32 *flags,
7955 struct vif_params *params
7956 )
7957{
7958 struct wireless_dev *wdev;
7959 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007960 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07007961 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007962 tCsrRoamProfile *pRoamProfile = NULL;
7963 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307964 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007965 eMib_dot11DesiredBssType connectedBssType;
7966 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307967 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007968
7969 ENTER();
7970
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307971 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007972 {
7973 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7974 "%s: Adapter context is null", __func__);
7975 return VOS_STATUS_E_FAILURE;
7976 }
7977
7978 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7979 if (!pHddCtx)
7980 {
7981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7982 "%s: HDD context is null", __func__);
7983 return VOS_STATUS_E_FAILURE;
7984 }
7985
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307986 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7987 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
7988 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307989 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307990 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007991 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307992 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007993 }
7994
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307995 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7996 __func__, hdd_device_modetoString(pAdapter->device_mode),
7997 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007998
Agarwal Ashish51325b52014-06-16 16:50:49 +05307999 if (vos_max_concurrent_connections_reached()) {
8000 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8001 return -EINVAL;
8002 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308003 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07008004 wdev = ndev->ieee80211_ptr;
8005
8006#ifdef WLAN_BTAMP_FEATURE
8007 if((NL80211_IFTYPE_P2P_CLIENT == type)||
8008 (NL80211_IFTYPE_ADHOC == type)||
8009 (NL80211_IFTYPE_AP == type)||
8010 (NL80211_IFTYPE_P2P_GO == type))
8011 {
8012 pHddCtx->isAmpAllowed = VOS_FALSE;
8013 // stop AMP traffic
8014 status = WLANBAP_StopAmp();
8015 if(VOS_STATUS_SUCCESS != status )
8016 {
8017 pHddCtx->isAmpAllowed = VOS_TRUE;
8018 hddLog(VOS_TRACE_LEVEL_FATAL,
8019 "%s: Failed to stop AMP", __func__);
8020 return -EINVAL;
8021 }
8022 }
8023#endif //WLAN_BTAMP_FEATURE
8024 /* Reset the current device mode bit mask*/
8025 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8026
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +05308027 /* Notify Mode change in case of concurrency.
8028 * Below function invokes TDLS teardown Functionality Since TDLS is
8029 * not Supported in case of concurrency i.e Once P2P session
8030 * is detected disable offchannel and teardown TDLS links
8031 */
8032 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
8033
Jeff Johnson295189b2012-06-20 16:38:30 -07008034 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008035 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07008036 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008037 )
8038 {
8039 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008040 if (!pWextState)
8041 {
8042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8043 "%s: pWextState is null", __func__);
8044 return VOS_STATUS_E_FAILURE;
8045 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008046 pRoamProfile = &pWextState->roamProfile;
8047 LastBSSType = pRoamProfile->BSSType;
8048
8049 switch (type)
8050 {
8051 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008052 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008053 hddLog(VOS_TRACE_LEVEL_INFO,
8054 "%s: setting interface Type to INFRASTRUCTURE", __func__);
8055 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008056#ifdef WLAN_FEATURE_11AC
8057 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
8058 {
8059 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
8060 }
8061#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308062 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07008063 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008064 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008065 //Check for sub-string p2p to confirm its a p2p interface
8066 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308067 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008068 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8069 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8070 }
8071 else
8072 {
8073 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008074 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008075 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008076 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05308077
Jeff Johnson295189b2012-06-20 16:38:30 -07008078 case NL80211_IFTYPE_ADHOC:
8079 hddLog(VOS_TRACE_LEVEL_INFO,
8080 "%s: setting interface Type to ADHOC", __func__);
8081 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
8082 pRoamProfile->phyMode =
8083 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07008084 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008085 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05308086 hdd_set_ibss_ops( pAdapter );
8087 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +05308088
8089 status = hdd_sta_id_hash_attach(pAdapter);
8090 if (VOS_STATUS_SUCCESS != status) {
8091 hddLog(VOS_TRACE_LEVEL_ERROR,
8092 FL("Failed to initialize hash for IBSS"));
8093 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008094 break;
8095
8096 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008097 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008098 {
8099 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8100 "%s: setting interface Type to %s", __func__,
8101 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
8102
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008103 //Cancel any remain on channel for GO mode
8104 if (NL80211_IFTYPE_P2P_GO == type)
8105 {
8106 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
8107 }
Mohit Khanna0f232092012-09-11 14:46:08 -07008108 if (NL80211_IFTYPE_AP == type)
8109 {
8110 /* As Loading WLAN Driver one interface being created for p2p device
8111 * address. This will take one HW STA and the max number of clients
8112 * that can connect to softAP will be reduced by one. so while changing
8113 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
8114 * interface as it is not required in SoftAP mode.
8115 */
8116
8117 // Get P2P Adapter
8118 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
8119
8120 if (pP2pAdapter)
8121 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308122 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05308123 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07008124 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
8125 }
8126 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05308127 //Disable IMPS & BMPS for SAP/GO
8128 if(VOS_STATUS_E_FAILURE ==
8129 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
8130 {
8131 //Fail to Exit BMPS
8132 VOS_ASSERT(0);
8133 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05308134
8135 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
8136
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308137#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07008138
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308139 /* A Mutex Lock is introduced while changing the mode to
8140 * protect the concurrent access for the Adapters by TDLS
8141 * module.
8142 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308143 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308144#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008145 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05308146 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008147 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07008148 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8149 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308150#ifdef FEATURE_WLAN_TDLS
8151 mutex_unlock(&pHddCtx->tdls_lock);
8152#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008153 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
8154 (pConfig->apRandomBssidEnabled))
8155 {
8156 /* To meet Android requirements create a randomized
8157 MAC address of the form 02:1A:11:Fx:xx:xx */
8158 get_random_bytes(&ndev->dev_addr[3], 3);
8159 ndev->dev_addr[0] = 0x02;
8160 ndev->dev_addr[1] = 0x1A;
8161 ndev->dev_addr[2] = 0x11;
8162 ndev->dev_addr[3] |= 0xF0;
8163 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
8164 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08008165 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
8166 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008167 }
8168
Jeff Johnson295189b2012-06-20 16:38:30 -07008169 hdd_set_ap_ops( pAdapter->dev );
8170
Kiet Lam10841362013-11-01 11:36:50 +05308171 /* This is for only SAP mode where users can
8172 * control country through ini.
8173 * P2P GO follows station country code
8174 * acquired during the STA scanning. */
8175 if((NL80211_IFTYPE_AP == type) &&
8176 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
8177 {
8178 int status = 0;
8179 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
8180 "%s: setting country code from INI ", __func__);
8181 init_completion(&pAdapter->change_country_code);
8182 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
8183 (void *)(tSmeChangeCountryCallback)
8184 wlan_hdd_change_country_code_cb,
8185 pConfig->apCntryCode, pAdapter,
8186 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308187 eSIR_FALSE,
8188 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05308189 if (eHAL_STATUS_SUCCESS == status)
8190 {
8191 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308192 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05308193 &pAdapter->change_country_code,
8194 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308195 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05308196 {
8197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308198 FL("SME Timed out while setting country code %ld"),
8199 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08008200
8201 if (pHddCtx->isLogpInProgress)
8202 {
8203 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8204 "%s: LOGP in Progress. Ignore!!!", __func__);
8205 return -EAGAIN;
8206 }
Kiet Lam10841362013-11-01 11:36:50 +05308207 }
8208 }
8209 else
8210 {
8211 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008212 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05308213 return -EINVAL;
8214 }
8215 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008216 status = hdd_init_ap_mode(pAdapter);
8217 if(status != VOS_STATUS_SUCCESS)
8218 {
8219 hddLog(VOS_TRACE_LEVEL_FATAL,
8220 "%s: Error initializing the ap mode", __func__);
8221 return -EINVAL;
8222 }
8223 hdd_set_conparam(1);
8224
Nirav Shah7e3c8132015-06-22 23:51:42 +05308225 status = hdd_sta_id_hash_attach(pAdapter);
8226 if (VOS_STATUS_SUCCESS != status)
8227 {
8228 hddLog(VOS_TRACE_LEVEL_ERROR,
8229 FL("Failed to initialize hash for AP"));
8230 return -EINVAL;
8231 }
8232
Jeff Johnson295189b2012-06-20 16:38:30 -07008233 /*interface type changed update in wiphy structure*/
8234 if(wdev)
8235 {
8236 wdev->iftype = type;
8237 pHddCtx->change_iface = type;
8238 }
8239 else
8240 {
8241 hddLog(VOS_TRACE_LEVEL_ERROR,
8242 "%s: ERROR !!!! Wireless dev is NULL", __func__);
8243 return -EINVAL;
8244 }
8245 goto done;
8246 }
8247
8248 default:
8249 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8250 __func__);
8251 return -EOPNOTSUPP;
8252 }
8253 }
8254 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008255 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008256 )
8257 {
8258 switch(type)
8259 {
8260 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008261 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008262 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05308263
8264 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308265#ifdef FEATURE_WLAN_TDLS
8266
8267 /* A Mutex Lock is introduced while changing the mode to
8268 * protect the concurrent access for the Adapters by TDLS
8269 * module.
8270 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308271 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308272#endif
c_hpothu002231a2015-02-05 14:58:51 +05308273 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008274 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008275 //Check for sub-string p2p to confirm its a p2p interface
8276 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008277 {
8278 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8279 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8280 }
8281 else
8282 {
8283 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008284 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008285 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008286 hdd_set_conparam(0);
8287 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008288 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
8289 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308290#ifdef FEATURE_WLAN_TDLS
8291 mutex_unlock(&pHddCtx->tdls_lock);
8292#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308293 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008294 if( VOS_STATUS_SUCCESS != status )
8295 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07008296 /* In case of JB, for P2P-GO, only change interface will be called,
8297 * This is the right place to enable back bmps_imps()
8298 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308299 if (pHddCtx->hdd_wlan_suspended)
8300 {
8301 hdd_set_pwrparams(pHddCtx);
8302 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008303 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008304 goto done;
8305 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008306 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008307 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008308 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8309 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008310 goto done;
8311 default:
8312 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8313 __func__);
8314 return -EOPNOTSUPP;
8315
8316 }
8317
8318 }
8319 else
8320 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308321 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
8322 __func__, hdd_device_modetoString(pAdapter->device_mode),
8323 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008324 return -EOPNOTSUPP;
8325 }
8326
8327
8328 if(pRoamProfile)
8329 {
8330 if ( LastBSSType != pRoamProfile->BSSType )
8331 {
8332 /*interface type changed update in wiphy structure*/
8333 wdev->iftype = type;
8334
8335 /*the BSS mode changed, We need to issue disconnect
8336 if connected or in IBSS disconnect state*/
8337 if ( hdd_connGetConnectedBssType(
8338 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
8339 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
8340 {
8341 /*need to issue a disconnect to CSR.*/
8342 INIT_COMPLETION(pAdapter->disconnect_comp_var);
8343 if( eHAL_STATUS_SUCCESS ==
8344 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
8345 pAdapter->sessionId,
8346 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
8347 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308348 ret = wait_for_completion_interruptible_timeout(
8349 &pAdapter->disconnect_comp_var,
8350 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
8351 if (ret <= 0)
8352 {
8353 hddLog(VOS_TRACE_LEVEL_ERROR,
8354 FL("wait on disconnect_comp_var failed %ld"), ret);
8355 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008356 }
8357 }
8358 }
8359 }
8360
8361done:
8362 /*set bitmask based on updated value*/
8363 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07008364
8365 /* Only STA mode support TM now
8366 * all other mode, TM feature should be disabled */
8367 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
8368 (~VOS_STA & pHddCtx->concurrency_mode) )
8369 {
8370 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
8371 }
8372
Jeff Johnson295189b2012-06-20 16:38:30 -07008373#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308374 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05308375 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07008376 {
8377 //we are ok to do AMP
8378 pHddCtx->isAmpAllowed = VOS_TRUE;
8379 }
8380#endif //WLAN_BTAMP_FEATURE
8381 EXIT();
8382 return 0;
8383}
8384
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308385/*
8386 * FUNCTION: wlan_hdd_cfg80211_change_iface
8387 * wrapper function to protect the actual implementation from SSR.
8388 */
8389int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
8390 struct net_device *ndev,
8391 enum nl80211_iftype type,
8392 u32 *flags,
8393 struct vif_params *params
8394 )
8395{
8396 int ret;
8397
8398 vos_ssr_protect(__func__);
8399 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
8400 vos_ssr_unprotect(__func__);
8401
8402 return ret;
8403}
8404
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008405#ifdef FEATURE_WLAN_TDLS
8406static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
8407 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
8408{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008409 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008410 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308411 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308412 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308413 hdd_adapter_t *pAdapter;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008414
8415 ENTER();
8416
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308417 if (!dev) {
8418 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
8419 return -EINVAL;
8420 }
8421
8422 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8423 if (!pAdapter) {
8424 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
8425 return -EINVAL;
8426 }
8427
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308428 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008429 {
8430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8431 "Invalid arguments");
8432 return -EINVAL;
8433 }
Hoonki Lee27511902013-03-14 18:19:06 -07008434
8435 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
8436 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
8437 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07008439 "%s: TDLS mode is disabled OR not enabled in FW."
8440 MAC_ADDRESS_STR " Request declined.",
8441 __func__, MAC_ADDR_ARRAY(mac));
8442 return -ENOTSUPP;
8443 }
8444
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008445 if (pHddCtx->isLogpInProgress)
8446 {
8447 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8448 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05308449 wlan_hdd_tdls_set_link_status(pAdapter,
8450 mac,
8451 eTDLS_LINK_IDLE,
8452 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008453 return -EBUSY;
8454 }
8455
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308456 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05308457 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008458
8459 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008461 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
8462 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308463 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008464 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008465 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308466 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008467
8468 /* in add station, we accept existing valid staId if there is */
8469 if ((0 == update) &&
8470 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
8471 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008472 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008474 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008475 " link_status %d. staId %d. add station ignored.",
8476 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
8477 return 0;
8478 }
8479 /* in change station, we accept only when staId is valid */
8480 if ((1 == update) &&
8481 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
8482 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
8483 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308484 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008485 "%s: " MAC_ADDRESS_STR
8486 " link status %d. staId %d. change station %s.",
8487 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
8488 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
8489 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008490 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008491
8492 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05308493 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008494 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008495 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8496 "%s: " MAC_ADDRESS_STR
8497 " TDLS setup is ongoing. Request declined.",
8498 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07008499 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008500 }
8501
8502 /* first to check if we reached to maximum supported TDLS peer.
8503 TODO: for now, return -EPERM looks working fine,
8504 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308505 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8506 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008507 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008508 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8509 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308510 " TDLS Max peer already connected. Request declined."
8511 " Num of peers (%d), Max allowed (%d).",
8512 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
8513 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008514 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008515 }
8516 else
8517 {
8518 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308519 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008520 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008521 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008522 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8523 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
8524 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008525 return -EPERM;
8526 }
8527 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008528 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05308529 wlan_hdd_tdls_set_link_status(pAdapter,
8530 mac,
8531 eTDLS_LINK_CONNECTING,
8532 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008533
Jeff Johnsond75fe012013-04-06 10:53:06 -07008534 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308535 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008536 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008538 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008539 if(StaParams->htcap_present)
8540 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008542 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008544 "ht_capa->extended_capabilities: %0x",
8545 StaParams->HTCap.extendedHtCapInfo);
8546 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308547 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008548 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308549 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008550 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008551 if(StaParams->vhtcap_present)
8552 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308553 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008554 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
8555 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
8556 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
8557 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008558 {
8559 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008561 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008563 "[%d]: %x ", i, StaParams->supported_rates[i]);
8564 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07008565 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308566 else if ((1 == update) && (NULL == StaParams))
8567 {
8568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8569 "%s : update is true, but staParams is NULL. Error!", __func__);
8570 return -EPERM;
8571 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008572
8573 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
8574
8575 if (!update)
8576 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308577 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008578 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308579 if (ret != eHAL_STATUS_SUCCESS) {
8580 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to add TDLS peer STA"));
8581 return -EPERM;
8582 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008583 }
8584 else
8585 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308586 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008587 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308588 if (ret != eHAL_STATUS_SUCCESS) {
8589 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
8590 return -EPERM;
8591 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008592 }
8593
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308594 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008595 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
8596
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308597 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008598 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308600 "%s: timeout waiting for tdls add station indication %ld",
8601 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008602 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008603 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308604
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008605 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
8606 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008608 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008609 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008610 }
8611
8612 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008613
8614error:
Atul Mittal115287b2014-07-08 13:26:33 +05308615 wlan_hdd_tdls_set_link_status(pAdapter,
8616 mac,
8617 eTDLS_LINK_IDLE,
8618 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008619 return -EPERM;
8620
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008621}
8622#endif
8623
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308624static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008625 struct net_device *dev,
8626 u8 *mac,
8627 struct station_parameters *params)
8628{
8629 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308630 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308631 hdd_context_t *pHddCtx;
8632 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008633 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308634 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008635#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008636 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008637 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308638 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008639#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008640
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308641 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308642
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308643 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308644 if ((NULL == pAdapter))
8645 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308647 "invalid adapter ");
8648 return -EINVAL;
8649 }
8650
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308651 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8652 TRACE_CODE_HDD_CHANGE_STATION,
8653 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05308654 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308655
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308656 ret = wlan_hdd_validate_context(pHddCtx);
8657 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05308658 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308659 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308660 }
8661
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308662 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8663
8664 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008665 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8667 "invalid HDD station context");
8668 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008669 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008670 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
8671
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008672 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8673 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07008674 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008675 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07008676 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308677 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07008678 WLANTL_STA_AUTHENTICATED);
8679
Gopichand Nakkala29149562013-05-10 21:43:41 +05308680 if (status != VOS_STATUS_SUCCESS)
8681 {
8682 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8683 "%s: Not able to change TL state to AUTHENTICATED", __func__);
8684 return -EINVAL;
8685 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008686 }
8687 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07008688 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8689 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308690#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008691 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8692 StaParams.capability = params->capability;
8693 StaParams.uapsd_queues = params->uapsd_queues;
8694 StaParams.max_sp = params->max_sp;
8695
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308696 /* Convert (first channel , number of channels) tuple to
8697 * the total list of channels. This goes with the assumption
8698 * that if the first channel is < 14, then the next channels
8699 * are an incremental of 1 else an incremental of 4 till the number
8700 * of channels.
8701 */
8702 if (0 != params->supported_channels_len) {
8703 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
8704 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
8705 {
8706 int wifi_chan_index;
8707 StaParams.supported_channels[j] = params->supported_channels[i];
8708 wifi_chan_index =
8709 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
8710 no_of_channels = params->supported_channels[i+1];
8711 for(k=1; k <= no_of_channels; k++)
8712 {
8713 StaParams.supported_channels[j+1] =
8714 StaParams.supported_channels[j] + wifi_chan_index;
8715 j+=1;
8716 }
8717 }
8718 StaParams.supported_channels_len = j;
8719 }
8720 vos_mem_copy(StaParams.supported_oper_classes,
8721 params->supported_oper_classes,
8722 params->supported_oper_classes_len);
8723 StaParams.supported_oper_classes_len =
8724 params->supported_oper_classes_len;
8725
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008726 if (0 != params->ext_capab_len)
8727 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
8728 sizeof(StaParams.extn_capability));
8729
8730 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008731 {
8732 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008733 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008734 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008735
8736 StaParams.supported_rates_len = params->supported_rates_len;
8737
8738 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
8739 * The supported_rates array , for all the structures propogating till Add Sta
8740 * to the firmware has to be modified , if the supplicant (ieee80211) is
8741 * modified to send more rates.
8742 */
8743
8744 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
8745 */
8746 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
8747 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
8748
8749 if (0 != StaParams.supported_rates_len) {
8750 int i = 0;
8751 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
8752 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008754 "Supported Rates with Length %d", StaParams.supported_rates_len);
8755 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008757 "[%d]: %0x", i, StaParams.supported_rates[i]);
8758 }
8759
8760 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008761 {
8762 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008763 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008764 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008765
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008766 if (0 != params->ext_capab_len ) {
8767 /*Define A Macro : TODO Sunil*/
8768 if ((1<<4) & StaParams.extn_capability[3]) {
8769 isBufSta = 1;
8770 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308771 /* TDLS Channel Switching Support */
8772 if ((1<<6) & StaParams.extn_capability[3]) {
8773 isOffChannelSupported = 1;
8774 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008775 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308776 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
8777 &StaParams, isBufSta,
8778 isOffChannelSupported);
8779
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308780 if (VOS_STATUS_SUCCESS != status) {
8781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8782 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
8783 return -EINVAL;
8784 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008785 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
8786
8787 if (VOS_STATUS_SUCCESS != status) {
8788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8789 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
8790 return -EINVAL;
8791 }
8792 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008793#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05308794 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008795 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008796 return status;
8797}
8798
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308799static int wlan_hdd_change_station(struct wiphy *wiphy,
8800 struct net_device *dev,
8801 u8 *mac,
8802 struct station_parameters *params)
8803{
8804 int ret;
8805
8806 vos_ssr_protect(__func__);
8807 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
8808 vos_ssr_unprotect(__func__);
8809
8810 return ret;
8811}
8812
Jeff Johnson295189b2012-06-20 16:38:30 -07008813/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308814 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008815 * This function is used to initialize the key information
8816 */
8817#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308818static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008819 struct net_device *ndev,
8820 u8 key_index, bool pairwise,
8821 const u8 *mac_addr,
8822 struct key_params *params
8823 )
8824#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308825static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008826 struct net_device *ndev,
8827 u8 key_index, const u8 *mac_addr,
8828 struct key_params *params
8829 )
8830#endif
8831{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008832 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07008833 tCsrRoamSetKey setKey;
8834 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308835 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008836 v_U32_t roamId= 0xFF;
8837 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008838 hdd_hostapd_state_t *pHostapdState;
8839 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008840 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308841 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008842
8843 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308844
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308845 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8846 TRACE_CODE_HDD_CFG80211_ADD_KEY,
8847 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308848 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8849 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308850 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008851 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308852 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008853 }
8854
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308855 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8856 __func__, hdd_device_modetoString(pAdapter->device_mode),
8857 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008858
8859 if (CSR_MAX_NUM_KEY <= key_index)
8860 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008861 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008862 key_index);
8863
8864 return -EINVAL;
8865 }
8866
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008867 if (CSR_MAX_KEY_LEN < params->key_len)
8868 {
8869 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
8870 params->key_len);
8871
8872 return -EINVAL;
8873 }
8874
8875 hddLog(VOS_TRACE_LEVEL_INFO,
8876 "%s: called with key index = %d & key length %d",
8877 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008878
8879 /*extract key idx, key len and key*/
8880 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8881 setKey.keyId = key_index;
8882 setKey.keyLength = params->key_len;
8883 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
8884
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008885 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07008886 {
8887 case WLAN_CIPHER_SUITE_WEP40:
8888 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
8889 break;
8890
8891 case WLAN_CIPHER_SUITE_WEP104:
8892 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
8893 break;
8894
8895 case WLAN_CIPHER_SUITE_TKIP:
8896 {
8897 u8 *pKey = &setKey.Key[0];
8898 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
8899
8900 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
8901
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008902 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07008903
8904 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008905 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008906 |--------------|----------|----------|
8907 <---16bytes---><--8bytes--><--8bytes-->
8908
8909 */
8910 /*Sme expects the 32 bytes key to be in the below order
8911
8912 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008913 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008914 |--------------|----------|----------|
8915 <---16bytes---><--8bytes--><--8bytes-->
8916 */
8917 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008918 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07008919
8920 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008921 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008922
8923 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008924 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008925
8926
8927 break;
8928 }
8929
8930 case WLAN_CIPHER_SUITE_CCMP:
8931 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
8932 break;
8933
8934#ifdef FEATURE_WLAN_WAPI
8935 case WLAN_CIPHER_SUITE_SMS4:
8936 {
8937 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8938 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
8939 params->key, params->key_len);
8940 return 0;
8941 }
8942#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008943
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008944#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07008945 case WLAN_CIPHER_SUITE_KRK:
8946 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
8947 break;
8948#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008949
8950#ifdef WLAN_FEATURE_11W
8951 case WLAN_CIPHER_SUITE_AES_CMAC:
8952 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07008953 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07008954#endif
8955
Jeff Johnson295189b2012-06-20 16:38:30 -07008956 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008957 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07008958 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308959 status = -EOPNOTSUPP;
8960 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008961 }
8962
8963 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
8964 __func__, setKey.encType);
8965
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008966 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07008967#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8968 (!pairwise)
8969#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008970 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07008971#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008972 )
8973 {
8974 /* set group key*/
8975 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8976 "%s- %d: setting Broadcast key",
8977 __func__, __LINE__);
8978 setKey.keyDirection = eSIR_RX_ONLY;
8979 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8980 }
8981 else
8982 {
8983 /* set pairwise key*/
8984 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8985 "%s- %d: setting pairwise key",
8986 __func__, __LINE__);
8987 setKey.keyDirection = eSIR_TX_RX;
8988 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8989 }
8990 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
8991 {
8992 setKey.keyDirection = eSIR_TX_RX;
8993 /*Set the group key*/
8994 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8995 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07008996
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008997 if ( 0 != status )
8998 {
8999 hddLog(VOS_TRACE_LEVEL_ERROR,
9000 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309001 status = -EINVAL;
9002 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009003 }
9004 /*Save the keys here and call sme_RoamSetKey for setting
9005 the PTK after peer joins the IBSS network*/
9006 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
9007 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309008 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009009 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05309010 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
9011 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
9012 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009013 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009014 if( pHostapdState->bssState == BSS_START )
9015 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009016 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9017 vos_status = wlan_hdd_check_ula_done(pAdapter);
9018
9019 if ( vos_status != VOS_STATUS_SUCCESS )
9020 {
9021 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9022 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9023 __LINE__, vos_status );
9024
9025 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9026
9027 status = -EINVAL;
9028 goto end;
9029 }
9030
Jeff Johnson295189b2012-06-20 16:38:30 -07009031 status = WLANSAP_SetKeySta( pVosContext, &setKey);
9032
9033 if ( status != eHAL_STATUS_SUCCESS )
9034 {
9035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9036 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9037 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309038 status = -EINVAL;
9039 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009040 }
9041 }
9042
9043 /* Saving WEP keys */
9044 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
9045 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
9046 {
9047 //Save the wep key in ap context. Issue setkey after the BSS is started.
9048 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9049 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
9050 }
9051 else
9052 {
9053 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009054 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009055 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
9056 }
9057 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009058 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
9059 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009060 {
9061 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9062 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9063
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309064#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9065 if (!pairwise)
9066#else
9067 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9068#endif
9069 {
9070 /* set group key*/
9071 if (pHddStaCtx->roam_info.deferKeyComplete)
9072 {
9073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9074 "%s- %d: Perform Set key Complete",
9075 __func__, __LINE__);
9076 hdd_PerformRoamSetKeyComplete(pAdapter);
9077 }
9078 }
9079
Jeff Johnson295189b2012-06-20 16:38:30 -07009080 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
9081
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08009082 pWextState->roamProfile.Keys.defaultIndex = key_index;
9083
9084
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009085 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009086 params->key, params->key_len);
9087
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309088
Jeff Johnson295189b2012-06-20 16:38:30 -07009089 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9090
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309091 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009092 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309093 __func__, setKey.peerMac[0], setKey.peerMac[1],
9094 setKey.peerMac[2], setKey.peerMac[3],
9095 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009096 setKey.keyDirection);
9097
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009098 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +05309099
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009100 if ( vos_status != VOS_STATUS_SUCCESS )
9101 {
9102 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009103 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9104 __LINE__, vos_status );
9105
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009106 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009107
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009108 status = -EINVAL;
9109 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009110
9111 }
9112
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009113#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309114 /* The supplicant may attempt to set the PTK once pre-authentication
9115 is done. Save the key in the UMAC and include it in the ADD BSS
9116 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009117 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309118 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009119 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309120 hddLog(VOS_TRACE_LEVEL_INFO_MED,
9121 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309122 status = 0;
9123 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309124 }
9125 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
9126 {
9127 hddLog(VOS_TRACE_LEVEL_ERROR,
9128 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309129 status = -EINVAL;
9130 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009131 }
9132#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07009133
9134 /* issue set key request to SME*/
9135 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9136 pAdapter->sessionId, &setKey, &roamId );
9137
9138 if ( 0 != status )
9139 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309140 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009141 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
9142 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309143 status = -EINVAL;
9144 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009145 }
9146
9147
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309148 /* in case of IBSS as there was no information available about WEP keys during
9149 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07009150 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309151 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
9152 !( ( IW_AUTH_KEY_MGMT_802_1X
9153 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07009154 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
9155 )
9156 &&
9157 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
9158 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
9159 )
9160 )
9161 {
9162 setKey.keyDirection = eSIR_RX_ONLY;
9163 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9164
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309165 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009166 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309167 __func__, setKey.peerMac[0], setKey.peerMac[1],
9168 setKey.peerMac[2], setKey.peerMac[3],
9169 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009170 setKey.keyDirection);
9171
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309172 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009173 pAdapter->sessionId, &setKey, &roamId );
9174
9175 if ( 0 != status )
9176 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309177 hddLog(VOS_TRACE_LEVEL_ERROR,
9178 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009179 __func__, status);
9180 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309181 status = -EINVAL;
9182 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009183 }
9184 }
9185 }
9186
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309187end:
9188 /* Need to clear any trace of key value in the memory.
9189 * Thus zero out the memory even though it is local
9190 * variable.
9191 */
9192 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309193 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309194 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009195}
9196
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309197#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9198static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9199 struct net_device *ndev,
9200 u8 key_index, bool pairwise,
9201 const u8 *mac_addr,
9202 struct key_params *params
9203 )
9204#else
9205static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9206 struct net_device *ndev,
9207 u8 key_index, const u8 *mac_addr,
9208 struct key_params *params
9209 )
9210#endif
9211{
9212 int ret;
9213 vos_ssr_protect(__func__);
9214#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9215 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
9216 mac_addr, params);
9217#else
9218 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
9219 params);
9220#endif
9221 vos_ssr_unprotect(__func__);
9222
9223 return ret;
9224}
9225
Jeff Johnson295189b2012-06-20 16:38:30 -07009226/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309227 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009228 * This function is used to get the key information
9229 */
9230#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309231static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309232 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009233 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309234 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009235 const u8 *mac_addr, void *cookie,
9236 void (*callback)(void *cookie, struct key_params*)
9237 )
9238#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309239static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309240 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009241 struct net_device *ndev,
9242 u8 key_index, const u8 *mac_addr, void *cookie,
9243 void (*callback)(void *cookie, struct key_params*)
9244 )
9245#endif
9246{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309247 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309248 hdd_wext_state_t *pWextState = NULL;
9249 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009250 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309251 hdd_context_t *pHddCtx;
9252 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009253
9254 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309255
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309256 if (NULL == pAdapter)
9257 {
9258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9259 "%s: HDD adapter is Null", __func__);
9260 return -ENODEV;
9261 }
9262
9263 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9264 ret = wlan_hdd_validate_context(pHddCtx);
9265 if (0 != ret)
9266 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309267 return ret;
9268 }
9269
9270 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9271 pRoamProfile = &(pWextState->roamProfile);
9272
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309273 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9274 __func__, hdd_device_modetoString(pAdapter->device_mode),
9275 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309276
Jeff Johnson295189b2012-06-20 16:38:30 -07009277 memset(&params, 0, sizeof(params));
9278
9279 if (CSR_MAX_NUM_KEY <= key_index)
9280 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309281 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07009282 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309283 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009284
9285 switch(pRoamProfile->EncryptionType.encryptionType[0])
9286 {
9287 case eCSR_ENCRYPT_TYPE_NONE:
9288 params.cipher = IW_AUTH_CIPHER_NONE;
9289 break;
9290
9291 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
9292 case eCSR_ENCRYPT_TYPE_WEP40:
9293 params.cipher = WLAN_CIPHER_SUITE_WEP40;
9294 break;
9295
9296 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
9297 case eCSR_ENCRYPT_TYPE_WEP104:
9298 params.cipher = WLAN_CIPHER_SUITE_WEP104;
9299 break;
9300
9301 case eCSR_ENCRYPT_TYPE_TKIP:
9302 params.cipher = WLAN_CIPHER_SUITE_TKIP;
9303 break;
9304
9305 case eCSR_ENCRYPT_TYPE_AES:
9306 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
9307 break;
9308
9309 default:
9310 params.cipher = IW_AUTH_CIPHER_NONE;
9311 break;
9312 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309313
c_hpothuaaf19692014-05-17 17:01:48 +05309314 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9315 TRACE_CODE_HDD_CFG80211_GET_KEY,
9316 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309317
Jeff Johnson295189b2012-06-20 16:38:30 -07009318 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
9319 params.seq_len = 0;
9320 params.seq = NULL;
9321 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
9322 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309323 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009324 return 0;
9325}
9326
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309327#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9328static int wlan_hdd_cfg80211_get_key(
9329 struct wiphy *wiphy,
9330 struct net_device *ndev,
9331 u8 key_index, bool pairwise,
9332 const u8 *mac_addr, void *cookie,
9333 void (*callback)(void *cookie, struct key_params*)
9334 )
9335#else
9336static int wlan_hdd_cfg80211_get_key(
9337 struct wiphy *wiphy,
9338 struct net_device *ndev,
9339 u8 key_index, const u8 *mac_addr, void *cookie,
9340 void (*callback)(void *cookie, struct key_params*)
9341 )
9342#endif
9343{
9344 int ret;
9345
9346 vos_ssr_protect(__func__);
9347#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9348 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
9349 mac_addr, cookie, callback);
9350#else
9351 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
9352 callback);
9353#endif
9354 vos_ssr_unprotect(__func__);
9355
9356 return ret;
9357}
9358
Jeff Johnson295189b2012-06-20 16:38:30 -07009359/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309360 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009361 * This function is used to delete the key information
9362 */
9363#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309364static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009365 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309366 u8 key_index,
9367 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009368 const u8 *mac_addr
9369 )
9370#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309371static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009372 struct net_device *ndev,
9373 u8 key_index,
9374 const u8 *mac_addr
9375 )
9376#endif
9377{
9378 int status = 0;
9379
9380 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309381 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009382 //it is observed that this is invalidating peer
9383 //key index whenever re-key is done. This is affecting data link.
9384 //It should be ok to ignore del_key.
9385#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309386 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
9387 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009388 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
9389 tCsrRoamSetKey setKey;
9390 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309391
Jeff Johnson295189b2012-06-20 16:38:30 -07009392 ENTER();
9393
9394 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
9395 __func__,pAdapter->device_mode);
9396
9397 if (CSR_MAX_NUM_KEY <= key_index)
9398 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309399 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009400 key_index);
9401
9402 return -EINVAL;
9403 }
9404
9405 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9406 setKey.keyId = key_index;
9407
9408 if (mac_addr)
9409 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9410 else
9411 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
9412
9413 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
9414
9415 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009416 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309417 )
9418 {
9419
9420 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07009421 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9422 if( pHostapdState->bssState == BSS_START)
9423 {
9424 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309425
Jeff Johnson295189b2012-06-20 16:38:30 -07009426 if ( status != eHAL_STATUS_SUCCESS )
9427 {
9428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9429 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9430 __LINE__, status );
9431 }
9432 }
9433 }
9434 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309435 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07009436 )
9437 {
9438 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9439
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309440 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9441
9442 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009443 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309444 __func__, setKey.peerMac[0], setKey.peerMac[1],
9445 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07009446 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309447 if(pAdapter->sessionCtx.station.conn_info.connState ==
9448 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07009449 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309450 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009451 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309452
Jeff Johnson295189b2012-06-20 16:38:30 -07009453 if ( 0 != status )
9454 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309455 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009456 "%s: sme_RoamSetKey failure, returned %d",
9457 __func__, status);
9458 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9459 return -EINVAL;
9460 }
9461 }
9462 }
9463#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009464 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009465 return status;
9466}
9467
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309468#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9469static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9470 struct net_device *ndev,
9471 u8 key_index,
9472 bool pairwise,
9473 const u8 *mac_addr
9474 )
9475#else
9476static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9477 struct net_device *ndev,
9478 u8 key_index,
9479 const u8 *mac_addr
9480 )
9481#endif
9482{
9483 int ret;
9484
9485 vos_ssr_protect(__func__);
9486#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9487 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
9488 mac_addr);
9489#else
9490 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
9491#endif
9492 vos_ssr_unprotect(__func__);
9493
9494 return ret;
9495}
9496
Jeff Johnson295189b2012-06-20 16:38:30 -07009497/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309498 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009499 * This function is used to set the default tx key index
9500 */
9501#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309502static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009503 struct net_device *ndev,
9504 u8 key_index,
9505 bool unicast, bool multicast)
9506#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309507static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009508 struct net_device *ndev,
9509 u8 key_index)
9510#endif
9511{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309512 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309513 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309514 hdd_wext_state_t *pWextState;
9515 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309516 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009517
9518 ENTER();
9519
Gopichand Nakkala29149562013-05-10 21:43:41 +05309520 if ((NULL == pAdapter))
9521 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309523 "invalid adapter");
9524 return -EINVAL;
9525 }
9526
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309527 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9528 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
9529 pAdapter->sessionId, key_index));
9530
Gopichand Nakkala29149562013-05-10 21:43:41 +05309531 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9532 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9533
9534 if ((NULL == pWextState) || (NULL == pHddStaCtx))
9535 {
9536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9537 "invalid Wext state or HDD context");
9538 return -EINVAL;
9539 }
9540
Arif Hussain6d2a3322013-11-17 19:50:10 -08009541 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009542 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309543
Jeff Johnson295189b2012-06-20 16:38:30 -07009544 if (CSR_MAX_NUM_KEY <= key_index)
9545 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309546 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009547 key_index);
9548
9549 return -EINVAL;
9550 }
9551
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309552 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9553 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309554 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009555 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309556 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009557 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309558
Jeff Johnson295189b2012-06-20 16:38:30 -07009559 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07009560 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309561 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009562 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309563 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08009564 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309565 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08009566 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07009567 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309568 {
9569 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07009570 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309571
Jeff Johnson295189b2012-06-20 16:38:30 -07009572 tCsrRoamSetKey setKey;
9573 v_U32_t roamId= 0xFF;
9574 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309575
9576 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009577 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309578
Jeff Johnson295189b2012-06-20 16:38:30 -07009579 Keys->defaultIndex = (u8)key_index;
9580 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9581 setKey.keyId = key_index;
9582 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309583
9584 vos_mem_copy(&setKey.Key[0],
9585 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009586 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309587
Gopichand Nakkala29149562013-05-10 21:43:41 +05309588 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309589
9590 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07009591 &pHddStaCtx->conn_info.bssId[0],
9592 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309593
Gopichand Nakkala29149562013-05-10 21:43:41 +05309594 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
9595 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
9596 eCSR_ENCRYPT_TYPE_WEP104)
9597 {
9598 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
9599 even though ap is configured for WEP-40 encryption. In this canse the key length
9600 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
9601 type(104) and switching encryption type to 40*/
9602 pWextState->roamProfile.EncryptionType.encryptionType[0] =
9603 eCSR_ENCRYPT_TYPE_WEP40;
9604 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
9605 eCSR_ENCRYPT_TYPE_WEP40;
9606 }
9607
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309608 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07009609 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309610
Jeff Johnson295189b2012-06-20 16:38:30 -07009611 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309612 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009613 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309614
Jeff Johnson295189b2012-06-20 16:38:30 -07009615 if ( 0 != status )
9616 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309617 hddLog(VOS_TRACE_LEVEL_ERROR,
9618 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009619 status);
9620 return -EINVAL;
9621 }
9622 }
9623 }
9624
9625 /* In SoftAp mode setting key direction for default mode */
9626 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
9627 {
9628 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
9629 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
9630 (eCSR_ENCRYPT_TYPE_AES !=
9631 pWextState->roamProfile.EncryptionType.encryptionType[0])
9632 )
9633 {
9634 /* Saving key direction for default key index to TX default */
9635 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9636 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
9637 }
9638 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309639 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009640 return status;
9641}
9642
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309643#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9644static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9645 struct net_device *ndev,
9646 u8 key_index,
9647 bool unicast, bool multicast)
9648#else
9649static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9650 struct net_device *ndev,
9651 u8 key_index)
9652#endif
9653{
9654 int ret;
9655 vos_ssr_protect(__func__);
9656#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9657 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
9658 multicast);
9659#else
9660 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
9661#endif
9662 vos_ssr_unprotect(__func__);
9663
9664 return ret;
9665}
9666
Jeff Johnson295189b2012-06-20 16:38:30 -07009667/*
9668 * FUNCTION: wlan_hdd_cfg80211_inform_bss
9669 * This function is used to inform the BSS details to nl80211 interface.
9670 */
9671static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
9672 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
9673{
9674 struct net_device *dev = pAdapter->dev;
9675 struct wireless_dev *wdev = dev->ieee80211_ptr;
9676 struct wiphy *wiphy = wdev->wiphy;
9677 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
9678 int chan_no;
9679 int ie_length;
9680 const char *ie;
9681 unsigned int freq;
9682 struct ieee80211_channel *chan;
9683 int rssi = 0;
9684 struct cfg80211_bss *bss = NULL;
9685
Jeff Johnson295189b2012-06-20 16:38:30 -07009686 if( NULL == pBssDesc )
9687 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009688 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009689 return bss;
9690 }
9691
9692 chan_no = pBssDesc->channelId;
9693 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
9694 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
9695
9696 if( NULL == ie )
9697 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009698 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009699 return bss;
9700 }
9701
9702#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9703 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9704 {
9705 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9706 }
9707 else
9708 {
9709 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9710 }
9711#else
9712 freq = ieee80211_channel_to_frequency(chan_no);
9713#endif
9714
9715 chan = __ieee80211_get_channel(wiphy, freq);
9716
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05309717 if (!chan) {
9718 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
9719 return NULL;
9720 }
9721
Abhishek Singhaee43942014-06-16 18:55:47 +05309722 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07009723
Abhishek Singhaee43942014-06-16 18:55:47 +05309724 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309725 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07009726 pBssDesc->capabilityInfo,
9727 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05309728 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07009729}
9730
9731
9732
9733/*
9734 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
9735 * This function is used to inform the BSS details to nl80211 interface.
9736 */
9737struct cfg80211_bss*
9738wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
9739 tSirBssDescription *bss_desc
9740 )
9741{
9742 /*
9743 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
9744 already exists in bss data base of cfg80211 for that particular BSS ID.
9745 Using cfg80211_inform_bss_frame to update the bss entry instead of
9746 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
9747 now there is no possibility to get the mgmt(probe response) frame from PE,
9748 converting bss_desc to ieee80211_mgmt(probe response) and passing to
9749 cfg80211_inform_bss_frame.
9750 */
9751 struct net_device *dev = pAdapter->dev;
9752 struct wireless_dev *wdev = dev->ieee80211_ptr;
9753 struct wiphy *wiphy = wdev->wiphy;
9754 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009755#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9756 qcom_ie_age *qie_age = NULL;
9757 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
9758#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009759 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009760#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009761 const char *ie =
9762 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
9763 unsigned int freq;
9764 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309765 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009766 struct cfg80211_bss *bss_status = NULL;
9767 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
9768 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07009769 hdd_context_t *pHddCtx;
9770 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07009771#ifdef WLAN_OPEN_SOURCE
9772 struct timespec ts;
9773#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009774
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309775
Wilson Yangf80a0542013-10-07 13:02:37 -07009776 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9777 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -07009778 if (0 != status)
9779 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009780 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009781 }
9782
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309783 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07009784 if (!mgmt)
9785 {
9786 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9787 "%s: memory allocation failed ", __func__);
9788 return NULL;
9789 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009790
Jeff Johnson295189b2012-06-20 16:38:30 -07009791 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07009792
9793#ifdef WLAN_OPEN_SOURCE
9794 /* Android does not want the timestamp from the frame.
9795 Instead it wants a monotonic increasing value */
9796 get_monotonic_boottime(&ts);
9797 mgmt->u.probe_resp.timestamp =
9798 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
9799#else
9800 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009801 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
9802 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07009803
9804#endif
9805
Jeff Johnson295189b2012-06-20 16:38:30 -07009806 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
9807 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009808
9809#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9810 /* GPS Requirement: need age ie per entry. Using vendor specific. */
9811 /* Assuming this is the last IE, copy at the end */
9812 ie_length -=sizeof(qcom_ie_age);
9813 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
9814 qie_age->element_id = QCOM_VENDOR_IE_ID;
9815 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
9816 qie_age->oui_1 = QCOM_OUI1;
9817 qie_age->oui_2 = QCOM_OUI2;
9818 qie_age->oui_3 = QCOM_OUI3;
9819 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
9820 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
9821#endif
9822
Jeff Johnson295189b2012-06-20 16:38:30 -07009823 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05309824 if (bss_desc->fProbeRsp)
9825 {
9826 mgmt->frame_control |=
9827 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
9828 }
9829 else
9830 {
9831 mgmt->frame_control |=
9832 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
9833 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009834
9835#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309836 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009837 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
9838 {
9839 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9840 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309841 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009842 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
9843
9844 {
9845 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9846 }
9847 else
9848 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309849 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
9850 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07009851 kfree(mgmt);
9852 return NULL;
9853 }
9854#else
9855 freq = ieee80211_channel_to_frequency(chan_no);
9856#endif
9857 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009858 /*when the band is changed on the fly using the GUI, three things are done
9859 * 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)
9860 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
9861 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
9862 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
9863 * and discards the channels correponding to previous band and calls back with zero bss results.
9864 * 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
9865 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
9866 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
9867 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
9868 * So drop the bss and continue to next bss.
9869 */
9870 if(chan == NULL)
9871 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309872 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07009873 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009874 return NULL;
9875 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +05309876 /*To keep the rssi icon of the connected AP in the scan window
9877 *and the rssi icon of the wireless networks in sync
9878 * */
9879 if (( eConnectionState_Associated ==
9880 pAdapter->sessionCtx.station.conn_info.connState ) &&
9881 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
9882 pAdapter->sessionCtx.station.conn_info.bssId,
9883 WNI_CFG_BSSID_LEN)) &&
9884 (pHddCtx->hdd_wlan_suspended == FALSE))
9885 {
9886 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
9887 rssi = (pAdapter->rssi * 100);
9888 }
9889 else
9890 {
9891 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
9892 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009893
Nirav Shah20ac06f2013-12-12 18:14:06 +05309894 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +05309895 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
9896 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +05309897
Jeff Johnson295189b2012-06-20 16:38:30 -07009898 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
9899 frame_len, rssi, GFP_KERNEL);
9900 kfree(mgmt);
9901 return bss_status;
9902}
9903
9904/*
9905 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
9906 * This function is used to update the BSS data base of CFG8011
9907 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309908struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009909 tCsrRoamInfo *pRoamInfo
9910 )
9911{
9912 tCsrRoamConnectedProfile roamProfile;
9913 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9914 struct cfg80211_bss *bss = NULL;
9915
9916 ENTER();
9917
9918 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
9919 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
9920
9921 if (NULL != roamProfile.pBssDesc)
9922 {
Girish Gowlif4b68022014-08-28 23:18:57 +05309923 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9924 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009925
9926 if (NULL == bss)
9927 {
9928 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
9929 __func__);
9930 }
9931
9932 sme_RoamFreeConnectProfile(hHal, &roamProfile);
9933 }
9934 else
9935 {
9936 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
9937 __func__);
9938 }
9939 return bss;
9940}
9941
9942/*
9943 * FUNCTION: wlan_hdd_cfg80211_update_bss
9944 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309945static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
9946 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07009947 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309948{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309949 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009950 tCsrScanResultInfo *pScanResult;
9951 eHalStatus status = 0;
9952 tScanResultHandle pResult;
9953 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009954 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +05309955 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -07009956 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309957
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309958 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9959 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
9960 NO_SESSION, pAdapter->sessionId));
9961
Wilson Yangf80a0542013-10-07 13:02:37 -07009962 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9963
9964 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009965 {
Wilson Yangf80a0542013-10-07 13:02:37 -07009966 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9967 "%s:LOGP in Progress. Ignore!!!",__func__);
9968 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009969 }
9970
Wilson Yangf80a0542013-10-07 13:02:37 -07009971
9972 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309973 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009974 {
9975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9976 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9977 return VOS_STATUS_E_PERM;
9978 }
9979
Deepthi Gowri10d0ae12015-05-25 14:39:50 +05309980 if (pAdapter->request != NULL)
9981 {
9982 if ((pAdapter->request->n_ssids == 1)
9983 && (pAdapter->request->ssids != NULL)
9984 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
9985 is_p2p_scan = true;
9986 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009987 /*
9988 * start getting scan results and populate cgf80211 BSS database
9989 */
9990 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
9991
9992 /* no scan results */
9993 if (NULL == pResult)
9994 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309995 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
9996 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +05309997 wlan_hdd_get_frame_logs(pAdapter,
9998 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -07009999 return status;
10000 }
10001
10002 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
10003
10004 while (pScanResult)
10005 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010006 /*
10007 * cfg80211_inform_bss() is not updating ie field of bss entry, if
10008 * entry already exists in bss data base of cfg80211 for that
10009 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
10010 * bss entry instead of cfg80211_inform_bss, But this call expects
10011 * mgmt packet as input. As of now there is no possibility to get
10012 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070010013 * ieee80211_mgmt(probe response) and passing to c
10014 * fg80211_inform_bss_frame.
10015 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010016 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
10017 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
10018 {
10019 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Non P2P BSS skipped: =%s:"),
10020 pScanResult->ssId.ssId);
10021 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10022 continue; //Skip the non p2p bss entries
10023 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010024 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10025 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010026
Jeff Johnson295189b2012-06-20 16:38:30 -070010027
10028 if (NULL == bss_status)
10029 {
10030 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010031 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010032 }
10033 else
10034 {
Yue Maf49ba872013-08-19 12:04:25 -070010035 cfg80211_put_bss(
10036#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
10037 wiphy,
10038#endif
10039 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010040 }
10041
10042 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10043 }
10044
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010045 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010046 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010047 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010048}
10049
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010050void
10051hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
10052{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010053 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080010054 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010055} /****** end hddPrintMacAddr() ******/
10056
10057void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010058hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010059{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010060 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010061 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010062 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
10063 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
10064 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010065} /****** end hddPrintPmkId() ******/
10066
10067//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
10068//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
10069
10070//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
10071//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
10072
10073#define dump_bssid(bssid) \
10074 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010075 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
10076 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010077 }
10078
10079#define dump_pmkid(pMac, pmkid) \
10080 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010081 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
10082 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010083 }
10084
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070010085#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010086/*
10087 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
10088 * This function is used to notify the supplicant of a new PMKSA candidate.
10089 */
10090int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010091 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010092 int index, bool preauth )
10093{
Jeff Johnsone7245742012-09-05 17:12:55 -070010094#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010095 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010096 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010097
10098 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070010099 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010100
10101 if( NULL == pRoamInfo )
10102 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010103 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010104 return -EINVAL;
10105 }
10106
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010107 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
10108 {
10109 dump_bssid(pRoamInfo->bssid);
10110 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010111 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010112 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010113#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010114 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010115}
10116#endif //FEATURE_WLAN_LFR
10117
Yue Maef608272013-04-08 23:09:17 -070010118#ifdef FEATURE_WLAN_LFR_METRICS
10119/*
10120 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
10121 * 802.11r/LFR metrics reporting function to report preauth initiation
10122 *
10123 */
10124#define MAX_LFR_METRICS_EVENT_LENGTH 100
10125VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
10126 tCsrRoamInfo *pRoamInfo)
10127{
10128 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10129 union iwreq_data wrqu;
10130
10131 ENTER();
10132
10133 if (NULL == pAdapter)
10134 {
10135 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10136 return VOS_STATUS_E_FAILURE;
10137 }
10138
10139 /* create the event */
10140 memset(&wrqu, 0, sizeof(wrqu));
10141 memset(metrics_notification, 0, sizeof(metrics_notification));
10142
10143 wrqu.data.pointer = metrics_notification;
10144 wrqu.data.length = scnprintf(metrics_notification,
10145 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
10146 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10147
10148 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10149
10150 EXIT();
10151
10152 return VOS_STATUS_SUCCESS;
10153}
10154
10155/*
10156 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
10157 * 802.11r/LFR metrics reporting function to report preauth completion
10158 * or failure
10159 */
10160VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
10161 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
10162{
10163 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10164 union iwreq_data wrqu;
10165
10166 ENTER();
10167
10168 if (NULL == pAdapter)
10169 {
10170 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10171 return VOS_STATUS_E_FAILURE;
10172 }
10173
10174 /* create the event */
10175 memset(&wrqu, 0, sizeof(wrqu));
10176 memset(metrics_notification, 0, sizeof(metrics_notification));
10177
10178 scnprintf(metrics_notification, sizeof(metrics_notification),
10179 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
10180 MAC_ADDR_ARRAY(pRoamInfo->bssid));
10181
10182 if (1 == preauth_status)
10183 strncat(metrics_notification, " TRUE", 5);
10184 else
10185 strncat(metrics_notification, " FALSE", 6);
10186
10187 wrqu.data.pointer = metrics_notification;
10188 wrqu.data.length = strlen(metrics_notification);
10189
10190 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10191
10192 EXIT();
10193
10194 return VOS_STATUS_SUCCESS;
10195}
10196
10197/*
10198 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
10199 * 802.11r/LFR metrics reporting function to report handover initiation
10200 *
10201 */
10202VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
10203 tCsrRoamInfo *pRoamInfo)
10204{
10205 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10206 union iwreq_data wrqu;
10207
10208 ENTER();
10209
10210 if (NULL == pAdapter)
10211 {
10212 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10213 return VOS_STATUS_E_FAILURE;
10214 }
10215
10216 /* create the event */
10217 memset(&wrqu, 0, sizeof(wrqu));
10218 memset(metrics_notification, 0, sizeof(metrics_notification));
10219
10220 wrqu.data.pointer = metrics_notification;
10221 wrqu.data.length = scnprintf(metrics_notification,
10222 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
10223 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10224
10225 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10226
10227 EXIT();
10228
10229 return VOS_STATUS_SUCCESS;
10230}
10231#endif
10232
Jeff Johnson295189b2012-06-20 16:38:30 -070010233/*
10234 * FUNCTION: hdd_cfg80211_scan_done_callback
10235 * scanning callback function, called after finishing scan
10236 *
10237 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010238static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070010239 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
10240{
10241 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010242 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070010243 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010244 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010245 struct cfg80211_scan_request *req = NULL;
10246 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010247 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010248 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010249 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010250 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010251
10252 ENTER();
10253
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010254 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053010255 if (NULL == pHddCtx) {
10256 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010257 goto allow_suspend;
10258 }
10259
10260 pScanInfo = &pHddCtx->scan_info;
10261
Jeff Johnson295189b2012-06-20 16:38:30 -070010262 hddLog(VOS_TRACE_LEVEL_INFO,
10263 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080010264 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010265 __func__, halHandle, pContext, (int) scanId, (int) status);
10266
Kiet Lamac06e2c2013-10-23 16:25:07 +053010267 pScanInfo->mScanPendingCounter = 0;
10268
Jeff Johnson295189b2012-06-20 16:38:30 -070010269 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010270 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070010271 &pScanInfo->scan_req_completion_event,
10272 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010273 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070010274 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010275 hddLog(VOS_TRACE_LEVEL_ERROR,
10276 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070010277 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010278 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010279 }
10280
Yue Maef608272013-04-08 23:09:17 -070010281 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010282 {
10283 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010284 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010285 }
10286
10287 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010288 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070010289 {
10290 hddLog(VOS_TRACE_LEVEL_INFO,
10291 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010292 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070010293 (int) scanId);
10294 }
10295
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010296 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010297 pAdapter);
10298
10299 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010300 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010301
10302
10303 /* If any client wait scan result through WEXT
10304 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010305 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070010306 {
10307 /* The other scan request waiting for current scan finish
10308 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010309 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010310 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010311 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070010312 }
10313 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010314 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010315 {
10316 struct net_device *dev = pAdapter->dev;
10317 union iwreq_data wrqu;
10318 int we_event;
10319 char *msg;
10320
10321 memset(&wrqu, '\0', sizeof(wrqu));
10322 we_event = SIOCGIWSCAN;
10323 msg = NULL;
10324 wireless_send_event(dev, we_event, &wrqu, msg);
10325 }
10326 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010327 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010328
10329 /* Get the Scan Req */
10330 req = pAdapter->request;
10331
10332 if (!req)
10333 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010334 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010335 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010336 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010337 }
10338
Jeff Johnson295189b2012-06-20 16:38:30 -070010339 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070010340 /* Scan is no longer pending */
10341 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010342
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010343 /* last_scan_timestamp is used to decide if new scan
10344 * is needed or not on station interface. If last station
10345 * scan time and new station scan time is less then
10346 * last_scan_timestamp ; driver will return cached scan.
10347 */
10348 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
10349 {
10350 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
10351
10352 if ( req->n_channels )
10353 {
10354 for (i = 0; i < req->n_channels ; i++ )
10355 {
10356 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
10357 }
10358 /* store no of channel scanned */
10359 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
10360 }
10361
10362 }
10363
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070010364 /*
10365 * cfg80211_scan_done informing NL80211 about completion
10366 * of scanning
10367 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010368 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
10369 {
10370 aborted = true;
10371 }
10372 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080010373 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010374
Siddharth Bhal76972212014-10-15 16:22:51 +053010375 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
10376 /* Generate new random mac addr for next scan */
10377 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
10378 hdd_processSpoofMacAddrRequest(pHddCtx);
10379 }
10380
Jeff Johnsone7245742012-09-05 17:12:55 -070010381allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010382 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010383 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010384
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010385 /* Acquire wakelock to handle the case where APP's tries to suspend
10386 * immediatly after the driver gets connect request(i.e after scan)
10387 * from supplicant, this result in app's is suspending and not able
10388 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010389 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010390
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010391#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010392 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010393#endif
10394
Jeff Johnson295189b2012-06-20 16:38:30 -070010395 EXIT();
10396 return 0;
10397}
10398
10399/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053010400 * FUNCTION: hdd_isConnectionInProgress
10401 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010402 *
10403 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010404v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010405{
10406 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10407 hdd_station_ctx_t *pHddStaCtx = NULL;
10408 hdd_adapter_t *pAdapter = NULL;
10409 VOS_STATUS status = 0;
10410 v_U8_t staId = 0;
10411 v_U8_t *staMac = NULL;
10412
c_hpothu9b781ba2013-12-30 20:57:45 +053010413 if (TRUE == pHddCtx->btCoexModeSet)
10414 {
10415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053010416 FL("BTCoex Mode operation in progress"));
10417 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053010418 }
10419
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010420 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10421
10422 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10423 {
10424 pAdapter = pAdapterNode->pAdapter;
10425
10426 if( pAdapter )
10427 {
10428 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010429 "%s: Adapter with device mode %s (%d) exists",
10430 __func__, hdd_device_modetoString(pAdapter->device_mode),
10431 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010432 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053010433 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10434 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
10435 (eConnectionState_Connecting ==
10436 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
10437 {
10438 hddLog(VOS_TRACE_LEVEL_ERROR,
10439 "%s: %p(%d) Connection is in progress", __func__,
10440 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10441 return VOS_TRUE;
10442 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010443 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053010444 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010445 {
10446 hddLog(VOS_TRACE_LEVEL_ERROR,
10447 "%s: %p(%d) Reassociation is in progress", __func__,
10448 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10449 return VOS_TRUE;
10450 }
10451 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010452 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10453 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010454 {
10455 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10456 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010457 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010458 {
10459 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
10460 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010461 "%s: client " MAC_ADDRESS_STR
10462 " is in the middle of WPS/EAPOL exchange.", __func__,
10463 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010464 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010465 }
10466 }
10467 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
10468 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
10469 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010470 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10471 ptSapContext pSapCtx = NULL;
10472 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10473 if(pSapCtx == NULL){
10474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10475 FL("psapCtx is NULL"));
10476 return VOS_FALSE;
10477 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010478 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
10479 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010480 if ((pSapCtx->aStaInfo[staId].isUsed) &&
10481 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010482 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010483 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010484
10485 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010486 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
10487 "middle of WPS/EAPOL exchange.", __func__,
10488 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010489 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010490 }
10491 }
10492 }
10493 }
10494 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10495 pAdapterNode = pNext;
10496 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053010497 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010498}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010499
10500/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010501 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070010502 * this scan respond to scan trigger and update cfg80211 scan database
10503 * later, scan dump command can be used to recieve scan results
10504 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010505int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010506#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10507 struct net_device *dev,
10508#endif
10509 struct cfg80211_scan_request *request)
10510{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010511 hdd_adapter_t *pAdapter = NULL;
10512 hdd_context_t *pHddCtx = NULL;
10513 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010514 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010515 tCsrScanRequest scanRequest;
10516 tANI_U8 *channelList = NULL, i;
10517 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010518 int status;
10519 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010520 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010521 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053010522 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010523 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053010524 v_S7_t rssi=0;
10525 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010526
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010527#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
10528 struct net_device *dev = NULL;
10529 if (NULL == request)
10530 {
10531 hddLog(VOS_TRACE_LEVEL_ERROR,
10532 "%s: scan req param null", __func__);
10533 return -EINVAL;
10534 }
10535 dev = request->wdev->netdev;
10536#endif
10537
10538 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
10539 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
10540 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10541
Jeff Johnson295189b2012-06-20 16:38:30 -070010542 ENTER();
10543
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010544 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10545 __func__, hdd_device_modetoString(pAdapter->device_mode),
10546 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010547
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010548 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010549 if (0 != status)
10550 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010551 return status;
10552 }
10553
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010554 if (NULL == pwextBuf)
10555 {
10556 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
10557 __func__);
10558 return -EIO;
10559 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010560 cfg_param = pHddCtx->cfg_ini;
10561 pScanInfo = &pHddCtx->scan_info;
10562
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053010563 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10564 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
10565 {
10566 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
10567 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
10568 }
10569
Jeff Johnson295189b2012-06-20 16:38:30 -070010570#ifdef WLAN_BTAMP_FEATURE
10571 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010572 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070010573 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010574 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010575 "%s: No scanning when AMP is on", __func__);
10576 return -EOPNOTSUPP;
10577 }
10578#endif
10579 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010580 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010581 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010582 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010583 "%s: Not scanning on device_mode = %s (%d)",
10584 __func__, hdd_device_modetoString(pAdapter->device_mode),
10585 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010586 return -EOPNOTSUPP;
10587 }
10588
10589 if (TRUE == pScanInfo->mScanPending)
10590 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010591 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
10592 {
10593 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
10594 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010595 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010596 }
10597
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010598 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070010599 //Channel and action frame is pending
10600 //Otherwise Cancel Remain On Channel and allow Scan
10601 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010602 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070010603 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010604 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010605 return -EBUSY;
10606 }
10607
Jeff Johnson295189b2012-06-20 16:38:30 -070010608 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
10609 {
10610 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080010611 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010612 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010613 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010614 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
10615 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010616 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010617 "%s: MAX TM Level Scan not allowed", __func__);
10618 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010619 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010620 }
10621 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
10622
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010623 /* Check if scan is allowed at this point of time.
10624 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010625 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010626 {
10627 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
10628 return -EBUSY;
10629 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010630
Jeff Johnson295189b2012-06-20 16:38:30 -070010631 vos_mem_zero( &scanRequest, sizeof(scanRequest));
10632
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010633 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
10634 (int)request->n_ssids);
10635
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010636
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010637 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
10638 * Becasue of this, driver is assuming that this is not wildcard scan and so
10639 * is not aging out the scan results.
10640 */
10641 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010642 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010643 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010644 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010645
10646 if ((request->ssids) && (0 < request->n_ssids))
10647 {
10648 tCsrSSIDInfo *SsidInfo;
10649 int j;
10650 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
10651 /* Allocate num_ssid tCsrSSIDInfo structure */
10652 SsidInfo = scanRequest.SSIDs.SSIDList =
10653 ( tCsrSSIDInfo *)vos_mem_malloc(
10654 request->n_ssids*sizeof(tCsrSSIDInfo));
10655
10656 if(NULL == scanRequest.SSIDs.SSIDList)
10657 {
10658 hddLog(VOS_TRACE_LEVEL_ERROR,
10659 "%s: memory alloc failed SSIDInfo buffer", __func__);
10660 return -ENOMEM;
10661 }
10662
10663 /* copy all the ssid's and their length */
10664 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
10665 {
10666 /* get the ssid length */
10667 SsidInfo->SSID.length = request->ssids[j].ssid_len;
10668 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
10669 SsidInfo->SSID.length);
10670 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
10671 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
10672 j, SsidInfo->SSID.ssId);
10673 }
10674 /* set the scan type to active */
10675 scanRequest.scanType = eSIR_ACTIVE_SCAN;
10676 }
10677 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070010678 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010679 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10680 TRACE_CODE_HDD_CFG80211_SCAN,
10681 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070010682 /* set the scan type to active */
10683 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010684 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010685 else
10686 {
10687 /*Set the scan type to default type, in this case it is ACTIVE*/
10688 scanRequest.scanType = pScanInfo->scan_mode;
10689 }
10690 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
10691 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070010692
10693 /* set BSSType to default type */
10694 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
10695
10696 /*TODO: scan the requested channels only*/
10697
10698 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010699 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070010700 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010701 hddLog(VOS_TRACE_LEVEL_WARN,
10702 "No of Scan Channels exceeded limit: %d", request->n_channels);
10703 request->n_channels = MAX_CHANNEL;
10704 }
10705
10706 hddLog(VOS_TRACE_LEVEL_INFO,
10707 "No of Scan Channels: %d", request->n_channels);
10708
10709
10710 if( request->n_channels )
10711 {
10712 char chList [(request->n_channels*5)+1];
10713 int len;
10714 channelList = vos_mem_malloc( request->n_channels );
10715 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053010716 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010717 hddLog(VOS_TRACE_LEVEL_ERROR,
10718 "%s: memory alloc failed channelList", __func__);
10719 status = -ENOMEM;
10720 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053010721 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010722
10723 for( i = 0, len = 0; i < request->n_channels ; i++ )
10724 {
10725 channelList[i] = request->channels[i]->hw_value;
10726 len += snprintf(chList+len, 5, "%d ", channelList[i]);
10727 }
10728
Nirav Shah20ac06f2013-12-12 18:14:06 +053010729 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010730 "Channel-List: %s ", chList);
10731 }
c_hpothu53512302014-04-15 18:49:53 +053010732
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010733 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
10734 scanRequest.ChannelInfo.ChannelList = channelList;
10735
10736 /* set requestType to full scan */
10737 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10738
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010739 /* if there is back to back scan happening in driver with in
10740 * nDeferScanTimeInterval interval driver should defer new scan request
10741 * and should provide last cached scan results instead of new channel list.
10742 * This rule is not applicable if scan is p2p scan.
10743 * This condition will work only in case when last request no of channels
10744 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053010745 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053010746 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010747 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010748
Sushant Kaushik86592172015-04-27 16:35:03 +053010749 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
10750 /* if wps ie is NULL , then only defer scan */
10751 if ( pWpsIe == NULL &&
10752 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053010753 {
10754 if ( pScanInfo->last_scan_timestamp !=0 &&
10755 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
10756 {
10757 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
10758 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
10759 vos_mem_compare(pScanInfo->last_scan_channelList,
10760 channelList, pScanInfo->last_scan_numChannels))
10761 {
10762 hddLog(VOS_TRACE_LEVEL_WARN,
10763 " New and old station scan time differ is less then %u",
10764 pHddCtx->cfg_ini->nDeferScanTimeInterval);
10765
10766 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010767 pAdapter);
10768
Agarwal Ashish57e84372014-12-05 18:26:53 +053010769 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010770 "Return old cached scan as all channels and no of channels are same");
10771
Agarwal Ashish57e84372014-12-05 18:26:53 +053010772 if (0 > ret)
10773 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010774
Agarwal Ashish57e84372014-12-05 18:26:53 +053010775 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010776
10777 status = eHAL_STATUS_SUCCESS;
10778 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053010779 }
10780 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010781 }
10782
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010783 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10784 * search (Flush on both full scan and social scan but not on single
10785 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10786 */
10787
10788 /* Supplicant does single channel scan after 8-way handshake
10789 * and in that case driver shoudnt flush scan results. If
10790 * driver flushes the scan results here and unfortunately if
10791 * the AP doesnt respond to our probe req then association
10792 * fails which is not desired
10793 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010794 if ((request->n_ssids == 1)
10795 && (request->ssids != NULL)
10796 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
10797 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010798
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010799 if( is_p2p_scan ||
10800 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010801 {
10802 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
10803 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
10804 pAdapter->sessionId );
10805 }
10806
10807 if( request->ie_len )
10808 {
10809 /* save this for future association (join requires this) */
10810 /*TODO: Array needs to be converted to dynamic allocation,
10811 * as multiple ie.s can be sent in cfg80211_scan_request structure
10812 * CR 597966
10813 */
10814 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
10815 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
10816 pScanInfo->scanAddIE.length = request->ie_len;
10817
10818 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10819 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10820 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010821 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053010822 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070010823 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010824 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
10825 memcpy( pwextBuf->roamProfile.addIEScan,
10826 request->ie, request->ie_len);
10827 }
10828 else
10829 {
10830 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
10831 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070010832 }
10833
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010834 }
10835 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
10836 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
10837
10838 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
10839 request->ie_len);
10840 if (pP2pIe != NULL)
10841 {
10842#ifdef WLAN_FEATURE_P2P_DEBUG
10843 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
10844 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
10845 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053010846 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010847 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
10848 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10849 "Go nego completed to Connection is started");
10850 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10851 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053010852 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010853 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
10854 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010855 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010856 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
10857 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10858 "Disconnected state to Connection is started");
10859 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10860 "for 4way Handshake");
10861 }
10862#endif
10863
10864 /* no_cck will be set during p2p find to disable 11b rates */
10865 if(TRUE == request->no_cck)
10866 {
10867 hddLog(VOS_TRACE_LEVEL_INFO,
10868 "%s: This is a P2P Search", __func__);
10869 scanRequest.p2pSearch = 1;
10870
10871 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053010872 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010873 /* set requestType to P2P Discovery */
10874 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
10875 }
10876
10877 /*
10878 Skip Dfs Channel in case of P2P Search
10879 if it is set in ini file
10880 */
10881 if(cfg_param->skipDfsChnlInP2pSearch)
10882 {
10883 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010884 }
10885 else
10886 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010887 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010888 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010889
Agarwal Ashish4f616132013-12-30 23:32:50 +053010890 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010891 }
10892 }
10893
10894 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
10895
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010896#ifdef FEATURE_WLAN_TDLS
10897 /* if tdls disagree scan right now, return immediately.
10898 tdls will schedule the scan when scan is allowed. (return SUCCESS)
10899 or will reject the scan if any TDLS is in progress. (return -EBUSY)
10900 */
10901 status = wlan_hdd_tdls_scan_callback (pAdapter,
10902 wiphy,
10903#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10904 dev,
10905#endif
10906 request);
10907 if(status <= 0)
10908 {
10909 if(!status)
10910 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
10911 "scan rejected %d", __func__, status);
10912 else
10913 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
10914 __func__, status);
10915
10916 return status;
10917 }
10918#endif
10919
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010920 /* acquire the wakelock to avoid the apps suspend during the scan. To
10921 * address the following issues.
10922 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
10923 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
10924 * for long time, this result in apps running at full power for long time.
10925 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
10926 * be stuck in full power because of resume BMPS
10927 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010928 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010929
Nirav Shah20ac06f2013-12-12 18:14:06 +053010930 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10931 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010932 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
10933 scanRequest.requestType, scanRequest.scanType,
10934 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053010935 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
10936
Siddharth Bhal76972212014-10-15 16:22:51 +053010937 if (pHddCtx->spoofMacAddr.isEnabled)
10938 {
10939 hddLog(VOS_TRACE_LEVEL_INFO,
10940 "%s: MAC Spoofing enabled for current scan", __func__);
10941 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
10942 * to fill TxBds for probe request during current scan
10943 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053010944 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053010945 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053010946
10947 if(status != VOS_STATUS_SUCCESS)
10948 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010949 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053010950 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053010951#ifdef FEATURE_WLAN_TDLS
10952 wlan_hdd_tdls_scan_done_callback(pAdapter);
10953#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053010954 goto free_mem;
10955 }
Siddharth Bhal76972212014-10-15 16:22:51 +053010956 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053010957 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070010958 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010959 pAdapter->sessionId, &scanRequest, &scanId,
10960 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070010961
Jeff Johnson295189b2012-06-20 16:38:30 -070010962 if (eHAL_STATUS_SUCCESS != status)
10963 {
10964 hddLog(VOS_TRACE_LEVEL_ERROR,
10965 "%s: sme_ScanRequest returned error %d", __func__, status);
10966 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010967 if(eHAL_STATUS_RESOURCES == status)
10968 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010969 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
10970 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010971 status = -EBUSY;
10972 } else {
10973 status = -EIO;
10974 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010975 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010976
10977#ifdef FEATURE_WLAN_TDLS
10978 wlan_hdd_tdls_scan_done_callback(pAdapter);
10979#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010980 goto free_mem;
10981 }
10982
10983 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010984 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070010985 pAdapter->request = request;
10986 pScanInfo->scanId = scanId;
10987
10988 complete(&pScanInfo->scan_req_completion_event);
10989
10990free_mem:
10991 if( scanRequest.SSIDs.SSIDList )
10992 {
10993 vos_mem_free(scanRequest.SSIDs.SSIDList);
10994 }
10995
10996 if( channelList )
10997 vos_mem_free( channelList );
10998
10999 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011000 return status;
11001}
11002
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011003int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
11004#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11005 struct net_device *dev,
11006#endif
11007 struct cfg80211_scan_request *request)
11008{
11009 int ret;
11010
11011 vos_ssr_protect(__func__);
11012 ret = __wlan_hdd_cfg80211_scan(wiphy,
11013#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11014 dev,
11015#endif
11016 request);
11017 vos_ssr_unprotect(__func__);
11018
11019 return ret;
11020}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011021
11022void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
11023{
11024 v_U8_t iniDot11Mode =
11025 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
11026 eHddDot11Mode hddDot11Mode = iniDot11Mode;
11027
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011028 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
11029 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011030 switch ( iniDot11Mode )
11031 {
11032 case eHDD_DOT11_MODE_AUTO:
11033 case eHDD_DOT11_MODE_11ac:
11034 case eHDD_DOT11_MODE_11ac_ONLY:
11035#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053011036 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
11037 sme_IsFeatureSupportedByFW(DOT11AC) )
11038 hddDot11Mode = eHDD_DOT11_MODE_11ac;
11039 else
11040 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011041#else
11042 hddDot11Mode = eHDD_DOT11_MODE_11n;
11043#endif
11044 break;
11045 case eHDD_DOT11_MODE_11n:
11046 case eHDD_DOT11_MODE_11n_ONLY:
11047 hddDot11Mode = eHDD_DOT11_MODE_11n;
11048 break;
11049 default:
11050 hddDot11Mode = iniDot11Mode;
11051 break;
11052 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011053#ifdef WLAN_FEATURE_AP_HT40_24G
11054 if (operationChannel > SIR_11B_CHANNEL_END)
11055#endif
11056 {
11057 /* This call decides required channel bonding mode */
11058 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011059 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
11060 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011061 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011062}
11063
Jeff Johnson295189b2012-06-20 16:38:30 -070011064/*
11065 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011066 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011067 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011068int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011069 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070011070{
11071 int status = 0;
11072 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080011073 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011074 v_U32_t roamId;
11075 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070011076 eCsrAuthType RSNAuthType;
11077
11078 ENTER();
11079
11080 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080011081 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11082
11083 status = wlan_hdd_validate_context(pHddCtx);
11084 if (status)
11085 {
Yue Mae36e3552014-03-05 17:06:20 -080011086 return status;
11087 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011088
Jeff Johnson295189b2012-06-20 16:38:30 -070011089 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
11090 {
11091 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
11092 return -EINVAL;
11093 }
11094
11095 pRoamProfile = &pWextState->roamProfile;
11096
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011097 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070011098 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011099 hdd_station_ctx_t *pHddStaCtx;
11100 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011101
Siddharth Bhalda0d1622015-04-24 15:47:49 +053011102 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
11103
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011104 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070011105 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
11106 {
11107 /*QoS not enabled in cfg file*/
11108 pRoamProfile->uapsd_mask = 0;
11109 }
11110 else
11111 {
11112 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011113 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070011114 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
11115 }
11116
11117 pRoamProfile->SSIDs.numOfSSIDs = 1;
11118 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
11119 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011120 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070011121 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
11122 ssid, ssid_len);
11123
11124 if (bssid)
11125 {
11126 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
11127 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
11128 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011129 /* Save BSSID in seperate variable as well, as RoamProfile
11130 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070011131 case of join failure we should send valid BSSID to supplicant
11132 */
11133 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
11134 WNI_CFG_BSSID_LEN);
11135 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070011136 else
11137 {
11138 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
11139 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011140
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011141 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
11142 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011143 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
11144 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011145 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011146 /*set gen ie*/
11147 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
11148 /*set auth*/
11149 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
11150 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011151#ifdef FEATURE_WLAN_WAPI
11152 if (pAdapter->wapi_info.nWapiMode)
11153 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011154 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011155 switch (pAdapter->wapi_info.wapiAuthMode)
11156 {
11157 case WAPI_AUTH_MODE_PSK:
11158 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011159 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011160 pAdapter->wapi_info.wapiAuthMode);
11161 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
11162 break;
11163 }
11164 case WAPI_AUTH_MODE_CERT:
11165 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011166 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011167 pAdapter->wapi_info.wapiAuthMode);
11168 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
11169 break;
11170 }
11171 } // End of switch
11172 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
11173 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
11174 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011175 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011176 pRoamProfile->AuthType.numEntries = 1;
11177 pRoamProfile->EncryptionType.numEntries = 1;
11178 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11179 pRoamProfile->mcEncryptionType.numEntries = 1;
11180 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11181 }
11182 }
11183#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011184#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011185 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011186 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11187 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
11188 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011189 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
11190 sizeof (tSirGtkOffloadParams));
11191 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011192 }
11193#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011194 pRoamProfile->csrPersona = pAdapter->device_mode;
11195
Jeff Johnson32d95a32012-09-10 13:15:23 -070011196 if( operatingChannel )
11197 {
11198 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
11199 pRoamProfile->ChannelInfo.numOfChannels = 1;
11200 }
Chet Lanctot186b5732013-03-18 10:26:30 -070011201 else
11202 {
11203 pRoamProfile->ChannelInfo.ChannelList = NULL;
11204 pRoamProfile->ChannelInfo.numOfChannels = 0;
11205 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011206 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
11207 {
11208 hdd_select_cbmode(pAdapter,operatingChannel);
11209 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011210
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011211 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
11212 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011213 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011214 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011215 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
11216 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011217 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11218 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053011219 {
11220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11221 "%s: Set HDD connState to eConnectionState_Connecting",
11222 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011223 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
11224 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053011225 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011226 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011227 pAdapter->sessionId, pRoamProfile, &roamId);
11228
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011229 if ((eHAL_STATUS_SUCCESS != status) &&
11230 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11231 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011232
11233 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011234 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
11235 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
11236 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011237 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011238 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011239 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011240
11241 pRoamProfile->ChannelInfo.ChannelList = NULL;
11242 pRoamProfile->ChannelInfo.numOfChannels = 0;
11243
Jeff Johnson295189b2012-06-20 16:38:30 -070011244 }
11245 else
11246 {
11247 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
11248 return -EINVAL;
11249 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011250 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011251 return status;
11252}
11253
11254/*
11255 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
11256 * This function is used to set the authentication type (OPEN/SHARED).
11257 *
11258 */
11259static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
11260 enum nl80211_auth_type auth_type)
11261{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011262 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011263 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11264
11265 ENTER();
11266
11267 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011268 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070011269 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011270 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011271 hddLog(VOS_TRACE_LEVEL_INFO,
11272 "%s: set authentication type to AUTOSWITCH", __func__);
11273 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
11274 break;
11275
11276 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011277#ifdef WLAN_FEATURE_VOWIFI_11R
11278 case NL80211_AUTHTYPE_FT:
11279#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011280 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011281 "%s: set authentication type to OPEN", __func__);
11282 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11283 break;
11284
11285 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011286 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011287 "%s: set authentication type to SHARED", __func__);
11288 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
11289 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011290#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011291 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011292 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011293 "%s: set authentication type to CCKM WPA", __func__);
11294 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
11295 break;
11296#endif
11297
11298
11299 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011300 hddLog(VOS_TRACE_LEVEL_ERROR,
11301 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011302 auth_type);
11303 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
11304 return -EINVAL;
11305 }
11306
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011307 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011308 pHddStaCtx->conn_info.authType;
11309 return 0;
11310}
11311
11312/*
11313 * FUNCTION: wlan_hdd_set_akm_suite
11314 * This function is used to set the key mgmt type(PSK/8021x).
11315 *
11316 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011317static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011318 u32 key_mgmt
11319 )
11320{
11321 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11322 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053011323 /* Should be in ieee802_11_defs.h */
11324#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
11325#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070011326 /*set key mgmt type*/
11327 switch(key_mgmt)
11328 {
11329 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053011330 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011331#ifdef WLAN_FEATURE_VOWIFI_11R
11332 case WLAN_AKM_SUITE_FT_PSK:
11333#endif
11334 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070011335 __func__);
11336 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
11337 break;
11338
11339 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053011340 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011341#ifdef WLAN_FEATURE_VOWIFI_11R
11342 case WLAN_AKM_SUITE_FT_8021X:
11343#endif
11344 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070011345 __func__);
11346 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11347 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011348#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011349#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
11350#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
11351 case WLAN_AKM_SUITE_CCKM:
11352 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
11353 __func__);
11354 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
11355 break;
11356#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070011357#ifndef WLAN_AKM_SUITE_OSEN
11358#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
11359 case WLAN_AKM_SUITE_OSEN:
11360 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
11361 __func__);
11362 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11363 break;
11364#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011365
11366 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011367 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011368 __func__, key_mgmt);
11369 return -EINVAL;
11370
11371 }
11372 return 0;
11373}
11374
11375/*
11376 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011377 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070011378 * (NONE/WEP40/WEP104/TKIP/CCMP).
11379 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011380static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
11381 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070011382 bool ucast
11383 )
11384{
11385 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011386 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011387 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11388
11389 ENTER();
11390
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011391 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011392 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011393 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070011394 __func__, cipher);
11395 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11396 }
11397 else
11398 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011399
Jeff Johnson295189b2012-06-20 16:38:30 -070011400 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011401 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011402 {
11403 case IW_AUTH_CIPHER_NONE:
11404 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11405 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011406
Jeff Johnson295189b2012-06-20 16:38:30 -070011407 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011408 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070011409 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011410
Jeff Johnson295189b2012-06-20 16:38:30 -070011411 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011412 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070011413 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011414
Jeff Johnson295189b2012-06-20 16:38:30 -070011415 case WLAN_CIPHER_SUITE_TKIP:
11416 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
11417 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011418
Jeff Johnson295189b2012-06-20 16:38:30 -070011419 case WLAN_CIPHER_SUITE_CCMP:
11420 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11421 break;
11422#ifdef FEATURE_WLAN_WAPI
11423 case WLAN_CIPHER_SUITE_SMS4:
11424 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
11425 break;
11426#endif
11427
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011428#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011429 case WLAN_CIPHER_SUITE_KRK:
11430 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
11431 break;
11432#endif
11433 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011434 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011435 __func__, cipher);
11436 return -EOPNOTSUPP;
11437 }
11438 }
11439
11440 if (ucast)
11441 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011442 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011443 __func__, encryptionType);
11444 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11445 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011446 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011447 encryptionType;
11448 }
11449 else
11450 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011451 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011452 __func__, encryptionType);
11453 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
11454 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
11455 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
11456 }
11457
11458 return 0;
11459}
11460
11461
11462/*
11463 * FUNCTION: wlan_hdd_cfg80211_set_ie
11464 * This function is used to parse WPA/RSN IE's.
11465 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011466int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
11467 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070011468 size_t ie_len
11469 )
11470{
11471 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11472 u8 *genie = ie;
11473 v_U16_t remLen = ie_len;
11474#ifdef FEATURE_WLAN_WAPI
11475 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
11476 u16 *tmp;
11477 v_U16_t akmsuiteCount;
11478 int *akmlist;
11479#endif
11480 ENTER();
11481
11482 /* clear previous assocAddIE */
11483 pWextState->assocAddIE.length = 0;
11484 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011485 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011486
11487 while (remLen >= 2)
11488 {
11489 v_U16_t eLen = 0;
11490 v_U8_t elementId;
11491 elementId = *genie++;
11492 eLen = *genie++;
11493 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011494
Arif Hussain6d2a3322013-11-17 19:50:10 -080011495 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070011496 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011497
11498 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070011499 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011500 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011501 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 -070011502 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011503 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011504 "%s: Invalid WPA IE", __func__);
11505 return -EINVAL;
11506 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011507 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070011508 {
11509 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011510 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011511 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011512
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011513 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011514 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011515 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
11516 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011517 VOS_ASSERT(0);
11518 return -ENOMEM;
11519 }
11520 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11521 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11522 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011523
Jeff Johnson295189b2012-06-20 16:38:30 -070011524 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
11525 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11526 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11527 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011528 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
11529 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011530 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
11531 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11532 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
11533 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
11534 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
11535 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011536 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053011537 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011538 {
11539 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011540 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011541 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011542
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011543 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011544 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011545 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11546 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011547 VOS_ASSERT(0);
11548 return -ENOMEM;
11549 }
11550 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11551 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11552 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011553
Jeff Johnson295189b2012-06-20 16:38:30 -070011554 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11555 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11556 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011557#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011558 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
11559 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011560 /*Consider WFD IE, only for P2P Client */
11561 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11562 {
11563 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011564 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011565 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011566
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011567 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011568 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011569 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11570 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011571 VOS_ASSERT(0);
11572 return -ENOMEM;
11573 }
11574 // WFD IE is saved to Additional IE ; it should be accumulated to handle
11575 // WPS IE + P2P IE + WFD IE
11576 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11577 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011578
Jeff Johnson295189b2012-06-20 16:38:30 -070011579 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11580 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11581 }
11582#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011583 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011584 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011585 HS20_OUI_TYPE_SIZE)) )
11586 {
11587 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011588 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011589 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011590
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011591 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011592 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011593 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11594 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011595 VOS_ASSERT(0);
11596 return -ENOMEM;
11597 }
11598 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11599 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011600
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011601 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11602 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11603 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011604 /* Appending OSEN Information Element in Assiciation Request */
11605 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
11606 OSEN_OUI_TYPE_SIZE)) )
11607 {
11608 v_U16_t curAddIELen = pWextState->assocAddIE.length;
11609 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
11610 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011611
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011612 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011613 {
11614 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11615 "Need bigger buffer space");
11616 VOS_ASSERT(0);
11617 return -ENOMEM;
11618 }
11619 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11620 pWextState->assocAddIE.length += eLen + 2;
11621
11622 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
11623 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11624 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11625 }
11626
Abhishek Singh4322e622015-06-10 15:42:54 +053011627 /* Update only for WPA IE */
11628 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
11629 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070011630
11631 /* populating as ADDIE in beacon frames */
11632 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11633 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
11634 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
11635 {
11636 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11637 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
11638 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11639 {
11640 hddLog(LOGE,
11641 "Coldn't pass "
11642 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
11643 }
11644 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
11645 else
11646 hddLog(LOGE,
11647 "Could not pass on "
11648 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
11649
11650 /* IBSS mode doesn't contain params->proberesp_ies still
11651 beaconIE's need to be populated in probe response frames */
11652 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
11653 {
11654 u16 rem_probe_resp_ie_len = eLen + 2;
11655 u8 probe_rsp_ie_len[3] = {0};
11656 u8 counter = 0;
11657
11658 /* Check Probe Resp Length if it is greater then 255 then
11659 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
11660 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
11661 not able Store More then 255 bytes into One Variable */
11662
11663 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
11664 {
11665 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
11666 {
11667 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
11668 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
11669 }
11670 else
11671 {
11672 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
11673 rem_probe_resp_ie_len = 0;
11674 }
11675 }
11676
11677 rem_probe_resp_ie_len = 0;
11678
11679 if (probe_rsp_ie_len[0] > 0)
11680 {
11681 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11682 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
11683 (tANI_U8*)(genie - 2),
11684 probe_rsp_ie_len[0], NULL,
11685 eANI_BOOLEAN_FALSE)
11686 == eHAL_STATUS_FAILURE)
11687 {
11688 hddLog(LOGE,
11689 "Could not pass"
11690 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
11691 }
11692 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
11693 }
11694
11695 if (probe_rsp_ie_len[1] > 0)
11696 {
11697 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11698 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
11699 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11700 probe_rsp_ie_len[1], NULL,
11701 eANI_BOOLEAN_FALSE)
11702 == eHAL_STATUS_FAILURE)
11703 {
11704 hddLog(LOGE,
11705 "Could not pass"
11706 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
11707 }
11708 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
11709 }
11710
11711 if (probe_rsp_ie_len[2] > 0)
11712 {
11713 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11714 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
11715 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11716 probe_rsp_ie_len[2], NULL,
11717 eANI_BOOLEAN_FALSE)
11718 == eHAL_STATUS_FAILURE)
11719 {
11720 hddLog(LOGE,
11721 "Could not pass"
11722 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
11723 }
11724 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
11725 }
11726
11727 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11728 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
11729 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11730 {
11731 hddLog(LOGE,
11732 "Could not pass"
11733 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
11734 }
11735 }
11736 else
11737 {
11738 // Reset WNI_CFG_PROBE_RSP Flags
11739 wlan_hdd_reset_prob_rspies(pAdapter);
11740
11741 hddLog(VOS_TRACE_LEVEL_INFO,
11742 "%s: No Probe Response IE received in set beacon",
11743 __func__);
11744 }
11745 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011746 break;
11747 case DOT11F_EID_RSN:
11748 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
11749 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11750 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
11751 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
11752 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
11753 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053011754
11755 /* Appending Extended Capabilities with Interworking bit set
11756 * in Assoc Req.
11757 *
11758 * In assoc req this EXT Cap will only be taken into account if
11759 * interworkingService bit is set to 1. Currently
11760 * driver is only interested in interworkingService capability
11761 * from supplicant. If in future any other EXT Cap info is
11762 * required from supplicat, it needs to be handled while
11763 * sending Assoc Req in LIM.
11764 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011765 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011766 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011767 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011768 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011769 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011770
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011771 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011772 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011773 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11774 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011775 VOS_ASSERT(0);
11776 return -ENOMEM;
11777 }
11778 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11779 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011780
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011781 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11782 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11783 break;
11784 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011785#ifdef FEATURE_WLAN_WAPI
11786 case WLAN_EID_WAPI:
11787 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011788 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011789 pAdapter->wapi_info.nWapiMode);
11790 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011791 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070011792 akmsuiteCount = WPA_GET_LE16(tmp);
11793 tmp = tmp + 1;
11794 akmlist = (int *)(tmp);
11795 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
11796 {
11797 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
11798 }
11799 else
11800 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011801 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070011802 VOS_ASSERT(0);
11803 return -EINVAL;
11804 }
11805
11806 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
11807 {
11808 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011809 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011810 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011811 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011812 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011813 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011814 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011815 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011816 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
11817 }
11818 break;
11819#endif
11820 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011821 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011822 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011823 /* when Unknown IE is received we should break and continue
11824 * to the next IE in the buffer instead we were returning
11825 * so changing this to break */
11826 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011827 }
11828 genie += eLen;
11829 remLen -= eLen;
11830 }
11831 EXIT();
11832 return 0;
11833}
11834
11835/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053011836 * FUNCTION: hdd_isWPAIEPresent
11837 * Parse the received IE to find the WPA IE
11838 *
11839 */
11840static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
11841{
11842 v_U8_t eLen = 0;
11843 v_U16_t remLen = ie_len;
11844 v_U8_t elementId = 0;
11845
11846 while (remLen >= 2)
11847 {
11848 elementId = *ie++;
11849 eLen = *ie++;
11850 remLen -= 2;
11851 if (eLen > remLen)
11852 {
11853 hddLog(VOS_TRACE_LEVEL_ERROR,
11854 "%s: IE length is wrong %d", __func__, eLen);
11855 return FALSE;
11856 }
11857 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
11858 {
11859 /* OUI - 0x00 0X50 0XF2
11860 WPA Information Element - 0x01
11861 WPA version - 0x01*/
11862 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
11863 return TRUE;
11864 }
11865 ie += eLen;
11866 remLen -= eLen;
11867 }
11868 return FALSE;
11869}
11870
11871/*
Jeff Johnson295189b2012-06-20 16:38:30 -070011872 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011873 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011874 * parameters during connect operation.
11875 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011876int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011877 struct cfg80211_connect_params *req
11878 )
11879{
11880 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011881 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011882 ENTER();
11883
11884 /*set wpa version*/
11885 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
11886
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011887 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011888 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053011889 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011890 {
11891 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11892 }
11893 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
11894 {
11895 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11896 }
11897 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011898
11899 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011900 pWextState->wpaVersion);
11901
11902 /*set authentication type*/
11903 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
11904
11905 if (0 > status)
11906 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011907 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011908 "%s: failed to set authentication type ", __func__);
11909 return status;
11910 }
11911
11912 /*set key mgmt type*/
11913 if (req->crypto.n_akm_suites)
11914 {
11915 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
11916 if (0 > status)
11917 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011918 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070011919 __func__);
11920 return status;
11921 }
11922 }
11923
11924 /*set pairwise cipher type*/
11925 if (req->crypto.n_ciphers_pairwise)
11926 {
11927 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
11928 req->crypto.ciphers_pairwise[0], true);
11929 if (0 > status)
11930 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011931 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011932 "%s: failed to set unicast cipher type", __func__);
11933 return status;
11934 }
11935 }
11936 else
11937 {
11938 /*Reset previous cipher suite to none*/
11939 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
11940 if (0 > status)
11941 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011942 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011943 "%s: failed to set unicast cipher type", __func__);
11944 return status;
11945 }
11946 }
11947
11948 /*set group cipher type*/
11949 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
11950 false);
11951
11952 if (0 > status)
11953 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011954 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070011955 __func__);
11956 return status;
11957 }
11958
Chet Lanctot186b5732013-03-18 10:26:30 -070011959#ifdef WLAN_FEATURE_11W
11960 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
11961#endif
11962
Jeff Johnson295189b2012-06-20 16:38:30 -070011963 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
11964 if (req->ie_len)
11965 {
11966 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
11967 if ( 0 > status)
11968 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011969 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011970 __func__);
11971 return status;
11972 }
11973 }
11974
11975 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011976 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011977 {
11978 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
11979 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
11980 )
11981 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011982 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070011983 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
11984 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011985 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011986 __func__);
11987 return -EOPNOTSUPP;
11988 }
11989 else
11990 {
11991 u8 key_len = req->key_len;
11992 u8 key_idx = req->key_idx;
11993
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011994 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011995 && (CSR_MAX_NUM_KEY > key_idx)
11996 )
11997 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011998 hddLog(VOS_TRACE_LEVEL_INFO,
11999 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012000 __func__, key_idx, key_len);
12001 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012002 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012003 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012004 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012005 (u8)key_len;
12006 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
12007 }
12008 }
12009 }
12010 }
12011
12012 return status;
12013}
12014
12015/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012016 * FUNCTION: wlan_hdd_try_disconnect
12017 * This function is used to disconnect from previous
12018 * connection
12019 */
12020static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
12021{
12022 long ret = 0;
12023 hdd_station_ctx_t *pHddStaCtx;
12024 eMib_dot11DesiredBssType connectedBssType;
12025
12026 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12027
12028 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
12029
12030 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
12031 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
12032 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
12033 {
12034 /* Issue disconnect to CSR */
12035 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12036 if( eHAL_STATUS_SUCCESS ==
12037 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12038 pAdapter->sessionId,
12039 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12040 {
12041 ret = wait_for_completion_interruptible_timeout(
12042 &pAdapter->disconnect_comp_var,
12043 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12044 if (0 >= ret)
12045 {
12046 hddLog(LOGE, FL("Failed to receive disconnect event"));
12047 return -EALREADY;
12048 }
12049 }
12050 }
12051 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
12052 {
12053 ret = wait_for_completion_interruptible_timeout(
12054 &pAdapter->disconnect_comp_var,
12055 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12056 if (0 >= ret)
12057 {
12058 hddLog(LOGE, FL("Failed to receive disconnect event"));
12059 return -EALREADY;
12060 }
12061 }
12062
12063 return 0;
12064}
12065
12066/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053012067 * FUNCTION: __wlan_hdd_cfg80211_connect
12068 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070012069 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012070static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012071 struct net_device *ndev,
12072 struct cfg80211_connect_params *req
12073 )
12074{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012075 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012076 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012077 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053012078 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012079
12080 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012081
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012082 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12083 TRACE_CODE_HDD_CFG80211_CONNECT,
12084 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012085 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012086 "%s: device_mode = %s (%d)", __func__,
12087 hdd_device_modetoString(pAdapter->device_mode),
12088 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012089
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012090 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012091 if (!pHddCtx)
12092 {
12093 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12094 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053012095 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012096 }
12097
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012098 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012099 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012100 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012101 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012102 }
12103
Agarwal Ashish51325b52014-06-16 16:50:49 +053012104 if (vos_max_concurrent_connections_reached()) {
12105 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12106 return -ECONNREFUSED;
12107 }
12108
Jeff Johnson295189b2012-06-20 16:38:30 -070012109#ifdef WLAN_BTAMP_FEATURE
12110 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012111 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070012112 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012113 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012114 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012115 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070012116 }
12117#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012118
12119 //If Device Mode is Station Concurrent Sessions Exit BMps
12120 //P2P Mode will be taken care in Open/close adapter
12121 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012122 (vos_concurrent_open_sessions_running())) {
12123 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
12124 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012125 }
12126
12127 /*Try disconnecting if already in connected state*/
12128 status = wlan_hdd_try_disconnect(pAdapter);
12129 if ( 0 > status)
12130 {
12131 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12132 " connection"));
12133 return -EALREADY;
12134 }
12135
Jeff Johnson295189b2012-06-20 16:38:30 -070012136 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012137 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070012138
12139 if ( 0 > status)
12140 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012141 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070012142 __func__);
12143 return status;
12144 }
Mohit Khanna765234a2012-09-11 15:08:35 -070012145 if ( req->channel )
12146 {
12147 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
12148 req->ssid_len, req->bssid,
12149 req->channel->hw_value);
12150 }
12151 else
12152 {
12153 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012154 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070012155 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012156
Sushant Kaushikd7083982015-03-18 14:33:24 +053012157 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012158 {
12159 //ReEnable BMPS if disabled
12160 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
12161 (NULL != pHddCtx))
12162 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012163 if (pHddCtx->hdd_wlan_suspended)
12164 {
12165 hdd_set_pwrparams(pHddCtx);
12166 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012167 //ReEnable Bmps and Imps back
12168 hdd_enable_bmps_imps(pHddCtx);
12169 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053012170 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070012171 return status;
12172 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012173 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012174 EXIT();
12175 return status;
12176}
12177
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012178static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
12179 struct net_device *ndev,
12180 struct cfg80211_connect_params *req)
12181{
12182 int ret;
12183 vos_ssr_protect(__func__);
12184 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
12185 vos_ssr_unprotect(__func__);
12186
12187 return ret;
12188}
Jeff Johnson295189b2012-06-20 16:38:30 -070012189
12190/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012191 * FUNCTION: wlan_hdd_disconnect
12192 * This function is used to issue a disconnect request to SME
12193 */
12194int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
12195{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012196 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012197 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012198 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012199 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012200
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012201 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012202
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012203 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012204 if (0 != status)
12205 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012206 return status;
12207 }
12208
Sushant Kaushikb4834d22015-07-15 15:29:05 +053012209 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
12210 {
12211 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
12212 pAdapter->sessionId);
12213 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012214 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012215
Agarwal Ashish47d18112014-08-04 19:55:07 +053012216 /* Need to apply spin lock before decreasing active sessions
12217 * as there can be chance for double decrement if context switch
12218 * Calls hdd_DisConnectHandler.
12219 */
12220
12221 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012222 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
12223 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012224 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
12225 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053012226 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
12227 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012228
Abhishek Singhf4669da2014-05-26 15:07:49 +053012229 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053012230 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
12231
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012232 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012233
Mihir Shete182a0b22014-08-18 16:08:48 +053012234 /*
12235 * stop tx queues before deleting STA/BSS context from the firmware.
12236 * tx has to be disabled because the firmware can get busy dropping
12237 * the tx frames after BSS/STA has been deleted and will not send
12238 * back a response resulting in WDI timeout
12239 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053012240 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053012241 netif_tx_disable(pAdapter->dev);
12242 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012243
Mihir Shete182a0b22014-08-18 16:08:48 +053012244 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012245 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12246 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012247 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
12248 {
12249 hddLog(VOS_TRACE_LEVEL_INFO,
12250 FL("status = %d, already disconnected"),
12251 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012252
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012253 }
12254 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012255 {
12256 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012257 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012258 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012259 result = -EINVAL;
12260 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012261 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012262 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012263 &pAdapter->disconnect_comp_var,
12264 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012265 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012266 {
12267 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012268 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012269 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012270 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012271 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012272 {
12273 hddLog(VOS_TRACE_LEVEL_ERROR,
12274 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012275 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012276 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012277disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012278 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12279 FL("Set HDD connState to eConnectionState_NotConnected"));
12280 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
12281
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012282 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012283 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012284}
12285
12286
12287/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012288 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070012289 * This function is used to issue a disconnect request to SME
12290 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012291static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012292 struct net_device *dev,
12293 u16 reason
12294 )
12295{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012296 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012297 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012298 tCsrRoamProfile *pRoamProfile;
12299 hdd_station_ctx_t *pHddStaCtx;
12300 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012301#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012302 tANI_U8 staIdx;
12303#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012304
Jeff Johnson295189b2012-06-20 16:38:30 -070012305 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012306
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012307 if (!pAdapter) {
12308 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
12309 return -EINVAL;
12310 }
12311
12312 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12313 if (!pHddStaCtx) {
12314 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
12315 return -EINVAL;
12316 }
12317
12318 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12319 status = wlan_hdd_validate_context(pHddCtx);
12320 if (0 != status)
12321 {
12322 return status;
12323 }
12324
12325 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
12326
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012327 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12328 TRACE_CODE_HDD_CFG80211_DISCONNECT,
12329 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012330 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
12331 __func__, hdd_device_modetoString(pAdapter->device_mode),
12332 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012333
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012334 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
12335 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070012336
Jeff Johnson295189b2012-06-20 16:38:30 -070012337 if (NULL != pRoamProfile)
12338 {
12339 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012340 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
12341 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070012342 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012343 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070012344 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012345 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012346 switch(reason)
12347 {
12348 case WLAN_REASON_MIC_FAILURE:
12349 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
12350 break;
12351
12352 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
12353 case WLAN_REASON_DISASSOC_AP_BUSY:
12354 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
12355 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
12356 break;
12357
12358 case WLAN_REASON_PREV_AUTH_NOT_VALID:
12359 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053012360 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070012361 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
12362 break;
12363
Jeff Johnson295189b2012-06-20 16:38:30 -070012364 default:
12365 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
12366 break;
12367 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012368 pScanInfo = &pHddCtx->scan_info;
12369 if (pScanInfo->mScanPending)
12370 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012371 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012372 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012373 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012374 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012375 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012376
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012377#ifdef FEATURE_WLAN_TDLS
12378 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012379 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012380 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012381 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
12382 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012383 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012384 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012385 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012387 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012388 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012389 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012390 status = sme_DeleteTdlsPeerSta(
12391 WLAN_HDD_GET_HAL_CTX(pAdapter),
12392 pAdapter->sessionId,
12393 mac);
12394 if (status != eHAL_STATUS_SUCCESS) {
12395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
12396 return -EPERM;
12397 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012398 }
12399 }
12400#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012401 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012402 status = wlan_hdd_disconnect(pAdapter, reasonCode);
12403 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070012404 {
12405 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012406 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012407 __func__, (int)status );
12408 return -EINVAL;
12409 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012410 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012411 else
12412 {
12413 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
12414 "called while in %d state", __func__,
12415 pHddStaCtx->conn_info.connState);
12416 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012417 }
12418 else
12419 {
12420 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
12421 }
12422
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012423 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012424 return status;
12425}
12426
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012427static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
12428 struct net_device *dev,
12429 u16 reason
12430 )
12431{
12432 int ret;
12433 vos_ssr_protect(__func__);
12434 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
12435 vos_ssr_unprotect(__func__);
12436
12437 return ret;
12438}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012439
Jeff Johnson295189b2012-06-20 16:38:30 -070012440/*
12441 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012442 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012443 * settings in IBSS mode.
12444 */
12445static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012446 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012447 struct cfg80211_ibss_params *params
12448 )
12449{
12450 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012451 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012452 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12453 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012454
Jeff Johnson295189b2012-06-20 16:38:30 -070012455 ENTER();
12456
12457 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070012458 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070012459
12460 if (params->ie_len && ( NULL != params->ie) )
12461 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012462 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12463 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012464 {
12465 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12466 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12467 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012468 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012469 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012470 tDot11fIEWPA dot11WPAIE;
12471 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012472 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012473
Wilson Yang00256342013-10-10 23:13:38 -070012474 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012475 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12476 params->ie_len, DOT11F_EID_WPA);
12477 if ( NULL != ie )
12478 {
12479 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12480 // Unpack the WPA IE
12481 //Skip past the EID byte and length byte - and four byte WiFi OUI
12482 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
12483 &ie[2+4],
12484 ie[1] - 4,
12485 &dot11WPAIE);
12486 /*Extract the multicast cipher, the encType for unicast
12487 cipher for wpa-none is none*/
12488 encryptionType =
12489 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
12490 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012491 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012492
Jeff Johnson295189b2012-06-20 16:38:30 -070012493 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
12494
12495 if (0 > status)
12496 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012497 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012498 __func__);
12499 return status;
12500 }
12501 }
12502
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012503 pWextState->roamProfile.AuthType.authType[0] =
12504 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012505 eCSR_AUTH_TYPE_OPEN_SYSTEM;
12506
12507 if (params->privacy)
12508 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012509 /* Security enabled IBSS, At this time there is no information available
12510 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070012511 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012512 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070012513 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012514 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070012515 *enable privacy bit in beacons */
12516
12517 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12518 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012519 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
12520 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070012521 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12522 pWextState->roamProfile.EncryptionType.numEntries = 1;
12523 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070012524 return status;
12525}
12526
12527/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012528 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012529 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012530 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012531static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012532 struct net_device *dev,
12533 struct cfg80211_ibss_params *params
12534 )
12535{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012536 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012537 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12538 tCsrRoamProfile *pRoamProfile;
12539 int status;
krunal sonie9002db2013-11-25 14:24:17 -080012540 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012541 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12542 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012543
12544 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012545
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012546 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12547 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
12548 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012549 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012550 "%s: device_mode = %s (%d)", __func__,
12551 hdd_device_modetoString(pAdapter->device_mode),
12552 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012553
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012554 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012555 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012556 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012557 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012558 }
12559
12560 if (NULL == pWextState)
12561 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012562 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012563 __func__);
12564 return -EIO;
12565 }
12566
Agarwal Ashish51325b52014-06-16 16:50:49 +053012567 if (vos_max_concurrent_connections_reached()) {
12568 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12569 return -ECONNREFUSED;
12570 }
12571
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012572 /*Try disconnecting if already in connected state*/
12573 status = wlan_hdd_try_disconnect(pAdapter);
12574 if ( 0 > status)
12575 {
12576 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12577 " IBSS connection"));
12578 return -EALREADY;
12579 }
12580
Jeff Johnson295189b2012-06-20 16:38:30 -070012581 pRoamProfile = &pWextState->roamProfile;
12582
12583 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
12584 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012585 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012586 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012587 return -EINVAL;
12588 }
12589
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012590 /* BSSID is provided by upper layers hence no need to AUTO generate */
12591 if (NULL != params->bssid) {
12592 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12593 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
12594 hddLog (VOS_TRACE_LEVEL_ERROR,
12595 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12596 return -EIO;
12597 }
12598 }
krunal sonie9002db2013-11-25 14:24:17 -080012599 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
12600 {
12601 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12602 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
12603 {
12604 hddLog (VOS_TRACE_LEVEL_ERROR,
12605 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12606 return -EIO;
12607 }
Sachin Ahuja46ff4912015-03-23 22:48:43 +053012608 params->bssid = vos_mem_malloc(VOS_MAC_ADDR_SIZE);
krunal sonie9002db2013-11-25 14:24:17 -080012609 if (!params->bssid)
12610 {
12611 hddLog (VOS_TRACE_LEVEL_ERROR,
12612 "%s:Failed memory allocation", __func__);
12613 return -EIO;
12614 }
12615 vos_mem_copy((v_U8_t *)params->bssid,
12616 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
12617 VOS_MAC_ADDR_SIZE);
12618 alloc_bssid = VOS_TRUE;
12619 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012620
Jeff Johnson295189b2012-06-20 16:38:30 -070012621 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070012622 if (NULL !=
12623#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12624 params->chandef.chan)
12625#else
12626 params->channel)
12627#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012628 {
12629 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012630 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12631 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
12632 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12633 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012634
12635 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012636 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070012637 ieee80211_frequency_to_channel(
12638#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12639 params->chandef.chan->center_freq);
12640#else
12641 params->channel->center_freq);
12642#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012643
12644 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12645 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070012646 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012647 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
12648 __func__);
12649 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012650 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012651
12652 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012653 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012654 if (channelNum == validChan[indx])
12655 {
12656 break;
12657 }
12658 }
12659 if (indx >= numChans)
12660 {
12661 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012662 __func__, channelNum);
12663 return -EINVAL;
12664 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012665 /* Set the Operational Channel */
12666 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
12667 channelNum);
12668 pRoamProfile->ChannelInfo.numOfChannels = 1;
12669 pHddStaCtx->conn_info.operationChannel = channelNum;
12670 pRoamProfile->ChannelInfo.ChannelList =
12671 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070012672 }
12673
12674 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012675 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070012676 if (status < 0)
12677 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012678 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070012679 __func__);
12680 return status;
12681 }
12682
12683 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012684 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012685 params->ssid_len, params->bssid,
12686 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012687
12688 if (0 > status)
12689 {
12690 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
12691 return status;
12692 }
12693
krunal sonie9002db2013-11-25 14:24:17 -080012694 if (NULL != params->bssid &&
12695 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
12696 alloc_bssid == VOS_TRUE)
12697 {
12698 vos_mem_free(params->bssid);
12699 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012700 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012701 return 0;
12702}
12703
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012704static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
12705 struct net_device *dev,
12706 struct cfg80211_ibss_params *params
12707 )
12708{
12709 int ret = 0;
12710
12711 vos_ssr_protect(__func__);
12712 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
12713 vos_ssr_unprotect(__func__);
12714
12715 return ret;
12716}
12717
Jeff Johnson295189b2012-06-20 16:38:30 -070012718/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012719 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012720 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012721 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012722static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012723 struct net_device *dev
12724 )
12725{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012726 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012727 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12728 tCsrRoamProfile *pRoamProfile;
12729 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012730 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012731
12732 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012733
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012734 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12735 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
12736 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012737 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012738 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012739 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012740 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012741 }
12742
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012743 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
12744 hdd_device_modetoString(pAdapter->device_mode),
12745 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012746 if (NULL == pWextState)
12747 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012748 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012749 __func__);
12750 return -EIO;
12751 }
12752
12753 pRoamProfile = &pWextState->roamProfile;
12754
12755 /* Issue disconnect only if interface type is set to IBSS */
12756 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
12757 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012758 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070012759 __func__);
12760 return -EINVAL;
12761 }
12762
12763 /* Issue Disconnect request */
12764 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12765 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12766 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
12767
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012768 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012769 return 0;
12770}
12771
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012772static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
12773 struct net_device *dev
12774 )
12775{
12776 int ret = 0;
12777
12778 vos_ssr_protect(__func__);
12779 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
12780 vos_ssr_unprotect(__func__);
12781
12782 return ret;
12783}
12784
Jeff Johnson295189b2012-06-20 16:38:30 -070012785/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012786 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070012787 * This function is used to set the phy parameters
12788 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
12789 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012790static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012791 u32 changed)
12792{
12793 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
12794 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012795 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012796
12797 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012798
12799 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012800 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
12801 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012802
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012803 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012804 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012805 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012806 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012807 }
12808
Jeff Johnson295189b2012-06-20 16:38:30 -070012809 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
12810 {
12811 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
12812 WNI_CFG_RTS_THRESHOLD_STAMAX :
12813 wiphy->rts_threshold;
12814
12815 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012816 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070012817 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012818 hddLog(VOS_TRACE_LEVEL_ERROR,
12819 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012820 __func__, rts_threshold);
12821 return -EINVAL;
12822 }
12823
12824 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
12825 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012826 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012827 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012828 hddLog(VOS_TRACE_LEVEL_ERROR,
12829 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012830 __func__, rts_threshold);
12831 return -EIO;
12832 }
12833
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012834 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012835 rts_threshold);
12836 }
12837
12838 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
12839 {
12840 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
12841 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
12842 wiphy->frag_threshold;
12843
12844 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012845 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012846 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012847 hddLog(VOS_TRACE_LEVEL_ERROR,
12848 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012849 frag_threshold);
12850 return -EINVAL;
12851 }
12852
12853 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
12854 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012855 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012856 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012857 hddLog(VOS_TRACE_LEVEL_ERROR,
12858 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012859 __func__, frag_threshold);
12860 return -EIO;
12861 }
12862
12863 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
12864 frag_threshold);
12865 }
12866
12867 if ((changed & WIPHY_PARAM_RETRY_SHORT)
12868 || (changed & WIPHY_PARAM_RETRY_LONG))
12869 {
12870 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
12871 wiphy->retry_short :
12872 wiphy->retry_long;
12873
12874 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
12875 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
12876 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012877 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012878 __func__, retry_value);
12879 return -EINVAL;
12880 }
12881
12882 if (changed & WIPHY_PARAM_RETRY_SHORT)
12883 {
12884 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
12885 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012886 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012887 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012888 hddLog(VOS_TRACE_LEVEL_ERROR,
12889 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012890 __func__, retry_value);
12891 return -EIO;
12892 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012893 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012894 __func__, retry_value);
12895 }
12896 else if (changed & WIPHY_PARAM_RETRY_SHORT)
12897 {
12898 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
12899 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012900 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012901 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012902 hddLog(VOS_TRACE_LEVEL_ERROR,
12903 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012904 __func__, retry_value);
12905 return -EIO;
12906 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012907 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012908 __func__, retry_value);
12909 }
12910 }
12911
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012912 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012913 return 0;
12914}
12915
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012916static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
12917 u32 changed)
12918{
12919 int ret;
12920
12921 vos_ssr_protect(__func__);
12922 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
12923 vos_ssr_unprotect(__func__);
12924
12925 return ret;
12926}
12927
Jeff Johnson295189b2012-06-20 16:38:30 -070012928/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012929 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012930 * This function is used to set the txpower
12931 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012932static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012933#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12934 struct wireless_dev *wdev,
12935#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012936#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012937 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012938#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012939 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012940#endif
12941 int dbm)
12942{
12943 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012944 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012945 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12946 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012947 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012948
12949 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012950
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012951 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12952 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
12953 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012954 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012955 if (0 != status)
12956 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012957 return status;
12958 }
12959
12960 hHal = pHddCtx->hHal;
12961
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012962 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
12963 dbm, ccmCfgSetCallback,
12964 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012965 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012966 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012967 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
12968 return -EIO;
12969 }
12970
12971 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
12972 dbm);
12973
12974 switch(type)
12975 {
12976 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
12977 /* Fall through */
12978 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
12979 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
12980 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012981 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
12982 __func__);
12983 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012984 }
12985 break;
12986 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012987 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012988 __func__);
12989 return -EOPNOTSUPP;
12990 break;
12991 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012992 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
12993 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070012994 return -EIO;
12995 }
12996
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012997 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012998 return 0;
12999}
13000
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013001static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
13002#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13003 struct wireless_dev *wdev,
13004#endif
13005#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13006 enum tx_power_setting type,
13007#else
13008 enum nl80211_tx_power_setting type,
13009#endif
13010 int dbm)
13011{
13012 int ret;
13013 vos_ssr_protect(__func__);
13014 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
13015#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13016 wdev,
13017#endif
13018#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13019 type,
13020#else
13021 type,
13022#endif
13023 dbm);
13024 vos_ssr_unprotect(__func__);
13025
13026 return ret;
13027}
13028
Jeff Johnson295189b2012-06-20 16:38:30 -070013029/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013030 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013031 * This function is used to read the txpower
13032 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013033static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013034#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13035 struct wireless_dev *wdev,
13036#endif
13037 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070013038{
13039
13040 hdd_adapter_t *pAdapter;
13041 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013042 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013043
Jeff Johnsone7245742012-09-05 17:12:55 -070013044 ENTER();
13045
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013046 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013047 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013048 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013049 *dbm = 0;
13050 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013051 }
13052
Jeff Johnson295189b2012-06-20 16:38:30 -070013053 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
13054 if (NULL == pAdapter)
13055 {
13056 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
13057 return -ENOENT;
13058 }
13059
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053013060 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13061 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
13062 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013063 wlan_hdd_get_classAstats(pAdapter);
13064 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
13065
Jeff Johnsone7245742012-09-05 17:12:55 -070013066 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013067 return 0;
13068}
13069
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013070static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
13071#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13072 struct wireless_dev *wdev,
13073#endif
13074 int *dbm)
13075{
13076 int ret;
13077
13078 vos_ssr_protect(__func__);
13079 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
13080#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13081 wdev,
13082#endif
13083 dbm);
13084 vos_ssr_unprotect(__func__);
13085
13086 return ret;
13087}
13088
13089
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013090static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070013091 u8* mac, struct station_info *sinfo)
13092{
13093 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13094 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13095 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053013096 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013097
13098 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
13099 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070013100
13101 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
13102 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
13103 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
13104 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
13105 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
13106 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
13107 tANI_U16 maxRate = 0;
13108 tANI_U16 myRate;
13109 tANI_U16 currentRate = 0;
13110 tANI_U8 maxSpeedMCS = 0;
13111 tANI_U8 maxMCSIdx = 0;
13112 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053013113 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013114 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013115 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013116
Leo Chang6f8870f2013-03-26 18:11:36 -070013117#ifdef WLAN_FEATURE_11AC
13118 tANI_U32 vht_mcs_map;
13119 eDataRate11ACMaxMcs vhtMaxMcs;
13120#endif /* WLAN_FEATURE_11AC */
13121
Jeff Johnsone7245742012-09-05 17:12:55 -070013122 ENTER();
13123
Jeff Johnson295189b2012-06-20 16:38:30 -070013124 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
13125 (0 == ssidlen))
13126 {
13127 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
13128 " Invalid ssidlen, %d", __func__, ssidlen);
13129 /*To keep GUI happy*/
13130 return 0;
13131 }
13132
Mukul Sharma811205f2014-07-09 21:07:30 +053013133 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
13134 {
13135 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13136 "%s: Roaming in progress, so unable to proceed this request", __func__);
13137 return 0;
13138 }
13139
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013140 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013141 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013142 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013143 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013144 }
13145
Jeff Johnson295189b2012-06-20 16:38:30 -070013146
Kiet Lam3b17fc82013-09-27 05:24:08 +053013147 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
13148 sinfo->filled |= STATION_INFO_SIGNAL;
13149
c_hpothu09f19542014-05-30 21:53:31 +053013150 wlan_hdd_get_station_stats(pAdapter);
13151 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
13152
13153 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053013154 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
13155 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053013156 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053013157 {
13158 rate_flags = pAdapter->maxRateFlags;
13159 }
c_hpothu44ff4e02014-05-08 00:13:57 +053013160
Jeff Johnson295189b2012-06-20 16:38:30 -070013161 //convert to the UI units of 100kbps
13162 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
13163
13164#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070013165 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 -070013166 sinfo->signal,
13167 pCfg->reportMaxLinkSpeed,
13168 myRate,
13169 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013170 (int) pCfg->linkSpeedRssiMid,
13171 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070013172 (int) rate_flags,
13173 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013174#endif //LINKSPEED_DEBUG_ENABLED
13175
13176 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
13177 {
13178 // we do not want to necessarily report the current speed
13179 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
13180 {
13181 // report the max possible speed
13182 rssidx = 0;
13183 }
13184 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
13185 {
13186 // report the max possible speed with RSSI scaling
13187 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
13188 {
13189 // report the max possible speed
13190 rssidx = 0;
13191 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013192 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070013193 {
13194 // report middle speed
13195 rssidx = 1;
13196 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013197 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
13198 {
13199 // report middle speed
13200 rssidx = 2;
13201 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013202 else
13203 {
13204 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013205 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070013206 }
13207 }
13208 else
13209 {
13210 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
13211 hddLog(VOS_TRACE_LEVEL_ERROR,
13212 "%s: Invalid value for reportMaxLinkSpeed: %u",
13213 __func__, pCfg->reportMaxLinkSpeed);
13214 rssidx = 0;
13215 }
13216
13217 maxRate = 0;
13218
13219 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013220 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
13221 OperationalRates, &ORLeng))
13222 {
13223 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13224 /*To keep GUI happy*/
13225 return 0;
13226 }
13227
Jeff Johnson295189b2012-06-20 16:38:30 -070013228 for (i = 0; i < ORLeng; i++)
13229 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013230 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013231 {
13232 /* Validate Rate Set */
13233 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
13234 {
13235 currentRate = supported_data_rate[j].supported_rate[rssidx];
13236 break;
13237 }
13238 }
13239 /* Update MAX rate */
13240 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13241 }
13242
13243 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013244 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
13245 ExtendedRates, &ERLeng))
13246 {
13247 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13248 /*To keep GUI happy*/
13249 return 0;
13250 }
13251
Jeff Johnson295189b2012-06-20 16:38:30 -070013252 for (i = 0; i < ERLeng; i++)
13253 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013254 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013255 {
13256 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
13257 {
13258 currentRate = supported_data_rate[j].supported_rate[rssidx];
13259 break;
13260 }
13261 }
13262 /* Update MAX rate */
13263 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13264 }
c_hpothu79aab322014-07-14 21:11:01 +053013265
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013266 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053013267 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013268 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053013269 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070013270 {
c_hpothu79aab322014-07-14 21:11:01 +053013271 if (rate_flags & eHAL_TX_RATE_VHT80)
13272 mode = 2;
13273 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
13274 mode = 1;
13275 else
13276 mode = 0;
13277
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013278 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
13279 MCSRates, &MCSLeng))
13280 {
13281 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13282 /*To keep GUI happy*/
13283 return 0;
13284 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013285 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070013286#ifdef WLAN_FEATURE_11AC
13287 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013288 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070013289 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013290 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013291 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070013292 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070013293 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013294 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013295 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013296 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070013297 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013298 maxMCSIdx = 7;
13299 }
13300 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
13301 {
13302 maxMCSIdx = 8;
13303 }
13304 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
13305 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013306 //VHT20 is supporting 0~8
13307 if (rate_flags & eHAL_TX_RATE_VHT20)
13308 maxMCSIdx = 8;
13309 else
13310 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070013311 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013312
c_hpothu79aab322014-07-14 21:11:01 +053013313 if (0 != rssidx)/*check for scaled */
13314 {
13315 //get middle rate MCS index if rssi=1/2
13316 for (i=0; i <= maxMCSIdx; i++)
13317 {
13318 if (sinfo->signal <= rssiMcsTbl[mode][i])
13319 {
13320 maxMCSIdx = i;
13321 break;
13322 }
13323 }
13324 }
13325
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013326 if (rate_flags & eHAL_TX_RATE_VHT80)
13327 {
13328 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
13329 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
13330 }
13331 else if (rate_flags & eHAL_TX_RATE_VHT40)
13332 {
13333 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
13334 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
13335 }
13336 else if (rate_flags & eHAL_TX_RATE_VHT20)
13337 {
13338 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
13339 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
13340 }
13341
Leo Chang6f8870f2013-03-26 18:11:36 -070013342 maxSpeedMCS = 1;
13343 if (currentRate > maxRate)
13344 {
13345 maxRate = currentRate;
13346 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013347
Leo Chang6f8870f2013-03-26 18:11:36 -070013348 }
13349 else
13350#endif /* WLAN_FEATURE_11AC */
13351 {
13352 if (rate_flags & eHAL_TX_RATE_HT40)
13353 {
13354 rateFlag |= 1;
13355 }
13356 if (rate_flags & eHAL_TX_RATE_SGI)
13357 {
13358 rateFlag |= 2;
13359 }
13360
Girish Gowli01abcee2014-07-31 20:18:55 +053013361 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053013362 if (rssidx == 1 || rssidx == 2)
13363 {
13364 //get middle rate MCS index if rssi=1/2
13365 for (i=0; i <= 7; i++)
13366 {
13367 if (sinfo->signal <= rssiMcsTbl[mode][i])
13368 {
13369 temp = i+1;
13370 break;
13371 }
13372 }
13373 }
c_hpothu79aab322014-07-14 21:11:01 +053013374
13375 for (i = 0; i < MCSLeng; i++)
13376 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013377 for (j = 0; j < temp; j++)
13378 {
13379 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
13380 {
13381 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053013382 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013383 break;
13384 }
13385 }
13386 if ((j < temp) && (currentRate > maxRate))
13387 {
13388 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070013389 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013390 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053013391 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013392 }
13393 }
13394
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013395 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
13396 {
13397 maxRate = myRate;
13398 maxSpeedMCS = 1;
13399 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13400 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013401 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053013402 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070013403 {
13404 maxRate = myRate;
13405 if (rate_flags & eHAL_TX_RATE_LEGACY)
13406 {
13407 maxSpeedMCS = 0;
13408 }
13409 else
13410 {
13411 maxSpeedMCS = 1;
13412 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13413 }
13414 }
13415
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013416 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070013417 {
13418 sinfo->txrate.legacy = maxRate;
13419#ifdef LINKSPEED_DEBUG_ENABLED
13420 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
13421#endif //LINKSPEED_DEBUG_ENABLED
13422 }
13423 else
13424 {
13425 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070013426#ifdef WLAN_FEATURE_11AC
13427 sinfo->txrate.nss = 1;
13428 if (rate_flags & eHAL_TX_RATE_VHT80)
13429 {
13430 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013431 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070013432 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013433 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070013434 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013435 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13436 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13437 }
13438 else if (rate_flags & eHAL_TX_RATE_VHT20)
13439 {
13440 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13441 }
13442#endif /* WLAN_FEATURE_11AC */
13443 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
13444 {
13445 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13446 if (rate_flags & eHAL_TX_RATE_HT40)
13447 {
13448 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13449 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013450 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013451 if (rate_flags & eHAL_TX_RATE_SGI)
13452 {
13453 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13454 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013455
Jeff Johnson295189b2012-06-20 16:38:30 -070013456#ifdef LINKSPEED_DEBUG_ENABLED
13457 pr_info("Reporting MCS rate %d flags %x\n",
13458 sinfo->txrate.mcs,
13459 sinfo->txrate.flags );
13460#endif //LINKSPEED_DEBUG_ENABLED
13461 }
13462 }
13463 else
13464 {
13465 // report current rate instead of max rate
13466
13467 if (rate_flags & eHAL_TX_RATE_LEGACY)
13468 {
13469 //provide to the UI in units of 100kbps
13470 sinfo->txrate.legacy = myRate;
13471#ifdef LINKSPEED_DEBUG_ENABLED
13472 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
13473#endif //LINKSPEED_DEBUG_ENABLED
13474 }
13475 else
13476 {
13477 //must be MCS
13478 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013479#ifdef WLAN_FEATURE_11AC
13480 sinfo->txrate.nss = 1;
13481 if (rate_flags & eHAL_TX_RATE_VHT80)
13482 {
13483 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13484 }
13485 else
13486#endif /* WLAN_FEATURE_11AC */
13487 {
13488 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13489 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013490 if (rate_flags & eHAL_TX_RATE_SGI)
13491 {
13492 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13493 }
13494 if (rate_flags & eHAL_TX_RATE_HT40)
13495 {
13496 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13497 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013498#ifdef WLAN_FEATURE_11AC
13499 else if (rate_flags & eHAL_TX_RATE_VHT80)
13500 {
13501 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
13502 }
13503#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070013504#ifdef LINKSPEED_DEBUG_ENABLED
13505 pr_info("Reporting actual MCS rate %d flags %x\n",
13506 sinfo->txrate.mcs,
13507 sinfo->txrate.flags );
13508#endif //LINKSPEED_DEBUG_ENABLED
13509 }
13510 }
13511 sinfo->filled |= STATION_INFO_TX_BITRATE;
13512
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013513 sinfo->tx_packets =
13514 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
13515 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
13516 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
13517 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
13518
13519 sinfo->tx_retries =
13520 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
13521 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
13522 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
13523 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
13524
13525 sinfo->tx_failed =
13526 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
13527 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
13528 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
13529 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
13530
13531 sinfo->filled |=
13532 STATION_INFO_TX_PACKETS |
13533 STATION_INFO_TX_RETRIES |
13534 STATION_INFO_TX_FAILED;
13535
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013536 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13537 TRACE_CODE_HDD_CFG80211_GET_STA,
13538 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013539 EXIT();
13540 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013541}
13542
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013543static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13544 u8* mac, struct station_info *sinfo)
13545{
13546 int ret;
13547
13548 vos_ssr_protect(__func__);
13549 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
13550 vos_ssr_unprotect(__func__);
13551
13552 return ret;
13553}
13554
13555static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070013556 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070013557{
13558 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013559 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013560 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013561 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013562
Jeff Johnsone7245742012-09-05 17:12:55 -070013563 ENTER();
13564
Jeff Johnson295189b2012-06-20 16:38:30 -070013565 if (NULL == pAdapter)
13566 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013567 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013568 return -ENODEV;
13569 }
13570
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013571 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13572 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
13573 pAdapter->sessionId, timeout));
13574
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013575 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013576 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013577 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013578 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013579 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013580 }
13581
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013582 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
13583 (TRUE == pHddCtx->hdd_wlan_suspended) &&
13584 (pHddCtx->cfg_ini->fhostArpOffload) &&
13585 (eConnectionState_Associated ==
13586 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13587 {
Amar Singhald53568e2013-09-26 11:03:45 -070013588
13589 hddLog(VOS_TRACE_LEVEL_INFO,
13590 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053013591 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013592 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13593 {
13594 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013595 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013596 __func__, vos_status);
13597 }
13598 }
13599
Jeff Johnson295189b2012-06-20 16:38:30 -070013600 /**The get power cmd from the supplicant gets updated by the nl only
13601 *on successful execution of the function call
13602 *we are oppositely mapped w.r.t mode in the driver
13603 **/
13604 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
13605
13606 if (VOS_STATUS_E_FAILURE == vos_status)
13607 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013608 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13609 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013610 return -EINVAL;
13611 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013612 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013613 return 0;
13614}
13615
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013616static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
13617 struct net_device *dev, bool mode, int timeout)
13618{
13619 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013620
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013621 vos_ssr_protect(__func__);
13622 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
13623 vos_ssr_unprotect(__func__);
13624
13625 return ret;
13626}
Jeff Johnson295189b2012-06-20 16:38:30 -070013627#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013628static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
13629 struct net_device *netdev,
13630 u8 key_index)
13631{
13632 ENTER();
13633 return 0;
13634}
13635
Jeff Johnson295189b2012-06-20 16:38:30 -070013636static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013637 struct net_device *netdev,
13638 u8 key_index)
13639{
13640 int ret;
13641 vos_ssr_protect(__func__);
13642 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
13643 vos_ssr_unprotect(__func__);
13644 return ret;
13645}
13646#endif //LINUX_VERSION_CODE
13647
13648#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13649static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13650 struct net_device *dev,
13651 struct ieee80211_txq_params *params)
13652{
13653 ENTER();
13654 return 0;
13655}
13656#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13657static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13658 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013659{
Jeff Johnsone7245742012-09-05 17:12:55 -070013660 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013661 return 0;
13662}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013663#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070013664
13665#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13666static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013667 struct net_device *dev,
13668 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013669{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013670 int ret;
13671
13672 vos_ssr_protect(__func__);
13673 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
13674 vos_ssr_unprotect(__func__);
13675 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013676}
13677#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13678static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
13679 struct ieee80211_txq_params *params)
13680{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013681 int ret;
13682
13683 vos_ssr_protect(__func__);
13684 ret = __wlan_hdd_set_txq_params(wiphy, params);
13685 vos_ssr_unprotect(__func__);
13686 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013687}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013688#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013689
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013690static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013691 struct net_device *dev,
13692 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070013693{
13694 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013695 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013696 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013697 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013698 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013699 v_CONTEXT_t pVosContext = NULL;
13700 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013701
Jeff Johnsone7245742012-09-05 17:12:55 -070013702 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013703
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013704 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070013705 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013706 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013707 return -EINVAL;
13708 }
13709
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013710 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13711 TRACE_CODE_HDD_CFG80211_DEL_STA,
13712 pAdapter->sessionId, pAdapter->device_mode));
13713
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013714 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13715 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013716 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013717 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013718 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013719 }
13720
Jeff Johnson295189b2012-06-20 16:38:30 -070013721 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013722 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013723 )
13724 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013725 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13726 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13727 if(pSapCtx == NULL){
13728 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13729 FL("psapCtx is NULL"));
13730 return -ENOENT;
13731 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013732 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013733 {
13734 v_U16_t i;
13735 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13736 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013737 if ((pSapCtx->aStaInfo[i].isUsed) &&
13738 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070013739 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013740 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013741 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013742 ETHER_ADDR_LEN);
13743
Jeff Johnson295189b2012-06-20 16:38:30 -070013744 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013745 "%s: Delete STA with MAC::"
13746 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013747 __func__,
13748 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
13749 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013750 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013751 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013752 }
13753 }
13754 }
13755 else
13756 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013757
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013758 vos_status = hdd_softap_GetStaId(pAdapter,
13759 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013760 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13761 {
13762 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013763 "%s: Skip this DEL STA as this is not used::"
13764 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013765 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013766 return -ENOENT;
13767 }
13768
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013769 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013770 {
13771 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013772 "%s: Skip this DEL STA as deauth is in progress::"
13773 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013774 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013775 return -ENOENT;
13776 }
13777
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013778 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013779
Jeff Johnson295189b2012-06-20 16:38:30 -070013780 hddLog(VOS_TRACE_LEVEL_INFO,
13781 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013782 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013783 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013784 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013785
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013786 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013787 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13788 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013789 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013790 hddLog(VOS_TRACE_LEVEL_INFO,
13791 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013792 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013793 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013794 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013795 return -ENOENT;
13796 }
13797
Jeff Johnson295189b2012-06-20 16:38:30 -070013798 }
13799 }
13800
13801 EXIT();
13802
13803 return 0;
13804}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013805
13806#ifdef CFG80211_DEL_STA_V2
13807static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13808 struct net_device *dev,
13809 struct station_del_parameters *param)
13810#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013811static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13812 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013813#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013814{
13815 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013816 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070013817
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013818 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013819
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013820#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013821 if (NULL == param) {
13822 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013823 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013824 return -EINVAL;
13825 }
13826
13827 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
13828 param->subtype, &delStaParams);
13829
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013830#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053013831 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013832 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013833#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013834 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
13835
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013836 vos_ssr_unprotect(__func__);
13837
13838 return ret;
13839}
13840
13841static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013842 struct net_device *dev, u8 *mac, struct station_parameters *params)
13843{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013844 hdd_adapter_t *pAdapter;
13845 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013846 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013847#ifdef FEATURE_WLAN_TDLS
13848 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013849
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013850 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013851
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013852 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13853 if (NULL == pAdapter)
13854 {
13855 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13856 "%s: Adapter is NULL",__func__);
13857 return -EINVAL;
13858 }
13859 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13860 status = wlan_hdd_validate_context(pHddCtx);
13861 if (0 != status)
13862 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013863 return status;
13864 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013865
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013866 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13867 TRACE_CODE_HDD_CFG80211_ADD_STA,
13868 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013869 mask = params->sta_flags_mask;
13870
13871 set = params->sta_flags_set;
13872
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053013873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013874 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
13875 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013876
13877 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13878 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013879 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013880 }
13881 }
13882#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013883 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013884 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013885}
13886
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013887static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
13888 struct net_device *dev, u8 *mac, struct station_parameters *params)
13889{
13890 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013891
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013892 vos_ssr_protect(__func__);
13893 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
13894 vos_ssr_unprotect(__func__);
13895
13896 return ret;
13897}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013898#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070013899
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013900static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070013901 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013902{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013903 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13904 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013905 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013906 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013907 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013908 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070013909
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013910 ENTER();
13911
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013912 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013913 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013914 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013915 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013916 return -EINVAL;
13917 }
13918
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013919 if (!pmksa) {
13920 hddLog(LOGE, FL("pmksa is NULL"));
13921 return -EINVAL;
13922 }
13923
13924 if (!pmksa->bssid || !pmksa->pmkid) {
13925 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
13926 pmksa->bssid, pmksa->pmkid);
13927 return -EINVAL;
13928 }
13929
13930 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
13931 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13932
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013933 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13934 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013935 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013936 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013937 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013938 }
13939
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013940 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013941 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13942
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013943 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
13944 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013945
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013946 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013947 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013948 &pmk_id, 1, FALSE);
13949
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013950 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13951 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
13952 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013953
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013954 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013955 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013956}
13957
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013958static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
13959 struct cfg80211_pmksa *pmksa)
13960{
13961 int ret;
13962
13963 vos_ssr_protect(__func__);
13964 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
13965 vos_ssr_unprotect(__func__);
13966
13967 return ret;
13968}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013969
Wilson Yang6507c4e2013-10-01 20:11:19 -070013970
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013971static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070013972 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013973{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013974 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13975 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013976 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013977 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013978
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013979 ENTER();
13980
Wilson Yang6507c4e2013-10-01 20:11:19 -070013981 /* Validate pAdapter */
13982 if (NULL == pAdapter)
13983 {
13984 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
13985 return -EINVAL;
13986 }
13987
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013988 if (!pmksa) {
13989 hddLog(LOGE, FL("pmksa is NULL"));
13990 return -EINVAL;
13991 }
13992
13993 if (!pmksa->bssid) {
13994 hddLog(LOGE, FL("pmksa->bssid is NULL"));
13995 return -EINVAL;
13996 }
13997
Kiet Lam98c46a12014-10-31 15:34:57 -070013998 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
13999 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14000
Wilson Yang6507c4e2013-10-01 20:11:19 -070014001 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14002 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014003 if (0 != status)
14004 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014005 return status;
14006 }
14007
14008 /*Retrieve halHandle*/
14009 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14010
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014011 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14012 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
14013 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014014 /* Delete the PMKID CSR cache */
14015 if (eHAL_STATUS_SUCCESS !=
14016 sme_RoamDelPMKIDfromCache(halHandle,
14017 pAdapter->sessionId, pmksa->bssid, FALSE)) {
14018 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
14019 MAC_ADDR_ARRAY(pmksa->bssid));
14020 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014021 }
14022
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014023 EXIT();
14024 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014025}
14026
Wilson Yang6507c4e2013-10-01 20:11:19 -070014027
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014028static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
14029 struct cfg80211_pmksa *pmksa)
14030{
14031 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014032
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014033 vos_ssr_protect(__func__);
14034 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
14035 vos_ssr_unprotect(__func__);
14036
14037 return ret;
14038
14039}
14040
14041static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014042{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014043 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14044 tHalHandle halHandle;
14045 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014046 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014047
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014048 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070014049
14050 /* Validate pAdapter */
14051 if (NULL == pAdapter)
14052 {
14053 hddLog(VOS_TRACE_LEVEL_ERROR,
14054 "%s: Invalid Adapter" ,__func__);
14055 return -EINVAL;
14056 }
14057
14058 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14059 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014060 if (0 != status)
14061 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014062 return status;
14063 }
14064
14065 /*Retrieve halHandle*/
14066 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14067
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014068 /* Flush the PMKID cache in CSR */
14069 if (eHAL_STATUS_SUCCESS !=
14070 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
14071 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
14072 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014073 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014074 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080014075 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014076}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014077
14078static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
14079{
14080 int ret;
14081
14082 vos_ssr_protect(__func__);
14083 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
14084 vos_ssr_unprotect(__func__);
14085
14086 return ret;
14087}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014088#endif
14089
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014090#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014091static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14092 struct net_device *dev,
14093 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014094{
14095 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14096 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014097 hdd_context_t *pHddCtx;
14098 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014099
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014100 ENTER();
14101
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014102 if (NULL == pAdapter)
14103 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014104 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014105 return -ENODEV;
14106 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014107 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14108 ret = wlan_hdd_validate_context(pHddCtx);
14109 if (0 != ret)
14110 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014111 return ret;
14112 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014113 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014114 if (NULL == pHddStaCtx)
14115 {
14116 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
14117 return -EINVAL;
14118 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014119
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014120 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14121 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
14122 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014123 // Added for debug on reception of Re-assoc Req.
14124 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
14125 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014126 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014127 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080014128 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014129 }
14130
14131#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080014132 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014133 ftie->ie_len);
14134#endif
14135
14136 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014137 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
14138 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014139 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014140
14141 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014142 return 0;
14143}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014144
14145static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14146 struct net_device *dev,
14147 struct cfg80211_update_ft_ies_params *ftie)
14148{
14149 int ret;
14150
14151 vos_ssr_protect(__func__);
14152 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
14153 vos_ssr_unprotect(__func__);
14154
14155 return ret;
14156}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014157#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014158
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014159#ifdef FEATURE_WLAN_SCAN_PNO
14160
14161void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
14162 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
14163{
14164 int ret;
14165 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
14166 hdd_context_t *pHddCtx;
14167
Nirav Shah80830bf2013-12-31 16:35:12 +053014168 ENTER();
14169
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014170 if (NULL == pAdapter)
14171 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014173 "%s: HDD adapter is Null", __func__);
14174 return ;
14175 }
14176
14177 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14178 if (NULL == pHddCtx)
14179 {
14180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14181 "%s: HDD context is Null!!!", __func__);
14182 return ;
14183 }
14184
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014185 spin_lock(&pHddCtx->schedScan_lock);
14186 if (TRUE == pHddCtx->isWiphySuspended)
14187 {
14188 pHddCtx->isSchedScanUpdatePending = TRUE;
14189 spin_unlock(&pHddCtx->schedScan_lock);
14190 hddLog(VOS_TRACE_LEVEL_INFO,
14191 "%s: Update cfg80211 scan database after it resume", __func__);
14192 return ;
14193 }
14194 spin_unlock(&pHddCtx->schedScan_lock);
14195
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014196 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
14197
14198 if (0 > ret)
14199 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
14200
14201 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14203 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014204}
14205
14206/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014207 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014208 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014209 */
14210static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
14211{
14212 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14213 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014214 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014215 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14216 int status = 0;
14217 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
14218
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014219 /* The current firmware design does not allow PNO during any
14220 * active sessions. Hence, determine the active sessions
14221 * and return a failure.
14222 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014223 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
14224 {
14225 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014226 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014227
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014228 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
14229 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
14230 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
14231 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
14232 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053014233 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014234 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014235 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014236 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014237 }
14238 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14239 pAdapterNode = pNext;
14240 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014241 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014242}
14243
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014244void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
14245{
14246 hdd_adapter_t *pAdapter = callbackContext;
14247 hdd_context_t *pHddCtx;
14248
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014249 ENTER();
14250
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014251 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
14252 {
14253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14254 FL("Invalid adapter or adapter has invalid magic"));
14255 return;
14256 }
14257
14258 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14259 if (0 != wlan_hdd_validate_context(pHddCtx))
14260 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014261 return;
14262 }
14263
c_hpothub53c45d2014-08-18 16:53:14 +053014264 if (VOS_STATUS_SUCCESS != status)
14265 {
14266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014267 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053014268 pHddCtx->isPnoEnable = FALSE;
14269 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014270
14271 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
14272 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014273 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014274}
14275
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014276/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014277 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
14278 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014279 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014280static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014281 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14282{
14283 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014284 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014285 hdd_context_t *pHddCtx;
14286 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014287 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053014288 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
14289 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014290 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14291 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014292 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014293 hdd_config_t *pConfig = NULL;
14294 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014295
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014296 ENTER();
14297
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014298 if (NULL == pAdapter)
14299 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014301 "%s: HDD adapter is Null", __func__);
14302 return -ENODEV;
14303 }
14304
14305 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014306 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014307
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014308 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014309 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014310 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014311 }
14312
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014313 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014314 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14315 if (NULL == hHal)
14316 {
14317 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14318 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014319 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014320 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014321 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14322 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
14323 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053014324 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014325 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053014326 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014327 {
14328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14329 "%s: aborting the existing scan is unsuccessfull", __func__);
14330 return -EBUSY;
14331 }
14332
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014333 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014334 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014336 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014337 return -EBUSY;
14338 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014339
c_hpothu37f21312014-04-09 21:49:54 +053014340 if (TRUE == pHddCtx->isPnoEnable)
14341 {
14342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14343 FL("already PNO is enabled"));
14344 return -EBUSY;
14345 }
c_hpothu225aa7c2014-10-22 17:45:13 +053014346
14347 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
14348 {
14349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14350 "%s: abort ROC failed ", __func__);
14351 return -EBUSY;
14352 }
14353
c_hpothu37f21312014-04-09 21:49:54 +053014354 pHddCtx->isPnoEnable = TRUE;
14355
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014356 pnoRequest.enable = 1; /*Enable PNO */
14357 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014358
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014359 if (( !pnoRequest.ucNetworksCount ) ||
14360 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014361 {
14362 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014363 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014364 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014365 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014366 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014367 goto error;
14368 }
14369
14370 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
14371 {
14372 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014373 "%s: Incorrect number of channels %d",
14374 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014375 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014376 goto error;
14377 }
14378
14379 /* Framework provides one set of channels(all)
14380 * common for all saved profile */
14381 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14382 channels_allowed, &num_channels_allowed))
14383 {
14384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14385 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014386 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014387 goto error;
14388 }
14389 /* Checking each channel against allowed channel list */
14390 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053014391 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014392 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014393 char chList [(request->n_channels*5)+1];
14394 int len;
14395 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014396 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014397 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014398 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014399 if (request->channels[i]->hw_value == channels_allowed[indx])
14400 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014401 if ((!pConfig->enableDFSPnoChnlScan) &&
14402 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
14403 {
14404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14405 "%s : Dropping DFS channel : %d",
14406 __func__,channels_allowed[indx]);
14407 num_ignore_dfs_ch++;
14408 break;
14409 }
14410
Nirav Shah80830bf2013-12-31 16:35:12 +053014411 valid_ch[num_ch++] = request->channels[i]->hw_value;
14412 len += snprintf(chList+len, 5, "%d ",
14413 request->channels[i]->hw_value);
14414 break ;
14415 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014416 }
14417 }
Nirav Shah80830bf2013-12-31 16:35:12 +053014418 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014419
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014420 /*If all channels are DFS and dropped, then ignore the PNO request*/
14421 if (num_ignore_dfs_ch == request->n_channels)
14422 {
14423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14424 "%s : All requested channels are DFS channels", __func__);
14425 ret = -EINVAL;
14426 goto error;
14427 }
14428 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014429
14430 pnoRequest.aNetworks =
14431 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14432 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014433 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014434 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14435 FL("failed to allocate memory aNetworks %u"),
14436 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14437 goto error;
14438 }
14439 vos_mem_zero(pnoRequest.aNetworks,
14440 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14441
14442 /* Filling per profile params */
14443 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
14444 {
14445 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014446 request->match_sets[i].ssid.ssid_len;
14447
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014448 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
14449 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014450 {
14451 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014452 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014453 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014454 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014455 goto error;
14456 }
14457
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014458 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014459 request->match_sets[i].ssid.ssid,
14460 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14462 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014463 i, pnoRequest.aNetworks[i].ssId.ssId);
14464 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
14465 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
14466 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014467
14468 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014469 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
14470 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014471
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014472 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014473 }
14474
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014475 for (i = 0; i < request->n_ssids; i++)
14476 {
14477 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014478 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014479 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014480 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014481 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014482 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014483 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014484 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014485 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014486 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014487 break;
14488 }
14489 j++;
14490 }
14491 }
14492 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14493 "Number of hidden networks being Configured = %d",
14494 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014495 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080014496 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014497
14498 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14499 if (pnoRequest.p24GProbeTemplate == NULL)
14500 {
14501 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14502 FL("failed to allocate memory p24GProbeTemplate %u"),
14503 SIR_PNO_MAX_PB_REQ_SIZE);
14504 goto error;
14505 }
14506
14507 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14508 if (pnoRequest.p5GProbeTemplate == NULL)
14509 {
14510 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14511 FL("failed to allocate memory p5GProbeTemplate %u"),
14512 SIR_PNO_MAX_PB_REQ_SIZE);
14513 goto error;
14514 }
14515
14516 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14517 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14518
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053014519 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
14520 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014521 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014522 pnoRequest.us24GProbeTemplateLen = request->ie_len;
14523 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
14524 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014525
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014526 pnoRequest.us5GProbeTemplateLen = request->ie_len;
14527 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
14528 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014529 }
14530
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014531 /* Driver gets only one time interval which is hardcoded in
14532 * supplicant for 10000ms. Taking power consumption into account 6 timers
14533 * will be used, Timervalue is increased exponentially i.e 10,20,40,
14534 * 80,160,320 secs. And number of scan cycle for each timer
14535 * is configurable through INI param gPNOScanTimerRepeatValue.
14536 * If it is set to 0 only one timer will be used and PNO scan cycle
14537 * will be repeated after each interval specified by supplicant
14538 * till PNO is disabled.
14539 */
14540 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014541 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014542 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014543 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014544 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
14545
14546 tempInterval = (request->interval)/1000;
14547 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14548 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
14549 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014550 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014551 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014552 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014553 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014554 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014555 tempInterval *= 2;
14556 }
14557 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014558 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014559
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014560 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014561
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014562 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014563 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
14564 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014565 pAdapter->pno_req_status = 0;
14566
Nirav Shah80830bf2013-12-31 16:35:12 +053014567 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14568 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014569 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
14570 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053014571
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014572 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014573 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014574 hdd_cfg80211_sched_scan_done_callback, pAdapter);
14575 if (eHAL_STATUS_SUCCESS != status)
14576 {
14577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014578 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014579 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014580 goto error;
14581 }
14582
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014583 ret = wait_for_completion_timeout(
14584 &pAdapter->pno_comp_var,
14585 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
14586 if (0 >= ret)
14587 {
14588 // Did not receive the response for PNO enable in time.
14589 // Assuming the PNO enable was success.
14590 // Returning error from here, because we timeout, results
14591 // in side effect of Wifi (Wifi Setting) not to work.
14592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14593 FL("Timed out waiting for PNO to be Enabled"));
14594 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014595 }
14596
14597 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053014598 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014599
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014600error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14602 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053014603 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014604 if (pnoRequest.aNetworks)
14605 vos_mem_free(pnoRequest.aNetworks);
14606 if (pnoRequest.p24GProbeTemplate)
14607 vos_mem_free(pnoRequest.p24GProbeTemplate);
14608 if (pnoRequest.p5GProbeTemplate)
14609 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014610
14611 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014612 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014613}
14614
14615/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014616 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
14617 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014618 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014619static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
14620 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14621{
14622 int ret;
14623
14624 vos_ssr_protect(__func__);
14625 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
14626 vos_ssr_unprotect(__func__);
14627
14628 return ret;
14629}
14630
14631/*
14632 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
14633 * Function to disable PNO
14634 */
14635static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014636 struct net_device *dev)
14637{
14638 eHalStatus status = eHAL_STATUS_FAILURE;
14639 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14640 hdd_context_t *pHddCtx;
14641 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014642 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014643 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014644
14645 ENTER();
14646
14647 if (NULL == pAdapter)
14648 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014650 "%s: HDD adapter is Null", __func__);
14651 return -ENODEV;
14652 }
14653
14654 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014655
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014656 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014657 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014659 "%s: HDD context is Null", __func__);
14660 return -ENODEV;
14661 }
14662
14663 /* The return 0 is intentional when isLogpInProgress and
14664 * isLoadUnloadInProgress. We did observe a crash due to a return of
14665 * failure in sched_scan_stop , especially for a case where the unload
14666 * of the happens at the same time. The function __cfg80211_stop_sched_scan
14667 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
14668 * success. If it returns a failure , then its next invocation due to the
14669 * clean up of the second interface will have the dev pointer corresponding
14670 * to the first one leading to a crash.
14671 */
14672 if (pHddCtx->isLogpInProgress)
14673 {
14674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14675 "%s: LOGP in Progress. Ignore!!!", __func__);
14676 return ret;
14677 }
14678
Mihir Shete18156292014-03-11 15:38:30 +053014679 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014680 {
14681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14682 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14683 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014684 }
14685
14686 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14687 if (NULL == hHal)
14688 {
14689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14690 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014691 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014692 }
14693
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014694 pnoRequest.enable = 0; /* Disable PNO */
14695 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014696
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014697 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14698 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
14699 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014700 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014701 pAdapter->sessionId,
14702 NULL, pAdapter);
14703 if (eHAL_STATUS_SUCCESS != status)
14704 {
14705 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14706 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014707 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014708 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014709 }
c_hpothu37f21312014-04-09 21:49:54 +053014710 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014711
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014712error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014714 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014715
14716 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014717 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014718}
14719
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014720/*
14721 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
14722 * NL interface to disable PNO
14723 */
14724static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
14725 struct net_device *dev)
14726{
14727 int ret;
14728
14729 vos_ssr_protect(__func__);
14730 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
14731 vos_ssr_unprotect(__func__);
14732
14733 return ret;
14734}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014735#endif /*FEATURE_WLAN_SCAN_PNO*/
14736
14737
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014738#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014739#if TDLS_MGMT_VERSION2
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014740static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014741 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014742 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
14743#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014744static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014745 u8 *peer, u8 action_code, u8 dialog_token,
14746 u16 status_code, const u8 *buf, size_t len)
14747#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014748{
14749
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014750 hdd_adapter_t *pAdapter;
14751 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014752 u8 peerMac[6];
14753 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070014754 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080014755 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070014756 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014757 int ret;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014758#if !(TDLS_MGMT_VERSION2)
14759 u32 peer_capability = 0;
14760#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014761 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014762
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014763 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14764 if (NULL == pAdapter)
14765 {
14766 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14767 "%s: Adapter is NULL",__func__);
14768 return -EINVAL;
14769 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014770 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14771 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
14772 pAdapter->sessionId, action_code));
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014773 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014774 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014775 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014777 "Invalid arguments");
14778 return -EINVAL;
14779 }
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014780 if (pHddCtx->isLogpInProgress)
14781 {
14782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14783 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053014784 wlan_hdd_tdls_set_link_status(pAdapter,
14785 peer,
14786 eTDLS_LINK_IDLE,
14787 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014788 return -EBUSY;
14789 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014790 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
14791 {
14792 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14793 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14794 return -EAGAIN;
14795 }
Hoonki Lee27511902013-03-14 18:19:06 -070014796 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014797 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014798 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070014799 "%s: TDLS mode is disabled OR not enabled in FW."
14800 MAC_ADDRESS_STR " action %d declined.",
14801 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014802 return -ENOTSUPP;
14803 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014804
Hoonki Lee27511902013-03-14 18:19:06 -070014805 /* other than teardown frame, other mgmt frames are not sent if disabled */
14806 if (SIR_MAC_TDLS_TEARDOWN != action_code)
14807 {
14808 /* if tdls_mode is disabled to respond to peer's request */
14809 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
14810 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014811 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070014812 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014813 " TDLS mode is disabled. action %d declined.",
14814 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070014815
14816 return -ENOTSUPP;
14817 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014818
14819 if (vos_max_concurrent_connections_reached())
14820 {
14821 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14822 return -EINVAL;
14823 }
Hoonki Lee27511902013-03-14 18:19:06 -070014824 }
14825
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014826 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
14827 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053014828 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014829 {
14830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014831 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014832 " TDLS setup is ongoing. action %d declined.",
14833 __func__, MAC_ADDR_ARRAY(peer), action_code);
14834 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014835 }
14836 }
14837
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014838 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
14839 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080014840 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014841 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14842 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014843 {
14844 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
14845 we return error code at 'add_station()'. Hence we have this
14846 check again in addtion to add_station().
14847 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014848 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014849 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014850 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14851 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014852 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
14853 __func__, MAC_ADDR_ARRAY(peer), action_code,
14854 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053014855 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080014856 }
14857 else
14858 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014859 /* maximum reached. tweak to send error code to peer and return
14860 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014861 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014862 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14863 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014864 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
14865 __func__, MAC_ADDR_ARRAY(peer), status_code,
14866 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070014867 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014868 /* fall through to send setup resp with failure status
14869 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014870 }
14871 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014872 else
14873 {
14874 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014875 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014876 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014877 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014878 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014879 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
14880 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014881 return -EPERM;
14882 }
14883 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014884 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014885 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014886
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014888 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014889 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
14890 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014891
Hoonki Leea34dd892013-02-05 22:56:02 -080014892 /*Except teardown responder will not be used so just make 0*/
14893 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014894 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080014895 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014896
14897 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014898 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014899
14900 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
14901 responder = pTdlsPeer->is_responder;
14902 else
Hoonki Leea34dd892013-02-05 22:56:02 -080014903 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014904 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014905 "%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 -070014906 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
14907 dialog_token, status_code, len);
14908 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080014909 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014910 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014911
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014912 /* For explicit trigger of DIS_REQ come out of BMPS for
14913 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070014914 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014915 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
14916 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070014917 {
14918 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
14919 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014920 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014921 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014922 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
14923 if (status != VOS_STATUS_SUCCESS) {
14924 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
14925 }
Hoonki Lee14621352013-04-16 17:51:19 -070014926 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014927 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
14928 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED)) {
14929 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
14930 }
14931 }
Hoonki Lee14621352013-04-16 17:51:19 -070014932 }
14933
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014934 /* make sure doesn't call send_mgmt() while it is pending */
14935 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
14936 {
14937 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014938 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014939 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014940 ret = -EBUSY;
14941 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014942 }
14943
14944 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014945 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
14946
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014947 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053014948 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014949
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014950 if (VOS_STATUS_SUCCESS != status)
14951 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14953 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014954 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014955 ret = -EINVAL;
14956 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014957 }
14958
Hoonki Leed37cbb32013-04-20 00:31:14 -070014959 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
14960 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
14961
14962 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014963 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070014964 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014965 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070014966 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014967 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080014968
14969 if (pHddCtx->isLogpInProgress)
14970 {
14971 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14972 "%s: LOGP in Progress. Ignore!!!", __func__);
14973 return -EAGAIN;
14974 }
14975
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014976 ret = -EINVAL;
14977 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014978 }
14979
Gopichand Nakkala05922802013-03-14 12:23:19 -070014980 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070014981 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014982 ret = max_sta_failed;
14983 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070014984 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014985
Hoonki Leea34dd892013-02-05 22:56:02 -080014986 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
14987 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014988 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE)) {
14989 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
14990 }
Hoonki Leea34dd892013-02-05 22:56:02 -080014991 }
14992 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
14993 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014994 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE)) {
14995 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
14996 }
Hoonki Leea34dd892013-02-05 22:56:02 -080014997 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014998
14999 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015000
15001tx_failed:
15002 /* add_station will be called before sending TDLS_SETUP_REQ and
15003 * TDLS_SETUP_RSP and as part of add_station driver will enable
15004 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
15005 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
15006 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
15007 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
15008 */
15009
15010 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
15011 (SIR_MAC_TDLS_SETUP_RSP == action_code))
15012 wlan_hdd_tdls_check_bmps(pAdapter);
15013 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015014}
15015
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015016#if TDLS_MGMT_VERSION2
15017static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15018 u8 *peer, u8 action_code, u8 dialog_token,
15019 u16 status_code, u32 peer_capability,
15020 const u8 *buf, size_t len)
15021#else
15022static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15023 u8 *peer, u8 action_code, u8 dialog_token,
15024 u16 status_code, const u8 *buf, size_t len)
15025#endif
15026{
15027 int ret;
15028
15029 vos_ssr_protect(__func__);
15030#if TDLS_MGMT_VERSION2
15031 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
15032 status_code, peer_capability, buf, len);
15033#else
15034 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
15035 status_code, buf, len);
15036#endif
15037 vos_ssr_unprotect(__func__);
15038
15039 return ret;
15040}
Atul Mittal115287b2014-07-08 13:26:33 +053015041
15042int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
15043 u8 *peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015044 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053015045 cfg80211_exttdls_callback callback)
15046{
15047
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015048 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053015049 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015050 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053015051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15052 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
15053 __func__, MAC_ADDR_ARRAY(peer));
15054
15055 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15056 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15057
15058 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015059 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15060 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15061 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015062 return -ENOTSUPP;
15063 }
15064
15065 /* To cater the requirement of establishing the TDLS link
15066 * irrespective of the data traffic , get an entry of TDLS peer.
15067 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015068 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015069 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
15070 if (pTdlsPeer == NULL) {
15071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15072 "%s: peer " MAC_ADDRESS_STR " not existing",
15073 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015074 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015075 return -EINVAL;
15076 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015077 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015078
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015079 /* check FW TDLS Off Channel capability */
15080 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015081 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015082 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015083 {
15084 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
15085 pTdlsPeer->peerParams.global_operating_class =
15086 tdls_peer_params->global_operating_class;
15087 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
15088 pTdlsPeer->peerParams.min_bandwidth_kbps =
15089 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015090 /* check configured channel is valid, non dfs and
15091 * not current operating channel */
15092 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
15093 tdls_peer_params->channel)) &&
15094 (pHddStaCtx) &&
15095 (tdls_peer_params->channel !=
15096 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015097 {
15098 pTdlsPeer->isOffChannelConfigured = TRUE;
15099 }
15100 else
15101 {
15102 pTdlsPeer->isOffChannelConfigured = FALSE;
15103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15104 "%s: Configured Tdls Off Channel is not valid", __func__);
15105
15106 }
15107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015108 "%s: tdls_off_channel %d isOffChannelConfigured %d "
15109 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015110 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015111 pTdlsPeer->isOffChannelConfigured,
15112 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015113 }
15114 else
15115 {
15116 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015117 "%s: TDLS off channel FW capability %d, "
15118 "host capab %d or Invalid TDLS Peer Params", __func__,
15119 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
15120 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015121 }
15122
Atul Mittal115287b2014-07-08 13:26:33 +053015123 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
15124
15125 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15126 " %s TDLS Add Force Peer Failed",
15127 __func__);
15128 return -EINVAL;
15129 }
15130 /*EXT TDLS*/
15131
15132 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
15133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15134 " %s TDLS set callback Failed",
15135 __func__);
15136 return -EINVAL;
15137 }
15138
15139 return(0);
15140
15141}
15142
15143int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
15144{
15145
15146 hddTdlsPeer_t *pTdlsPeer;
15147 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15149 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
15150 __func__, MAC_ADDR_ARRAY(peer));
15151
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015152 if (0 != wlan_hdd_validate_context(pHddCtx)) {
15153 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
15154 return -EINVAL;
15155 }
15156
Atul Mittal115287b2014-07-08 13:26:33 +053015157 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15158 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15159
15160 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015161 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15162 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15163 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015164 return -ENOTSUPP;
15165 }
15166
15167
15168 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15169
15170 if ( NULL == pTdlsPeer ) {
15171 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015172 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053015173 __func__, MAC_ADDR_ARRAY(peer));
15174 return -EINVAL;
15175 }
15176 else {
15177 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
15178 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015179 /* if channel switch is configured, reset
15180 the channel for this peer */
15181 if (TRUE == pTdlsPeer->isOffChannelConfigured)
15182 {
15183 pTdlsPeer->peerParams.channel = 0;
15184 pTdlsPeer->isOffChannelConfigured = FALSE;
15185 }
Atul Mittal115287b2014-07-08 13:26:33 +053015186 }
15187
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015188 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
15189 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053015190 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015191 }
Atul Mittal115287b2014-07-08 13:26:33 +053015192
15193 /*EXT TDLS*/
15194
15195 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
15196
15197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15198 " %s TDLS set callback Failed",
15199 __func__);
15200 return -EINVAL;
15201 }
15202 return(0);
15203
15204}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015205static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015206 u8 *peer, enum nl80211_tdls_operation oper)
15207{
15208 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15209 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015210 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015211 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015212
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015213 ENTER();
15214
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015215 if (!pAdapter) {
15216 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15217 return -EINVAL;
15218 }
15219
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015220 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15221 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
15222 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015223 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015224 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070015226 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015227 return -EINVAL;
15228 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015229
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015230 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015231 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015232 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015233 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015234 }
15235
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015236
15237 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015238 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015239 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015240 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015241 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
15242 "Cannot process TDLS commands",
15243 pHddCtx->cfg_ini->fEnableTDLSSupport,
15244 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015245 return -ENOTSUPP;
15246 }
15247
15248 switch (oper) {
15249 case NL80211_TDLS_ENABLE_LINK:
15250 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015251 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015252 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015253 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053015254 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015255 tANI_U16 numCurrTdlsPeers = 0;
15256 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015257 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015258
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015259 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15260 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
15261 __func__, MAC_ADDR_ARRAY(peer));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015262 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015263 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015264 if ( NULL == pTdlsPeer ) {
15265 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15266 " (oper %d) not exsting. ignored",
15267 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15268 return -EINVAL;
15269 }
15270
15271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15272 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15273 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15274 "NL80211_TDLS_ENABLE_LINK");
15275
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070015276 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
15277 {
15278 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
15279 MAC_ADDRESS_STR " failed",
15280 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
15281 return -EINVAL;
15282 }
15283
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053015284 /* before starting tdls connection, set tdls
15285 * off channel established status to default value */
15286 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015287 /* TDLS Off Channel, Disable tdls channel switch,
15288 when there are more than one tdls link */
15289 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053015290 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015291 {
15292 /* get connected peer and send disable tdls off chan */
15293 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015294 if ((connPeer) &&
15295 (connPeer->isOffChannelSupported == TRUE) &&
15296 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015297 {
15298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15299 "%s: More then one peer connected, Disable "
15300 "TDLS channel switch", __func__);
15301
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015302 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015303 ret = sme_SendTdlsChanSwitchReq(
15304 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015305 pAdapter->sessionId,
15306 connPeer->peerMac,
15307 connPeer->peerParams.channel,
15308 TDLS_OFF_CHANNEL_BW_OFFSET,
15309 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015310 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015311 hddLog(VOS_TRACE_LEVEL_ERROR,
15312 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015313 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015314 }
15315 else
15316 {
15317 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15318 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015319 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015320 "isOffChannelConfigured %d",
15321 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015322 (connPeer ? (connPeer->isOffChannelSupported)
15323 : -1),
15324 (connPeer ? (connPeer->isOffChannelConfigured)
15325 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015326 }
15327 }
15328
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015329 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015330 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015331 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053015332
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015333 if (0 != wlan_hdd_tdls_get_link_establish_params(
15334 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015335 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015336 return -EINVAL;
15337 }
15338 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015339
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015340 ret = sme_SendTdlsLinkEstablishParams(
15341 WLAN_HDD_GET_HAL_CTX(pAdapter),
15342 pAdapter->sessionId, peer,
15343 &tdlsLinkEstablishParams);
15344 if (ret != VOS_STATUS_SUCCESS) {
15345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
15346 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015347 /* Send TDLS peer UAPSD capabilities to the firmware and
15348 * register with the TL on after the response for this operation
15349 * is received .
15350 */
15351 ret = wait_for_completion_interruptible_timeout(
15352 &pAdapter->tdls_link_establish_req_comp,
15353 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
15354 if (ret <= 0)
15355 {
15356 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015357 FL("Link Establish Request Failed Status %ld"),
15358 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015359 return -EINVAL;
15360 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015361 }
Atul Mittal115287b2014-07-08 13:26:33 +053015362 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15363 eTDLS_LINK_CONNECTED,
15364 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015365 staDesc.ucSTAId = pTdlsPeer->staId;
15366 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015367 ret = WLANTL_UpdateTdlsSTAClient(
15368 pHddCtx->pvosContext,
15369 &staDesc);
15370 if (ret != VOS_STATUS_SUCCESS) {
15371 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
15372 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053015373
Gopichand Nakkala471708b2013-06-04 20:03:01 +053015374 /* Mark TDLS client Authenticated .*/
15375 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
15376 pTdlsPeer->staId,
15377 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015378 if (VOS_STATUS_SUCCESS == status)
15379 {
Hoonki Lee14621352013-04-16 17:51:19 -070015380 if (pTdlsPeer->is_responder == 0)
15381 {
15382 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
15383
15384 wlan_hdd_tdls_timer_restart(pAdapter,
15385 &pTdlsPeer->initiatorWaitTimeoutTimer,
15386 WAIT_TIME_TDLS_INITIATOR);
15387 /* suspend initiator TX until it receives direct packet from the
15388 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015389 ret = WLANTL_SuspendDataTx(
15390 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15391 &staId, NULL);
15392 if (ret != VOS_STATUS_SUCCESS) {
15393 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
15394 }
Hoonki Lee14621352013-04-16 17:51:19 -070015395 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015396
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015397 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015398 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015399 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015400 suppChannelLen =
15401 tdlsLinkEstablishParams.supportedChannelsLen;
15402
15403 if ((suppChannelLen > 0) &&
15404 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
15405 {
15406 tANI_U8 suppPeerChannel = 0;
15407 int i = 0;
15408 for (i = 0U; i < suppChannelLen; i++)
15409 {
15410 suppPeerChannel =
15411 tdlsLinkEstablishParams.supportedChannels[i];
15412
15413 pTdlsPeer->isOffChannelSupported = FALSE;
15414 if (suppPeerChannel ==
15415 pTdlsPeer->peerParams.channel)
15416 {
15417 pTdlsPeer->isOffChannelSupported = TRUE;
15418 break;
15419 }
15420 }
15421 }
15422 else
15423 {
15424 pTdlsPeer->isOffChannelSupported = FALSE;
15425 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015426 }
15427 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15428 "%s: TDLS channel switch request for channel "
15429 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015430 "%d isOffChannelSupported %d", __func__,
15431 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015432 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015433 suppChannelLen,
15434 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015435
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015436 /* TDLS Off Channel, Enable tdls channel switch,
15437 when their is only one tdls link and it supports */
15438 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15439 if ((numCurrTdlsPeers == 1) &&
15440 (TRUE == pTdlsPeer->isOffChannelSupported) &&
15441 (TRUE == pTdlsPeer->isOffChannelConfigured))
15442 {
15443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15444 "%s: Send TDLS channel switch request for channel %d",
15445 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015446
15447 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015448 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
15449 pAdapter->sessionId,
15450 pTdlsPeer->peerMac,
15451 pTdlsPeer->peerParams.channel,
15452 TDLS_OFF_CHANNEL_BW_OFFSET,
15453 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015454 if (ret != VOS_STATUS_SUCCESS) {
15455 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
15456 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015457 }
15458 else
15459 {
15460 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15461 "%s: TDLS channel switch request not sent"
15462 " numCurrTdlsPeers %d "
15463 "isOffChannelSupported %d "
15464 "isOffChannelConfigured %d",
15465 __func__, numCurrTdlsPeers,
15466 pTdlsPeer->isOffChannelSupported,
15467 pTdlsPeer->isOffChannelConfigured);
15468 }
15469
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015470 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015471 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015472
15473 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015474 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
15475 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015476 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015477 int ac;
15478 uint8 ucAc[4] = { WLANTL_AC_VO,
15479 WLANTL_AC_VI,
15480 WLANTL_AC_BK,
15481 WLANTL_AC_BE };
15482 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
15483 for(ac=0; ac < 4; ac++)
15484 {
15485 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15486 pTdlsPeer->staId, ucAc[ac],
15487 tlTid[ac], tlTid[ac], 0, 0,
15488 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015489 if (status != VOS_STATUS_SUCCESS) {
15490 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
15491 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015492 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015493 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015494 }
15495
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015496 }
15497 break;
15498 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080015499 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015500 tANI_U16 numCurrTdlsPeers = 0;
15501 hddTdlsPeer_t *connPeer = NULL;
15502
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15504 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
15505 __func__, MAC_ADDR_ARRAY(peer));
15506
Sunil Dutt41de4e22013-11-14 18:09:02 +053015507 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15508
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015509
Sunil Dutt41de4e22013-11-14 18:09:02 +053015510 if ( NULL == pTdlsPeer ) {
15511 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15512 " (oper %d) not exsting. ignored",
15513 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15514 return -EINVAL;
15515 }
15516
15517 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15518 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15519 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15520 "NL80211_TDLS_DISABLE_LINK");
15521
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015522 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080015523 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015524 long status;
15525
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053015526 /* set tdls off channel status to false for this peer */
15527 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053015528 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15529 eTDLS_LINK_TEARING,
15530 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
15531 eTDLS_LINK_UNSPECIFIED:
15532 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015533 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
15534
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015535 status = sme_DeleteTdlsPeerSta(
15536 WLAN_HDD_GET_HAL_CTX(pAdapter),
15537 pAdapter->sessionId, peer );
15538 if (status != VOS_STATUS_SUCCESS) {
15539 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15540 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015541
15542 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
15543 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053015544 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053015545 eTDLS_LINK_IDLE,
15546 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015547 if (status <= 0)
15548 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015549 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15550 "%s: Del station failed status %ld",
15551 __func__, status);
15552 return -EPERM;
15553 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015554
15555 /* TDLS Off Channel, Enable tdls channel switch,
15556 when their is only one tdls link and it supports */
15557 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15558 if (numCurrTdlsPeers == 1)
15559 {
15560 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
15561 if ((connPeer) &&
15562 (connPeer->isOffChannelSupported == TRUE) &&
15563 (connPeer->isOffChannelConfigured == TRUE))
15564 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015565 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015566 status = sme_SendTdlsChanSwitchReq(
15567 WLAN_HDD_GET_HAL_CTX(pAdapter),
15568 pAdapter->sessionId,
15569 connPeer->peerMac,
15570 connPeer->peerParams.channel,
15571 TDLS_OFF_CHANNEL_BW_OFFSET,
15572 TDLS_CHANNEL_SWITCH_ENABLE);
15573 if (status != VOS_STATUS_SUCCESS) {
15574 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
15575 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015576 }
15577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15578 "%s: TDLS channel switch "
15579 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015580 "isOffChannelConfigured %d "
15581 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015582 __func__,
15583 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015584 (connPeer ? connPeer->isOffChannelConfigured : -1),
15585 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015586 }
15587 else
15588 {
15589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15590 "%s: TDLS channel switch request not sent "
15591 "numCurrTdlsPeers %d ",
15592 __func__, numCurrTdlsPeers);
15593 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015594 }
15595 else
15596 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15598 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080015599 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015600 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015601 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015602 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015603 {
Atul Mittal115287b2014-07-08 13:26:33 +053015604 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015605
Atul Mittal115287b2014-07-08 13:26:33 +053015606 if (0 != status)
15607 {
15608 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015609 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053015610 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015611 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053015612 break;
15613 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015614 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015615 {
Atul Mittal115287b2014-07-08 13:26:33 +053015616 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
15617 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015618 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053015619 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015620
Atul Mittal115287b2014-07-08 13:26:33 +053015621 if (0 != status)
15622 {
15623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015624 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053015625 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053015626 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053015627 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015628 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015629 case NL80211_TDLS_DISCOVERY_REQ:
15630 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015632 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015633 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015634 return -ENOTSUPP;
15635 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15637 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015638 return -ENOTSUPP;
15639 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015640
15641 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015642 return 0;
15643}
Chilam NG571c65a2013-01-19 12:27:36 +053015644
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015645static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
15646 u8 *peer, enum nl80211_tdls_operation oper)
15647{
15648 int ret;
15649
15650 vos_ssr_protect(__func__);
15651 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
15652 vos_ssr_unprotect(__func__);
15653
15654 return ret;
15655}
15656
Chilam NG571c65a2013-01-19 12:27:36 +053015657int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
15658 struct net_device *dev, u8 *peer)
15659{
Arif Hussaina7c8e412013-11-20 11:06:42 -080015660 hddLog(VOS_TRACE_LEVEL_INFO,
15661 "tdls send discover req: "MAC_ADDRESS_STR,
15662 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053015663
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015664#if TDLS_MGMT_VERSION2
15665 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15666 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15667#else
Chilam NG571c65a2013-01-19 12:27:36 +053015668 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15669 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015670#endif
Chilam NG571c65a2013-01-19 12:27:36 +053015671}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015672#endif
15673
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015674#ifdef WLAN_FEATURE_GTK_OFFLOAD
15675/*
15676 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
15677 * Callback rountine called upon receiving response for
15678 * get offload info
15679 */
15680void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
15681 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
15682{
15683
15684 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015685 tANI_U8 tempReplayCounter[8];
15686 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015687
15688 ENTER();
15689
15690 if (NULL == pAdapter)
15691 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053015692 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015693 "%s: HDD adapter is Null", __func__);
15694 return ;
15695 }
15696
15697 if (NULL == pGtkOffloadGetInfoRsp)
15698 {
15699 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15700 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
15701 return ;
15702 }
15703
15704 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
15705 {
15706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15707 "%s: wlan Failed to get replay counter value",
15708 __func__);
15709 return ;
15710 }
15711
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015712 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15713 /* Update replay counter */
15714 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
15715 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15716
15717 {
15718 /* changing from little to big endian since supplicant
15719 * works on big endian format
15720 */
15721 int i;
15722 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15723
15724 for (i = 0; i < 8; i++)
15725 {
15726 tempReplayCounter[7-i] = (tANI_U8)p[i];
15727 }
15728 }
15729
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015730 /* Update replay counter to NL */
15731 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015732 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015733}
15734
15735/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015736 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015737 * This function is used to offload GTK rekeying job to the firmware.
15738 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015739int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015740 struct cfg80211_gtk_rekey_data *data)
15741{
15742 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15743 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15744 hdd_station_ctx_t *pHddStaCtx;
15745 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015746 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015747 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015748 eHalStatus status = eHAL_STATUS_FAILURE;
15749
15750 ENTER();
15751
15752 if (NULL == pAdapter)
15753 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015755 "%s: HDD adapter is Null", __func__);
15756 return -ENODEV;
15757 }
15758
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015759 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15760 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
15761 pAdapter->sessionId, pAdapter->device_mode));
15762
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015763 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015764 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015765 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015766 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015767 }
15768
15769 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15770 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15771 if (NULL == hHal)
15772 {
15773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15774 "%s: HAL context is Null!!!", __func__);
15775 return -EAGAIN;
15776 }
15777
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015778 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
15779 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
15780 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
15781 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015782 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015783 {
15784 /* changing from big to little endian since driver
15785 * works on little endian format
15786 */
15787 tANI_U8 *p =
15788 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
15789 int i;
15790
15791 for (i = 0; i < 8; i++)
15792 {
15793 p[7-i] = data->replay_ctr[i];
15794 }
15795 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015796
15797 if (TRUE == pHddCtx->hdd_wlan_suspended)
15798 {
15799 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015800 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
15801 sizeof (tSirGtkOffloadParams));
15802 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015803 pAdapter->sessionId);
15804
15805 if (eHAL_STATUS_SUCCESS != status)
15806 {
15807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15808 "%s: sme_SetGTKOffload failed, returned %d",
15809 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053015810
15811 /* Need to clear any trace of key value in the memory.
15812 * Thus zero out the memory even though it is local
15813 * variable.
15814 */
15815 vos_mem_zero(&hddGtkOffloadReqParams,
15816 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015817 return status;
15818 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15820 "%s: sme_SetGTKOffload successfull", __func__);
15821 }
15822 else
15823 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15825 "%s: wlan not suspended GTKOffload request is stored",
15826 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015827 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015828
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053015829 /* Need to clear any trace of key value in the memory.
15830 * Thus zero out the memory even though it is local
15831 * variable.
15832 */
15833 vos_mem_zero(&hddGtkOffloadReqParams,
15834 sizeof(hddGtkOffloadReqParams));
15835
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015836 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015837 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015838}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015839
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015840int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
15841 struct cfg80211_gtk_rekey_data *data)
15842{
15843 int ret;
15844
15845 vos_ssr_protect(__func__);
15846 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
15847 vos_ssr_unprotect(__func__);
15848
15849 return ret;
15850}
15851#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015852/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015853 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015854 * This function is used to set access control policy
15855 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015856static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
15857 struct net_device *dev,
15858 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015859{
15860 int i;
15861 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15862 hdd_hostapd_state_t *pHostapdState;
15863 tsap_Config_t *pConfig;
15864 v_CONTEXT_t pVosContext = NULL;
15865 hdd_context_t *pHddCtx;
15866 int status;
15867
15868 ENTER();
15869
15870 if (NULL == pAdapter)
15871 {
15872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15873 "%s: HDD adapter is Null", __func__);
15874 return -ENODEV;
15875 }
15876
15877 if (NULL == params)
15878 {
15879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15880 "%s: params is Null", __func__);
15881 return -EINVAL;
15882 }
15883
15884 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15885 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015886 if (0 != status)
15887 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015888 return status;
15889 }
15890
15891 pVosContext = pHddCtx->pvosContext;
15892 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
15893
15894 if (NULL == pHostapdState)
15895 {
15896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15897 "%s: pHostapdState is Null", __func__);
15898 return -EINVAL;
15899 }
15900
15901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
15902 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015903 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15904 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
15905 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015906
15907 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
15908 {
15909 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
15910
15911 /* default value */
15912 pConfig->num_accept_mac = 0;
15913 pConfig->num_deny_mac = 0;
15914
15915 /**
15916 * access control policy
15917 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
15918 * listed in hostapd.deny file.
15919 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
15920 * listed in hostapd.accept file.
15921 */
15922 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
15923 {
15924 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
15925 }
15926 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
15927 {
15928 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
15929 }
15930 else
15931 {
15932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15933 "%s:Acl Policy : %d is not supported",
15934 __func__, params->acl_policy);
15935 return -ENOTSUPP;
15936 }
15937
15938 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
15939 {
15940 pConfig->num_accept_mac = params->n_acl_entries;
15941 for (i = 0; i < params->n_acl_entries; i++)
15942 {
15943 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15944 "** Add ACL MAC entry %i in WhiletList :"
15945 MAC_ADDRESS_STR, i,
15946 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
15947
15948 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
15949 sizeof(qcmacaddr));
15950 }
15951 }
15952 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
15953 {
15954 pConfig->num_deny_mac = params->n_acl_entries;
15955 for (i = 0; i < params->n_acl_entries; i++)
15956 {
15957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15958 "** Add ACL MAC entry %i in BlackList :"
15959 MAC_ADDRESS_STR, i,
15960 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
15961
15962 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
15963 sizeof(qcmacaddr));
15964 }
15965 }
15966
15967 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
15968 {
15969 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15970 "%s: SAP Set Mac Acl fail", __func__);
15971 return -EINVAL;
15972 }
15973 }
15974 else
15975 {
15976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015977 "%s: Invalid device_mode = %s (%d)",
15978 __func__, hdd_device_modetoString(pAdapter->device_mode),
15979 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015980 return -EINVAL;
15981 }
15982
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015983 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015984 return 0;
15985}
15986
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015987static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
15988 struct net_device *dev,
15989 const struct cfg80211_acl_data *params)
15990{
15991 int ret;
15992 vos_ssr_protect(__func__);
15993 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
15994 vos_ssr_unprotect(__func__);
15995
15996 return ret;
15997}
15998
Leo Chang9056f462013-08-01 19:21:11 -070015999#ifdef WLAN_NL80211_TESTMODE
16000#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070016001void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070016002(
16003 void *pAdapter,
16004 void *indCont
16005)
16006{
Leo Changd9df8aa2013-09-26 13:32:26 -070016007 tSirLPHBInd *lphbInd;
16008 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053016009 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070016010
16011 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016012 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070016013
c_hpothu73f35e62014-04-18 13:40:08 +053016014 if (pAdapter == NULL)
16015 {
16016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16017 "%s: pAdapter is NULL\n",__func__);
16018 return;
16019 }
16020
Leo Chang9056f462013-08-01 19:21:11 -070016021 if (NULL == indCont)
16022 {
16023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016024 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070016025 return;
16026 }
16027
c_hpothu73f35e62014-04-18 13:40:08 +053016028 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070016029 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070016030 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053016031 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070016032 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070016033 GFP_ATOMIC);
16034 if (!skb)
16035 {
16036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16037 "LPHB timeout, NL buffer alloc fail");
16038 return;
16039 }
16040
Leo Changac3ba772013-10-07 09:47:04 -070016041 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070016042 {
16043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16044 "WLAN_HDD_TM_ATTR_CMD put fail");
16045 goto nla_put_failure;
16046 }
Leo Changac3ba772013-10-07 09:47:04 -070016047 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070016048 {
16049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16050 "WLAN_HDD_TM_ATTR_TYPE put fail");
16051 goto nla_put_failure;
16052 }
Leo Changac3ba772013-10-07 09:47:04 -070016053 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070016054 sizeof(tSirLPHBInd), lphbInd))
16055 {
16056 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16057 "WLAN_HDD_TM_ATTR_DATA put fail");
16058 goto nla_put_failure;
16059 }
Leo Chang9056f462013-08-01 19:21:11 -070016060 cfg80211_testmode_event(skb, GFP_ATOMIC);
16061 return;
16062
16063nla_put_failure:
16064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16065 "NLA Put fail");
16066 kfree_skb(skb);
16067
16068 return;
16069}
16070#endif /* FEATURE_WLAN_LPHB */
16071
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016072static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070016073{
16074 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
16075 int err = 0;
16076#ifdef FEATURE_WLAN_LPHB
16077 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070016078 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016079
16080 ENTER();
16081
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016082 err = wlan_hdd_validate_context(pHddCtx);
16083 if (0 != err)
16084 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016085 return err;
16086 }
Leo Chang9056f462013-08-01 19:21:11 -070016087#endif /* FEATURE_WLAN_LPHB */
16088
16089 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
16090 if (err)
16091 {
16092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16093 "%s Testmode INV ATTR", __func__);
16094 return err;
16095 }
16096
16097 if (!tb[WLAN_HDD_TM_ATTR_CMD])
16098 {
16099 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16100 "%s Testmode INV CMD", __func__);
16101 return -EINVAL;
16102 }
16103
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016104 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16105 TRACE_CODE_HDD_CFG80211_TESTMODE,
16106 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070016107 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
16108 {
16109#ifdef FEATURE_WLAN_LPHB
16110 /* Low Power Heartbeat configuration request */
16111 case WLAN_HDD_TM_CMD_WLAN_HB:
16112 {
16113 int buf_len;
16114 void *buf;
16115 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080016116 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070016117
16118 if (!tb[WLAN_HDD_TM_ATTR_DATA])
16119 {
16120 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16121 "%s Testmode INV DATA", __func__);
16122 return -EINVAL;
16123 }
16124
16125 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
16126 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080016127
16128 hb_params_temp =(tSirLPHBReq *)buf;
16129 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
16130 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
16131 return -EINVAL;
16132
Leo Chang9056f462013-08-01 19:21:11 -070016133 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
16134 if (NULL == hb_params)
16135 {
16136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16137 "%s Request Buffer Alloc Fail", __func__);
16138 return -EINVAL;
16139 }
16140
16141 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070016142 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
16143 hb_params,
16144 wlan_hdd_cfg80211_lphb_ind_handler);
16145 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070016146 {
Leo Changd9df8aa2013-09-26 13:32:26 -070016147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16148 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070016149 vos_mem_free(hb_params);
16150 }
Leo Chang9056f462013-08-01 19:21:11 -070016151 return 0;
16152 }
16153#endif /* FEATURE_WLAN_LPHB */
16154 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16156 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070016157 return -EOPNOTSUPP;
16158 }
16159
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016160 EXIT();
16161 return err;
Leo Chang9056f462013-08-01 19:21:11 -070016162}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016163
16164static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
16165{
16166 int ret;
16167
16168 vos_ssr_protect(__func__);
16169 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
16170 vos_ssr_unprotect(__func__);
16171
16172 return ret;
16173}
Leo Chang9056f462013-08-01 19:21:11 -070016174#endif /* CONFIG_NL80211_TESTMODE */
16175
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016176static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016177 struct net_device *dev,
16178 int idx, struct survey_info *survey)
16179{
16180 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16181 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053016182 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016183 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053016184 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016185 v_S7_t snr,rssi;
16186 int status, i, j, filled = 0;
16187
16188 ENTER();
16189
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016190 if (NULL == pAdapter)
16191 {
16192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16193 "%s: HDD adapter is Null", __func__);
16194 return -ENODEV;
16195 }
16196
16197 if (NULL == wiphy)
16198 {
16199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16200 "%s: wiphy is Null", __func__);
16201 return -ENODEV;
16202 }
16203
16204 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16205 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016206 if (0 != status)
16207 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016208 return status;
16209 }
16210
Mihir Sheted9072e02013-08-21 17:02:29 +053016211 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16212
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016213 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053016214 0 != pAdapter->survey_idx ||
16215 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016216 {
16217 /* The survey dump ops when implemented completely is expected to
16218 * return a survey of all channels and the ops is called by the
16219 * kernel with incremental values of the argument 'idx' till it
16220 * returns -ENONET. But we can only support the survey for the
16221 * operating channel for now. survey_idx is used to track
16222 * that the ops is called only once and then return -ENONET for
16223 * the next iteration
16224 */
16225 pAdapter->survey_idx = 0;
16226 return -ENONET;
16227 }
16228
Mukul Sharma9d5233b2015-06-11 20:28:20 +053016229 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16230 {
16231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16232 "%s: Roaming in progress, hence return ", __func__);
16233 return -ENONET;
16234 }
16235
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016236 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16237
16238 wlan_hdd_get_snr(pAdapter, &snr);
16239 wlan_hdd_get_rssi(pAdapter, &rssi);
16240
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016241 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16242 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
16243 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016244 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
16245 hdd_wlan_get_freq(channel, &freq);
16246
16247
16248 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
16249 {
16250 if (NULL == wiphy->bands[i])
16251 {
16252 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
16253 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
16254 continue;
16255 }
16256
16257 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
16258 {
16259 struct ieee80211_supported_band *band = wiphy->bands[i];
16260
16261 if (band->channels[j].center_freq == (v_U16_t)freq)
16262 {
16263 survey->channel = &band->channels[j];
16264 /* The Rx BDs contain SNR values in dB for the received frames
16265 * while the supplicant expects noise. So we calculate and
16266 * return the value of noise (dBm)
16267 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
16268 */
16269 survey->noise = rssi - snr;
16270 survey->filled = SURVEY_INFO_NOISE_DBM;
16271 filled = 1;
16272 }
16273 }
16274 }
16275
16276 if (filled)
16277 pAdapter->survey_idx = 1;
16278 else
16279 {
16280 pAdapter->survey_idx = 0;
16281 return -ENONET;
16282 }
16283
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016284 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016285 return 0;
16286}
16287
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016288static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
16289 struct net_device *dev,
16290 int idx, struct survey_info *survey)
16291{
16292 int ret;
16293
16294 vos_ssr_protect(__func__);
16295 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
16296 vos_ssr_unprotect(__func__);
16297
16298 return ret;
16299}
16300
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016301/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016302 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016303 * this is called when cfg80211 driver resume
16304 * driver updates latest sched_scan scan result(if any) to cfg80211 database
16305 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016306int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016307{
16308 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16309 hdd_adapter_t *pAdapter;
16310 hdd_adapter_list_node_t *pAdapterNode, *pNext;
16311 VOS_STATUS status = VOS_STATUS_SUCCESS;
16312
16313 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016314
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016315 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016316 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016317 return 0;
16318 }
16319
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016320 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
16321 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016322 spin_lock(&pHddCtx->schedScan_lock);
16323 pHddCtx->isWiphySuspended = FALSE;
16324 if (TRUE != pHddCtx->isSchedScanUpdatePending)
16325 {
16326 spin_unlock(&pHddCtx->schedScan_lock);
16327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16328 "%s: Return resume is not due to PNO indication", __func__);
16329 return 0;
16330 }
16331 // Reset flag to avoid updatating cfg80211 data old results again
16332 pHddCtx->isSchedScanUpdatePending = FALSE;
16333 spin_unlock(&pHddCtx->schedScan_lock);
16334
16335 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
16336
16337 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
16338 {
16339 pAdapter = pAdapterNode->pAdapter;
16340 if ( (NULL != pAdapter) &&
16341 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
16342 {
16343 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016344 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016345 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16346 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016347 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016348 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016349 {
16350 /* Acquire wakelock to handle the case where APP's tries to
16351 * suspend immediately after updating the scan results. Whis
16352 * results in app's is in suspended state and not able to
16353 * process the connect request to AP
16354 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053016355 hdd_prevent_suspend_timeout(2000,
16356 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016357 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016358 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016359
16360 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16361 "%s : cfg80211 scan result database updated", __func__);
16362
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016363 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016364 return 0;
16365
16366 }
16367 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16368 pAdapterNode = pNext;
16369 }
16370
16371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16372 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016373 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016374 return 0;
16375}
16376
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016377int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
16378{
16379 int ret;
16380
16381 vos_ssr_protect(__func__);
16382 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
16383 vos_ssr_unprotect(__func__);
16384
16385 return ret;
16386}
16387
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016388/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016389 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016390 * this is called when cfg80211 driver suspends
16391 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016392int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016393 struct cfg80211_wowlan *wow)
16394{
16395 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016396 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016397
16398 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016399
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016400 ret = wlan_hdd_validate_context(pHddCtx);
16401 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016402 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016403 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016404 }
16405
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016406
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016407 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16408 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
16409 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016410 pHddCtx->isWiphySuspended = TRUE;
16411
16412 EXIT();
16413
16414 return 0;
16415}
16416
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016417int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
16418 struct cfg80211_wowlan *wow)
16419{
16420 int ret;
16421
16422 vos_ssr_protect(__func__);
16423 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
16424 vos_ssr_unprotect(__func__);
16425
16426 return ret;
16427}
Jeff Johnson295189b2012-06-20 16:38:30 -070016428/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016429static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070016430{
16431 .add_virtual_intf = wlan_hdd_add_virtual_intf,
16432 .del_virtual_intf = wlan_hdd_del_virtual_intf,
16433 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
16434 .change_station = wlan_hdd_change_station,
16435#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
16436 .add_beacon = wlan_hdd_cfg80211_add_beacon,
16437 .del_beacon = wlan_hdd_cfg80211_del_beacon,
16438 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016439#else
16440 .start_ap = wlan_hdd_cfg80211_start_ap,
16441 .change_beacon = wlan_hdd_cfg80211_change_beacon,
16442 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070016443#endif
16444 .change_bss = wlan_hdd_cfg80211_change_bss,
16445 .add_key = wlan_hdd_cfg80211_add_key,
16446 .get_key = wlan_hdd_cfg80211_get_key,
16447 .del_key = wlan_hdd_cfg80211_del_key,
16448 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016449#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070016450 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016451#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016452 .scan = wlan_hdd_cfg80211_scan,
16453 .connect = wlan_hdd_cfg80211_connect,
16454 .disconnect = wlan_hdd_cfg80211_disconnect,
16455 .join_ibss = wlan_hdd_cfg80211_join_ibss,
16456 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
16457 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
16458 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
16459 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070016460 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
16461 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053016462 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070016463#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16464 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
16465 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
16466 .set_txq_params = wlan_hdd_set_txq_params,
16467#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016468 .get_station = wlan_hdd_cfg80211_get_station,
16469 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
16470 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016471 .add_station = wlan_hdd_cfg80211_add_station,
16472#ifdef FEATURE_WLAN_LFR
16473 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
16474 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
16475 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
16476#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016477#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
16478 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
16479#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016480#ifdef FEATURE_WLAN_TDLS
16481 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
16482 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
16483#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016484#ifdef WLAN_FEATURE_GTK_OFFLOAD
16485 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
16486#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016487#ifdef FEATURE_WLAN_SCAN_PNO
16488 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
16489 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
16490#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016491 .resume = wlan_hdd_cfg80211_resume_wlan,
16492 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016493 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070016494#ifdef WLAN_NL80211_TESTMODE
16495 .testmode_cmd = wlan_hdd_cfg80211_testmode,
16496#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016497 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070016498};
16499