blob: dc072d80b87c39b35c8fc51cb969292406c5dc87 [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#ifdef FEATURE_WLAN_TDLS
94#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053095#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053096#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080097#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053098#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070099#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700100
101#define g_mode_rates_size (12)
102#define a_mode_rates_size (8)
103#define FREQ_BASE_80211G (2407)
104#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700105#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530106#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700107#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800108 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700109
110#define HDD2GHZCHAN(freq, chan, flag) { \
111 .band = IEEE80211_BAND_2GHZ, \
112 .center_freq = (freq), \
113 .hw_value = (chan),\
114 .flags = (flag), \
115 .max_antenna_gain = 0 ,\
116 .max_power = 30, \
117}
118
119#define HDD5GHZCHAN(freq, chan, flag) { \
120 .band = IEEE80211_BAND_5GHZ, \
121 .center_freq = (freq), \
122 .hw_value = (chan),\
123 .flags = (flag), \
124 .max_antenna_gain = 0 ,\
125 .max_power = 30, \
126}
127
128#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
129{\
130 .bitrate = rate, \
131 .hw_value = rate_id, \
132 .flags = flag, \
133}
134
Lee Hoonkic1262f22013-01-24 21:59:00 -0800135#ifndef WLAN_FEATURE_TDLS_DEBUG
136#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
137#else
138#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
139#endif
140
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530141#ifdef WLAN_FEATURE_VOWIFI_11R
142#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
143#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
144#endif
145
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530146#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530147#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530148
Sunil Duttc69bccb2014-05-26 21:30:20 +0530149#ifdef WLAN_FEATURE_LINK_LAYER_STATS
150/*
151 * Used to allocate the size of 4096 for the link layer stats.
152 * The size of 4096 is considered assuming that all data per
153 * respective event fit with in the limit.Please take a call
154 * on the limit based on the data requirements on link layer
155 * statistics.
156 */
157#define LL_STATS_EVENT_BUF_SIZE 4096
158#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530159#ifdef WLAN_FEATURE_EXTSCAN
160/*
161 * Used to allocate the size of 4096 for the EXTScan NL data.
162 * The size of 4096 is considered assuming that all data per
163 * respective event fit with in the limit.Please take a call
164 * on the limit based on the data requirements.
165 */
166
167#define EXTSCAN_EVENT_BUF_SIZE 4096
168#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
169#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530170
Atul Mittal115287b2014-07-08 13:26:33 +0530171/*EXT TDLS*/
172/*
173 * Used to allocate the size of 4096 for the TDLS.
174 * The size of 4096 is considered assuming that all data per
175 * respective event fit with in the limit.Please take a call
176 * on the limit based on the data requirements on link layer
177 * statistics.
178 */
179#define EXTTDLS_EVENT_BUF_SIZE 4096
180
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530181static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700182{
183 WLAN_CIPHER_SUITE_WEP40,
184 WLAN_CIPHER_SUITE_WEP104,
185 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800186#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700187#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
188 WLAN_CIPHER_SUITE_KRK,
189 WLAN_CIPHER_SUITE_CCMP,
190#else
191 WLAN_CIPHER_SUITE_CCMP,
192#endif
193#ifdef FEATURE_WLAN_WAPI
194 WLAN_CIPHER_SUITE_SMS4,
195#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700196#ifdef WLAN_FEATURE_11W
197 WLAN_CIPHER_SUITE_AES_CMAC,
198#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700199};
200
201static inline int is_broadcast_ether_addr(const u8 *addr)
202{
203 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
204 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
205}
206
207static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530208{
Jeff Johnson295189b2012-06-20 16:38:30 -0700209 HDD2GHZCHAN(2412, 1, 0) ,
210 HDD2GHZCHAN(2417, 2, 0) ,
211 HDD2GHZCHAN(2422, 3, 0) ,
212 HDD2GHZCHAN(2427, 4, 0) ,
213 HDD2GHZCHAN(2432, 5, 0) ,
214 HDD2GHZCHAN(2437, 6, 0) ,
215 HDD2GHZCHAN(2442, 7, 0) ,
216 HDD2GHZCHAN(2447, 8, 0) ,
217 HDD2GHZCHAN(2452, 9, 0) ,
218 HDD2GHZCHAN(2457, 10, 0) ,
219 HDD2GHZCHAN(2462, 11, 0) ,
220 HDD2GHZCHAN(2467, 12, 0) ,
221 HDD2GHZCHAN(2472, 13, 0) ,
222 HDD2GHZCHAN(2484, 14, 0) ,
223};
224
Jeff Johnson295189b2012-06-20 16:38:30 -0700225static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
226{
227 HDD2GHZCHAN(2412, 1, 0) ,
228 HDD2GHZCHAN(2437, 6, 0) ,
229 HDD2GHZCHAN(2462, 11, 0) ,
230};
Jeff Johnson295189b2012-06-20 16:38:30 -0700231
232static struct ieee80211_channel hdd_channels_5_GHZ[] =
233{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700234 HDD5GHZCHAN(4920, 240, 0) ,
235 HDD5GHZCHAN(4940, 244, 0) ,
236 HDD5GHZCHAN(4960, 248, 0) ,
237 HDD5GHZCHAN(4980, 252, 0) ,
238 HDD5GHZCHAN(5040, 208, 0) ,
239 HDD5GHZCHAN(5060, 212, 0) ,
240 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700241 HDD5GHZCHAN(5180, 36, 0) ,
242 HDD5GHZCHAN(5200, 40, 0) ,
243 HDD5GHZCHAN(5220, 44, 0) ,
244 HDD5GHZCHAN(5240, 48, 0) ,
245 HDD5GHZCHAN(5260, 52, 0) ,
246 HDD5GHZCHAN(5280, 56, 0) ,
247 HDD5GHZCHAN(5300, 60, 0) ,
248 HDD5GHZCHAN(5320, 64, 0) ,
249 HDD5GHZCHAN(5500,100, 0) ,
250 HDD5GHZCHAN(5520,104, 0) ,
251 HDD5GHZCHAN(5540,108, 0) ,
252 HDD5GHZCHAN(5560,112, 0) ,
253 HDD5GHZCHAN(5580,116, 0) ,
254 HDD5GHZCHAN(5600,120, 0) ,
255 HDD5GHZCHAN(5620,124, 0) ,
256 HDD5GHZCHAN(5640,128, 0) ,
257 HDD5GHZCHAN(5660,132, 0) ,
258 HDD5GHZCHAN(5680,136, 0) ,
259 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800260#ifdef FEATURE_WLAN_CH144
261 HDD5GHZCHAN(5720,144, 0) ,
262#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700263 HDD5GHZCHAN(5745,149, 0) ,
264 HDD5GHZCHAN(5765,153, 0) ,
265 HDD5GHZCHAN(5785,157, 0) ,
266 HDD5GHZCHAN(5805,161, 0) ,
267 HDD5GHZCHAN(5825,165, 0) ,
268};
269
270static struct ieee80211_rate g_mode_rates[] =
271{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530272 HDD_G_MODE_RATETAB(10, 0x1, 0),
273 HDD_G_MODE_RATETAB(20, 0x2, 0),
274 HDD_G_MODE_RATETAB(55, 0x4, 0),
275 HDD_G_MODE_RATETAB(110, 0x8, 0),
276 HDD_G_MODE_RATETAB(60, 0x10, 0),
277 HDD_G_MODE_RATETAB(90, 0x20, 0),
278 HDD_G_MODE_RATETAB(120, 0x40, 0),
279 HDD_G_MODE_RATETAB(180, 0x80, 0),
280 HDD_G_MODE_RATETAB(240, 0x100, 0),
281 HDD_G_MODE_RATETAB(360, 0x200, 0),
282 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700283 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530284};
Jeff Johnson295189b2012-06-20 16:38:30 -0700285
286static struct ieee80211_rate a_mode_rates[] =
287{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530288 HDD_G_MODE_RATETAB(60, 0x10, 0),
289 HDD_G_MODE_RATETAB(90, 0x20, 0),
290 HDD_G_MODE_RATETAB(120, 0x40, 0),
291 HDD_G_MODE_RATETAB(180, 0x80, 0),
292 HDD_G_MODE_RATETAB(240, 0x100, 0),
293 HDD_G_MODE_RATETAB(360, 0x200, 0),
294 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700295 HDD_G_MODE_RATETAB(540, 0x800, 0),
296};
297
298static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
299{
300 .channels = hdd_channels_2_4_GHZ,
301 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
302 .band = IEEE80211_BAND_2GHZ,
303 .bitrates = g_mode_rates,
304 .n_bitrates = g_mode_rates_size,
305 .ht_cap.ht_supported = 1,
306 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
307 | IEEE80211_HT_CAP_GRN_FLD
308 | IEEE80211_HT_CAP_DSSSCCK40
309 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
310 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
311 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
312 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
313 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
314 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
315};
316
Jeff Johnson295189b2012-06-20 16:38:30 -0700317static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
318{
319 .channels = hdd_social_channels_2_4_GHZ,
320 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
321 .band = IEEE80211_BAND_2GHZ,
322 .bitrates = g_mode_rates,
323 .n_bitrates = g_mode_rates_size,
324 .ht_cap.ht_supported = 1,
325 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
326 | IEEE80211_HT_CAP_GRN_FLD
327 | IEEE80211_HT_CAP_DSSSCCK40
328 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
329 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
330 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
331 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
332 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
333 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
334};
Jeff Johnson295189b2012-06-20 16:38:30 -0700335
336static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
337{
338 .channels = hdd_channels_5_GHZ,
339 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
340 .band = IEEE80211_BAND_5GHZ,
341 .bitrates = a_mode_rates,
342 .n_bitrates = a_mode_rates_size,
343 .ht_cap.ht_supported = 1,
344 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
345 | IEEE80211_HT_CAP_GRN_FLD
346 | IEEE80211_HT_CAP_DSSSCCK40
347 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
348 | IEEE80211_HT_CAP_SGI_40
349 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
350 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
351 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
352 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
353 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
354 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
355};
356
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530357/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700358 TX/RX direction for each kind of interface */
359static const struct ieee80211_txrx_stypes
360wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
361 [NL80211_IFTYPE_STATION] = {
362 .tx = 0xffff,
363 .rx = BIT(SIR_MAC_MGMT_ACTION) |
364 BIT(SIR_MAC_MGMT_PROBE_REQ),
365 },
366 [NL80211_IFTYPE_AP] = {
367 .tx = 0xffff,
368 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
369 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
370 BIT(SIR_MAC_MGMT_PROBE_REQ) |
371 BIT(SIR_MAC_MGMT_DISASSOC) |
372 BIT(SIR_MAC_MGMT_AUTH) |
373 BIT(SIR_MAC_MGMT_DEAUTH) |
374 BIT(SIR_MAC_MGMT_ACTION),
375 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700376 [NL80211_IFTYPE_ADHOC] = {
377 .tx = 0xffff,
378 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
379 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
380 BIT(SIR_MAC_MGMT_PROBE_REQ) |
381 BIT(SIR_MAC_MGMT_DISASSOC) |
382 BIT(SIR_MAC_MGMT_AUTH) |
383 BIT(SIR_MAC_MGMT_DEAUTH) |
384 BIT(SIR_MAC_MGMT_ACTION),
385 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700386 [NL80211_IFTYPE_P2P_CLIENT] = {
387 .tx = 0xffff,
388 .rx = BIT(SIR_MAC_MGMT_ACTION) |
389 BIT(SIR_MAC_MGMT_PROBE_REQ),
390 },
391 [NL80211_IFTYPE_P2P_GO] = {
392 /* This is also same as for SoftAP */
393 .tx = 0xffff,
394 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
395 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
396 BIT(SIR_MAC_MGMT_PROBE_REQ) |
397 BIT(SIR_MAC_MGMT_DISASSOC) |
398 BIT(SIR_MAC_MGMT_AUTH) |
399 BIT(SIR_MAC_MGMT_DEAUTH) |
400 BIT(SIR_MAC_MGMT_ACTION),
401 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700402};
403
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800404#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800405static const struct ieee80211_iface_limit
406wlan_hdd_iface_limit[] = {
407 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800408 /* max = 3 ; Our driver create two interfaces during driver init
409 * wlan0 and p2p0 interfaces. p2p0 is considered as station
410 * interface until a group is formed. In JB architecture, once the
411 * group is formed, interface type of p2p0 is changed to P2P GO or
412 * Client.
413 * When supplicant remove the group, it first issue a set interface
414 * cmd to change the mode back to Station. In JB this works fine as
415 * we advertize two station type interface during driver init.
416 * Some vendors create separate interface for P2P GO/Client,
417 * after group formation(Third one). But while group remove
418 * supplicant first tries to change the mode(3rd interface) to STATION
419 * But as we advertized only two sta type interfaces nl80211 was
420 * returning error for the third one which was leading to failure in
421 * delete interface. Ideally while removing the group, supplicant
422 * should not try to change the 3rd interface mode to Station type.
423 * Till we get a fix in wpa_supplicant, we advertize max STA
424 * interface type to 3
425 */
426 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800427 .types = BIT(NL80211_IFTYPE_STATION),
428 },
429 {
430 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700431 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800432 },
433 {
434 .max = 1,
435 .types = BIT(NL80211_IFTYPE_P2P_GO) |
436 BIT(NL80211_IFTYPE_P2P_CLIENT),
437 },
438};
439
440/* By default, only single channel concurrency is allowed */
441static struct ieee80211_iface_combination
442wlan_hdd_iface_combination = {
443 .limits = wlan_hdd_iface_limit,
444 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800445 /*
446 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
447 * and p2p0 interfaces during driver init
448 * Some vendors create separate interface for P2P operations.
449 * wlan0: STA interface
450 * p2p0: P2P Device interface, action frames goes
451 * through this interface.
452 * p2p-xx: P2P interface, After GO negotiation this interface is
453 * created for p2p operations(GO/CLIENT interface).
454 */
455 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800456 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
457 .beacon_int_infra_match = false,
458};
459#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800460
Jeff Johnson295189b2012-06-20 16:38:30 -0700461static struct cfg80211_ops wlan_hdd_cfg80211_ops;
462
463/* Data rate 100KBPS based on IE Index */
464struct index_data_rate_type
465{
466 v_U8_t beacon_rate_index;
467 v_U16_t supported_rate[4];
468};
469
470/* 11B, 11G Rate table include Basic rate and Extended rate
471 The IDX field is the rate index
472 The HI field is the rate when RSSI is strong or being ignored
473 (in this case we report actual rate)
474 The MID field is the rate when RSSI is moderate
475 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
476 The LO field is the rate when RSSI is low
477 (in this case we don't report rates, actual current rate used)
478 */
479static const struct
480{
481 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700482 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700483} supported_data_rate[] =
484{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700485/* IDX HI HM LM LO (RSSI-based index */
486 {2, { 10, 10, 10, 0}},
487 {4, { 20, 20, 10, 0}},
488 {11, { 55, 20, 10, 0}},
489 {12, { 60, 55, 20, 0}},
490 {18, { 90, 55, 20, 0}},
491 {22, {110, 55, 20, 0}},
492 {24, {120, 90, 60, 0}},
493 {36, {180, 120, 60, 0}},
494 {44, {220, 180, 60, 0}},
495 {48, {240, 180, 90, 0}},
496 {66, {330, 180, 90, 0}},
497 {72, {360, 240, 90, 0}},
498 {96, {480, 240, 120, 0}},
499 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700500};
501
502/* MCS Based rate table */
503static struct index_data_rate_type supported_mcs_rate[] =
504{
505/* MCS L20 L40 S20 S40 */
506 {0, {65, 135, 72, 150}},
507 {1, {130, 270, 144, 300}},
508 {2, {195, 405, 217, 450}},
509 {3, {260, 540, 289, 600}},
510 {4, {390, 810, 433, 900}},
511 {5, {520, 1080, 578, 1200}},
512 {6, {585, 1215, 650, 1350}},
513 {7, {650, 1350, 722, 1500}}
514};
515
Leo Chang6f8870f2013-03-26 18:11:36 -0700516#ifdef WLAN_FEATURE_11AC
517
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530518#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700519
520struct index_vht_data_rate_type
521{
522 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530523 v_U16_t supported_VHT80_rate[2];
524 v_U16_t supported_VHT40_rate[2];
525 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700526};
527
528typedef enum
529{
530 DATA_RATE_11AC_MAX_MCS_7,
531 DATA_RATE_11AC_MAX_MCS_8,
532 DATA_RATE_11AC_MAX_MCS_9,
533 DATA_RATE_11AC_MAX_MCS_NA
534} eDataRate11ACMaxMcs;
535
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530536/* SSID broadcast type */
537typedef enum eSSIDBcastType
538{
539 eBCAST_UNKNOWN = 0,
540 eBCAST_NORMAL = 1,
541 eBCAST_HIDDEN = 2,
542} tSSIDBcastType;
543
Leo Chang6f8870f2013-03-26 18:11:36 -0700544/* MCS Based VHT rate table */
545static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
546{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530547/* MCS L80 S80 L40 S40 L20 S40*/
548 {0, {293, 325}, {135, 150}, {65, 72}},
549 {1, {585, 650}, {270, 300}, {130, 144}},
550 {2, {878, 975}, {405, 450}, {195, 217}},
551 {3, {1170, 1300}, {540, 600}, {260, 289}},
552 {4, {1755, 1950}, {810, 900}, {390, 433}},
553 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
554 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
555 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
556 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
557 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700558};
559#endif /* WLAN_FEATURE_11AC */
560
c_hpothu79aab322014-07-14 21:11:01 +0530561/*array index points to MCS and array value points respective rssi*/
562static int rssiMcsTbl[][10] =
563{
564/*MCS 0 1 2 3 4 5 6 7 8 9*/
565 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
566 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
567 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
568};
569
Jeff Johnson295189b2012-06-20 16:38:30 -0700570extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530571#ifdef FEATURE_WLAN_SCAN_PNO
572static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
573#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700574
Leo Chang9056f462013-08-01 19:21:11 -0700575#ifdef WLAN_NL80211_TESTMODE
576enum wlan_hdd_tm_attr
577{
578 WLAN_HDD_TM_ATTR_INVALID = 0,
579 WLAN_HDD_TM_ATTR_CMD = 1,
580 WLAN_HDD_TM_ATTR_DATA = 2,
581 WLAN_HDD_TM_ATTR_TYPE = 3,
582 /* keep last */
583 WLAN_HDD_TM_ATTR_AFTER_LAST,
584 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
585};
586
587enum wlan_hdd_tm_cmd
588{
589 WLAN_HDD_TM_CMD_WLAN_HB = 1,
590};
591
592#define WLAN_HDD_TM_DATA_MAX_LEN 5000
593
594static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
595{
596 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
597 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
598 .len = WLAN_HDD_TM_DATA_MAX_LEN },
599};
600#endif /* WLAN_NL80211_TESTMODE */
601
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800602#ifdef FEATURE_WLAN_CH_AVOID
603/*
604 * FUNCTION: wlan_hdd_send_avoid_freq_event
605 * This is called when wlan driver needs to send vendor specific
606 * avoid frequency range event to userspace
607 */
608int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
609 tHddAvoidFreqList *pAvoidFreqList)
610{
611 struct sk_buff *vendor_event;
612
613 ENTER();
614
615 if (!pHddCtx)
616 {
617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
618 "%s: HDD context is null", __func__);
619 return -1;
620 }
621
622 if (!pAvoidFreqList)
623 {
624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
625 "%s: pAvoidFreqList is null", __func__);
626 return -1;
627 }
628
629 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
630 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530631 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800632 GFP_KERNEL);
633 if (!vendor_event)
634 {
635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
636 "%s: cfg80211_vendor_event_alloc failed", __func__);
637 return -1;
638 }
639
640 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
641 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
642
643 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
644
645 EXIT();
646 return 0;
647}
648#endif /* FEATURE_WLAN_CH_AVOID */
649
Sunil Duttc69bccb2014-05-26 21:30:20 +0530650#ifdef WLAN_FEATURE_LINK_LAYER_STATS
651
652static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
653 struct sk_buff *vendor_event)
654{
655 if (nla_put_u8(vendor_event,
656 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
657 stats->rate.preamble) ||
658 nla_put_u8(vendor_event,
659 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
660 stats->rate.nss) ||
661 nla_put_u8(vendor_event,
662 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
663 stats->rate.bw) ||
664 nla_put_u8(vendor_event,
665 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
666 stats->rate.rateMcsIdx) ||
667 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
668 stats->rate.bitrate ) ||
669 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
670 stats->txMpdu ) ||
671 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
672 stats->rxMpdu ) ||
673 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
674 stats->mpduLost ) ||
675 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
676 stats->retries) ||
677 nla_put_u32(vendor_event,
678 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
679 stats->retriesShort ) ||
680 nla_put_u32(vendor_event,
681 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
682 stats->retriesLong))
683 {
684 hddLog(VOS_TRACE_LEVEL_ERROR,
685 FL("QCA_WLAN_VENDOR_ATTR put fail"));
686 return FALSE;
687 }
688 return TRUE;
689}
690
691static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
692 struct sk_buff *vendor_event)
693{
694 u32 i = 0;
695 struct nlattr *rateInfo;
696 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
697 stats->type) ||
698 nla_put(vendor_event,
699 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
700 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
701 nla_put_u32(vendor_event,
702 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
703 stats->capabilities) ||
704 nla_put_u32(vendor_event,
705 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
706 stats->numRate))
707 {
708 hddLog(VOS_TRACE_LEVEL_ERROR,
709 FL("QCA_WLAN_VENDOR_ATTR put fail"));
710 goto error;
711 }
712
713 rateInfo = nla_nest_start(vendor_event,
714 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530715 if(!rateInfo)
716 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530717 for (i = 0; i < stats->numRate; i++)
718 {
719 struct nlattr *rates;
720 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
721 stats->rateStats +
722 (i * sizeof(tSirWifiRateStat)));
723 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530724 if(!rates)
725 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530726
727 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
728 {
729 hddLog(VOS_TRACE_LEVEL_ERROR,
730 FL("QCA_WLAN_VENDOR_ATTR put fail"));
731 return FALSE;
732 }
733 nla_nest_end(vendor_event, rates);
734 }
735 nla_nest_end(vendor_event, rateInfo);
736
737 return TRUE;
738error:
739 return FALSE;
740}
741
742static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
743 struct sk_buff *vendor_event)
744{
745 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
746 stats->ac ) ||
747 nla_put_u32(vendor_event,
748 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
749 stats->txMpdu ) ||
750 nla_put_u32(vendor_event,
751 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
752 stats->rxMpdu ) ||
753 nla_put_u32(vendor_event,
754 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
755 stats->txMcast ) ||
756 nla_put_u32(vendor_event,
757 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
758 stats->rxMcast ) ||
759 nla_put_u32(vendor_event,
760 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
761 stats->rxAmpdu ) ||
762 nla_put_u32(vendor_event,
763 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
764 stats->txAmpdu ) ||
765 nla_put_u32(vendor_event,
766 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
767 stats->mpduLost )||
768 nla_put_u32(vendor_event,
769 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
770 stats->retries ) ||
771 nla_put_u32(vendor_event,
772 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
773 stats->retriesShort ) ||
774 nla_put_u32(vendor_event,
775 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
776 stats->retriesLong ) ||
777 nla_put_u32(vendor_event,
778 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
779 stats->contentionTimeMin ) ||
780 nla_put_u32(vendor_event,
781 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
782 stats->contentionTimeMax ) ||
783 nla_put_u32(vendor_event,
784 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
785 stats->contentionTimeAvg ) ||
786 nla_put_u32(vendor_event,
787 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
788 stats->contentionNumSamples ))
789 {
790 hddLog(VOS_TRACE_LEVEL_ERROR,
791 FL("QCA_WLAN_VENDOR_ATTR put fail") );
792 return FALSE;
793 }
794 return TRUE;
795}
796
797static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
798 struct sk_buff *vendor_event)
799{
Dino Myclec8f3f332014-07-21 16:48:27 +0530800 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530801 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
802 nla_put(vendor_event,
803 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
804 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
805 nla_put_u32(vendor_event,
806 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
807 stats->state ) ||
808 nla_put_u32(vendor_event,
809 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
810 stats->roaming ) ||
811 nla_put_u32(vendor_event,
812 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
813 stats->capabilities ) ||
814 nla_put(vendor_event,
815 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
816 strlen(stats->ssid), stats->ssid) ||
817 nla_put(vendor_event,
818 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
819 WNI_CFG_BSSID_LEN, stats->bssid) ||
820 nla_put(vendor_event,
821 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
822 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
823 nla_put(vendor_event,
824 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
825 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
826 )
827 {
828 hddLog(VOS_TRACE_LEVEL_ERROR,
829 FL("QCA_WLAN_VENDOR_ATTR put fail") );
830 return FALSE;
831 }
832 return TRUE;
833}
834
Dino Mycle3b9536d2014-07-09 22:05:24 +0530835static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
836 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530837 struct sk_buff *vendor_event)
838{
839 int i = 0;
840 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530841 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
842 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530843 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530844
Sunil Duttc69bccb2014-05-26 21:30:20 +0530845 if (FALSE == put_wifi_interface_info(
846 &pWifiIfaceStat->info,
847 vendor_event))
848 {
849 hddLog(VOS_TRACE_LEVEL_ERROR,
850 FL("QCA_WLAN_VENDOR_ATTR put fail") );
851 return FALSE;
852
853 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530854 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
855 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
856 if (NULL == pWifiIfaceStatTL)
857 {
858 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
859 return FALSE;
860 }
861
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530862 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
863 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
864 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
865 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
866
867 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
868 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
869 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
870 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530871
872 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
873 {
874 if (VOS_STATUS_SUCCESS ==
875 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
876 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
877 {
878 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
879 * obtained from TL structure
880 */
881
882 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
883 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530884 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
885
Srinivas Dasari98947432014-11-07 19:41:24 +0530886 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
887 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
888 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
889 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
890 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
891 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
892 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
893 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530894
Srinivas Dasari98947432014-11-07 19:41:24 +0530895 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
896 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
897 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
898 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
899 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
900 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
901 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
902 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530903
Srinivas Dasari98947432014-11-07 19:41:24 +0530904 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
905 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
906 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
907 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
908 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
909 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
910 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
911 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530912 }
913 else
914 {
915 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
916 }
917
Dino Mycle3b9536d2014-07-09 22:05:24 +0530918 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
919 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
920 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
921 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
922 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
923 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
924 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
925 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
926 }
927 else
928 {
929 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
930 }
931
932
Sunil Duttc69bccb2014-05-26 21:30:20 +0530933
934 if (nla_put_u32(vendor_event,
935 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
936 pWifiIfaceStat->beaconRx) ||
937 nla_put_u32(vendor_event,
938 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
939 pWifiIfaceStat->mgmtRx) ||
940 nla_put_u32(vendor_event,
941 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
942 pWifiIfaceStat->mgmtActionRx) ||
943 nla_put_u32(vendor_event,
944 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
945 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530946 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530947 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
948 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530949 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530950 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
951 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530952 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530953 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
954 pWifiIfaceStat->rssiAck))
955 {
956 hddLog(VOS_TRACE_LEVEL_ERROR,
957 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530958 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530959 return FALSE;
960 }
961
962 wmmInfo = nla_nest_start(vendor_event,
963 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530964 if(!wmmInfo)
965 {
966 vos_mem_free(pWifiIfaceStatTL);
967 return FALSE;
968 }
Sunil Duttc69bccb2014-05-26 21:30:20 +0530969 for (i = 0; i < WIFI_AC_MAX; i++)
970 {
971 struct nlattr *wmmStats;
972 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530973 if(!wmmStats)
974 {
975 vos_mem_free(pWifiIfaceStatTL);
976 return FALSE;
977 }
Sunil Duttc69bccb2014-05-26 21:30:20 +0530978 if (FALSE == put_wifi_wmm_ac_stat(
979 &pWifiIfaceStat->AccessclassStats[i],
980 vendor_event))
981 {
982 hddLog(VOS_TRACE_LEVEL_ERROR,
983 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530984 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530985 return FALSE;
986 }
987
988 nla_nest_end(vendor_event, wmmStats);
989 }
990 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +0530991 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530992 return TRUE;
993}
994
995static tSirWifiInterfaceMode
996 hdd_map_device_to_ll_iface_mode ( int deviceMode )
997{
998 switch (deviceMode)
999 {
1000 case WLAN_HDD_INFRA_STATION:
1001 return WIFI_INTERFACE_STA;
1002 case WLAN_HDD_SOFTAP:
1003 return WIFI_INTERFACE_SOFTAP;
1004 case WLAN_HDD_P2P_CLIENT:
1005 return WIFI_INTERFACE_P2P_CLIENT;
1006 case WLAN_HDD_P2P_GO:
1007 return WIFI_INTERFACE_P2P_GO;
1008 case WLAN_HDD_IBSS:
1009 return WIFI_INTERFACE_IBSS;
1010 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301011 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301012 }
1013}
1014
1015static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1016 tpSirWifiInterfaceInfo pInfo)
1017{
1018 v_U8_t *staMac = NULL;
1019 hdd_station_ctx_t *pHddStaCtx;
1020 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1021 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1022
1023 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1024
1025 vos_mem_copy(pInfo->macAddr,
1026 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1027
1028 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1029 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1030 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1031 {
1032 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1033 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1034 {
1035 pInfo->state = WIFI_DISCONNECTED;
1036 }
1037 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1038 {
1039 hddLog(VOS_TRACE_LEVEL_ERROR,
1040 "%s: Session ID %d, Connection is in progress", __func__,
1041 pAdapter->sessionId);
1042 pInfo->state = WIFI_ASSOCIATING;
1043 }
1044 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1045 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1046 {
1047 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1048 hddLog(VOS_TRACE_LEVEL_ERROR,
1049 "%s: client " MAC_ADDRESS_STR
1050 " is in the middle of WPS/EAPOL exchange.", __func__,
1051 MAC_ADDR_ARRAY(staMac));
1052 pInfo->state = WIFI_AUTHENTICATING;
1053 }
1054 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1055 {
1056 pInfo->state = WIFI_ASSOCIATED;
1057 vos_mem_copy(pInfo->bssid,
1058 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1059 vos_mem_copy(pInfo->ssid,
1060 pHddStaCtx->conn_info.SSID.SSID.ssId,
1061 pHddStaCtx->conn_info.SSID.SSID.length);
1062 //NULL Terminate the string.
1063 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1064 }
1065 }
1066 vos_mem_copy(pInfo->countryStr,
1067 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1068
1069 vos_mem_copy(pInfo->apCountryStr,
1070 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1071
1072 return TRUE;
1073}
1074
1075/*
1076 * hdd_link_layer_process_peer_stats () - This function is called after
1077 * receiving Link Layer Peer statistics from FW.This function converts
1078 * the firmware data to the NL data and sends the same to the kernel/upper
1079 * layers.
1080 */
1081static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1082 v_VOID_t *pData)
1083{
1084 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1085 tpSirWifiRateStat pWifiRateStat;
1086 tpSirWifiPeerStat pWifiPeerStat;
1087 tpSirWifiPeerInfo pWifiPeerInfo;
1088 struct nlattr *peerInfo;
1089 struct sk_buff *vendor_event;
1090 int status, i;
1091
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301092 ENTER();
1093
Sunil Duttc69bccb2014-05-26 21:30:20 +05301094 status = wlan_hdd_validate_context(pHddCtx);
1095 if (0 != status)
1096 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301097 return;
1098 }
1099
1100 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1101
1102 hddLog(VOS_TRACE_LEVEL_INFO,
1103 "LL_STATS_PEER_ALL : numPeers %u",
1104 pWifiPeerStat->numPeers);
1105 {
1106 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1107 {
1108 pWifiPeerInfo = (tpSirWifiPeerInfo)
1109 ((uint8 *)pWifiPeerStat->peerInfo +
1110 ( i * sizeof(tSirWifiPeerInfo)));
1111
Dasari Srinivas1be0c4e2014-10-19 13:03:41 +05301112 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) {
1113 pWifiPeerInfo->type = WIFI_PEER_AP;
1114 }
1115 if (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) {
1116 pWifiPeerInfo->type = WIFI_PEER_P2P_GO;
1117 }
1118
Sunil Duttc69bccb2014-05-26 21:30:20 +05301119 hddLog(VOS_TRACE_LEVEL_INFO,
1120 " %d) LL_STATS Channel Stats "
1121 " Peer Type %u "
1122 " peerMacAddress %pM "
1123 " capabilities 0x%x "
1124 " numRate %u ",
1125 i,
1126 pWifiPeerInfo->type,
1127 pWifiPeerInfo->peerMacAddress,
1128 pWifiPeerInfo->capabilities,
1129 pWifiPeerInfo->numRate);
1130 {
1131 int j;
1132 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1133 {
1134 pWifiRateStat = (tpSirWifiRateStat)
1135 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1136 ( j * sizeof(tSirWifiRateStat)));
1137
1138 hddLog(VOS_TRACE_LEVEL_INFO,
1139 " peer Rate Stats "
1140 " preamble %u "
1141 " nss %u "
1142 " bw %u "
1143 " rateMcsIdx %u "
1144 " reserved %u "
1145 " bitrate %u "
1146 " txMpdu %u "
1147 " rxMpdu %u "
1148 " mpduLost %u "
1149 " retries %u "
1150 " retriesShort %u "
1151 " retriesLong %u",
1152 pWifiRateStat->rate.preamble,
1153 pWifiRateStat->rate.nss,
1154 pWifiRateStat->rate.bw,
1155 pWifiRateStat->rate.rateMcsIdx,
1156 pWifiRateStat->rate.reserved,
1157 pWifiRateStat->rate.bitrate,
1158 pWifiRateStat->txMpdu,
1159 pWifiRateStat->rxMpdu,
1160 pWifiRateStat->mpduLost,
1161 pWifiRateStat->retries,
1162 pWifiRateStat->retriesShort,
1163 pWifiRateStat->retriesLong);
1164 }
1165 }
1166 }
1167 }
1168
1169 /*
1170 * Allocate a size of 4096 for the peer stats comprising
1171 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1172 * sizeof (tSirWifiRateStat).Each field is put with an
1173 * NL attribute.The size of 4096 is considered assuming
1174 * that number of rates shall not exceed beyond 50 with
1175 * the sizeof (tSirWifiRateStat) being 32.
1176 */
1177 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1178 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1179 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1180 GFP_KERNEL);
1181 if (!vendor_event)
1182 {
1183 hddLog(VOS_TRACE_LEVEL_ERROR,
1184 "%s: cfg80211_vendor_event_alloc failed",
1185 __func__);
1186 return;
1187 }
1188 if (nla_put_u32(vendor_event,
1189 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1190 pWifiPeerStat->numPeers))
1191 {
1192 hddLog(VOS_TRACE_LEVEL_ERROR,
1193 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1194 kfree_skb(vendor_event);
1195 return;
1196 }
1197
1198 peerInfo = nla_nest_start(vendor_event,
1199 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301200 if(!peerInfo)
1201 {
1202 hddLog(VOS_TRACE_LEVEL_ERROR,
1203 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1204 __func__);
1205 kfree_skb(vendor_event);
1206 return;
1207 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301208
1209 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1210 pWifiPeerStat->peerInfo);
1211
1212 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1213 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301214 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301215 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301216
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301217 if(!peers)
1218 {
1219 hddLog(VOS_TRACE_LEVEL_ERROR,
1220 "%s: peer stats put fail",
1221 __func__);
1222 kfree_skb(vendor_event);
1223 return;
1224 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301225 if (FALSE == put_wifi_peer_info(
1226 pWifiPeerInfo, vendor_event))
1227 {
1228 hddLog(VOS_TRACE_LEVEL_ERROR,
1229 "%s: put_wifi_peer_info put fail", __func__);
1230 kfree_skb(vendor_event);
1231 return;
1232 }
1233
1234 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1235 pWifiPeerStat->peerInfo +
1236 (i * sizeof(tSirWifiPeerInfo)) +
1237 (numRate * sizeof (tSirWifiRateStat)));
1238 nla_nest_end(vendor_event, peers);
1239 }
1240 nla_nest_end(vendor_event, peerInfo);
1241 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301242
1243 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301244}
1245
1246/*
1247 * hdd_link_layer_process_iface_stats () - This function is called after
1248 * receiving Link Layer Interface statistics from FW.This function converts
1249 * the firmware data to the NL data and sends the same to the kernel/upper
1250 * layers.
1251 */
1252static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1253 v_VOID_t *pData)
1254{
1255 tpSirWifiIfaceStat pWifiIfaceStat;
1256 struct sk_buff *vendor_event;
1257 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1258 int status;
1259
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301260 ENTER();
1261
Sunil Duttc69bccb2014-05-26 21:30:20 +05301262 status = wlan_hdd_validate_context(pHddCtx);
1263 if (0 != status)
1264 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301265 return;
1266 }
1267 /*
1268 * Allocate a size of 4096 for the interface stats comprising
1269 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1270 * assuming that all these fit with in the limit.Please take
1271 * a call on the limit based on the data requirements on
1272 * interface statistics.
1273 */
1274 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1275 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1276 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1277 GFP_KERNEL);
1278 if (!vendor_event)
1279 {
1280 hddLog(VOS_TRACE_LEVEL_ERROR,
1281 FL("cfg80211_vendor_event_alloc failed") );
1282 return;
1283 }
1284
1285 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1286
Dino Mycle3b9536d2014-07-09 22:05:24 +05301287
1288 if (FALSE == hdd_get_interface_info( pAdapter,
1289 &pWifiIfaceStat->info))
1290 {
1291 hddLog(VOS_TRACE_LEVEL_ERROR,
1292 FL("hdd_get_interface_info get fail") );
1293 kfree_skb(vendor_event);
1294 return;
1295 }
1296
1297 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1298 vendor_event))
1299 {
1300 hddLog(VOS_TRACE_LEVEL_ERROR,
1301 FL("put_wifi_iface_stats fail") );
1302 kfree_skb(vendor_event);
1303 return;
1304 }
1305
Sunil Duttc69bccb2014-05-26 21:30:20 +05301306 hddLog(VOS_TRACE_LEVEL_INFO,
1307 "WMI_LINK_STATS_IFACE Data");
1308
1309 hddLog(VOS_TRACE_LEVEL_INFO,
1310 "LL_STATS_IFACE: "
1311 " Mode %u "
1312 " MAC %pM "
1313 " State %u "
1314 " Roaming %u "
1315 " capabilities 0x%x "
1316 " SSID %s "
1317 " BSSID %pM",
1318 pWifiIfaceStat->info.mode,
1319 pWifiIfaceStat->info.macAddr,
1320 pWifiIfaceStat->info.state,
1321 pWifiIfaceStat->info.roaming,
1322 pWifiIfaceStat->info.capabilities,
1323 pWifiIfaceStat->info.ssid,
1324 pWifiIfaceStat->info.bssid);
1325
1326 hddLog(VOS_TRACE_LEVEL_INFO,
1327 " AP country str: %c%c%c",
1328 pWifiIfaceStat->info.apCountryStr[0],
1329 pWifiIfaceStat->info.apCountryStr[1],
1330 pWifiIfaceStat->info.apCountryStr[2]);
1331
1332
1333 hddLog(VOS_TRACE_LEVEL_INFO,
1334 " Country Str Association: %c%c%c",
1335 pWifiIfaceStat->info.countryStr[0],
1336 pWifiIfaceStat->info.countryStr[1],
1337 pWifiIfaceStat->info.countryStr[2]);
1338
1339 hddLog(VOS_TRACE_LEVEL_INFO,
1340 " beaconRx %u "
1341 " mgmtRx %u "
1342 " mgmtActionRx %u "
1343 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301344 " rssiMgmt %d "
1345 " rssiData %d "
1346 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301347 pWifiIfaceStat->beaconRx,
1348 pWifiIfaceStat->mgmtRx,
1349 pWifiIfaceStat->mgmtActionRx,
1350 pWifiIfaceStat->mgmtActionTx,
1351 pWifiIfaceStat->rssiMgmt,
1352 pWifiIfaceStat->rssiData,
1353 pWifiIfaceStat->rssiAck );
1354
1355
1356 {
1357 int i;
1358 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1359 {
1360 hddLog(VOS_TRACE_LEVEL_INFO,
1361
1362 " %d) LL_STATS IFACE: "
1363 " ac: %u txMpdu: %u "
1364 " rxMpdu: %u txMcast: %u "
1365 " rxMcast: %u rxAmpdu: %u "
1366 " txAmpdu: %u mpduLost: %u "
1367 " retries: %u retriesShort: %u "
1368 " retriesLong: %u contentionTimeMin: %u "
1369 " contentionTimeMax: %u contentionTimeAvg: %u "
1370 " contentionNumSamples: %u",
1371 i,
1372 pWifiIfaceStat->AccessclassStats[i].ac,
1373 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1374 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1375 pWifiIfaceStat->AccessclassStats[i].txMcast,
1376 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1377 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1378 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1379 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1380 pWifiIfaceStat->AccessclassStats[i].retries,
1381 pWifiIfaceStat->
1382 AccessclassStats[i].retriesShort,
1383 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1384 pWifiIfaceStat->
1385 AccessclassStats[i].contentionTimeMin,
1386 pWifiIfaceStat->
1387 AccessclassStats[i].contentionTimeMax,
1388 pWifiIfaceStat->
1389 AccessclassStats[i].contentionTimeAvg,
1390 pWifiIfaceStat->
1391 AccessclassStats[i].contentionNumSamples);
1392
1393 }
1394 }
1395
Sunil Duttc69bccb2014-05-26 21:30:20 +05301396 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301397
1398 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301399}
1400
1401/*
1402 * hdd_link_layer_process_radio_stats () - This function is called after
1403 * receiving Link Layer Radio statistics from FW.This function converts
1404 * the firmware data to the NL data and sends the same to the kernel/upper
1405 * layers.
1406 */
1407static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1408 v_VOID_t *pData)
1409{
1410 int status, i;
1411 tpSirWifiRadioStat pWifiRadioStat;
1412 tpSirWifiChannelStats pWifiChannelStats;
1413 struct sk_buff *vendor_event;
1414 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1415 struct nlattr *chList;
1416
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301417 ENTER();
1418
Sunil Duttc69bccb2014-05-26 21:30:20 +05301419 status = wlan_hdd_validate_context(pHddCtx);
1420 if (0 != status)
1421 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301422 return;
1423 }
1424 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1425
1426 hddLog(VOS_TRACE_LEVEL_INFO,
1427 "LL_STATS_RADIO"
1428 " radio is %d onTime is %u "
1429 " txTime is %u rxTime is %u "
1430 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301431 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301432 " onTimePnoScan is %u onTimeHs20 is %u "
1433 " numChannels is %u",
1434 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1435 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1436 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301437 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301438 pWifiRadioStat->onTimeRoamScan,
1439 pWifiRadioStat->onTimePnoScan,
1440 pWifiRadioStat->onTimeHs20,
1441 pWifiRadioStat->numChannels);
1442 /*
1443 * Allocate a size of 4096 for the Radio stats comprising
1444 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1445 * (tSirWifiChannelStats).Each channel data is put with an
1446 * NL attribute.The size of 4096 is considered assuming that
1447 * number of channels shall not exceed beyond 60 with the
1448 * sizeof (tSirWifiChannelStats) being 24 bytes.
1449 */
1450
1451 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1452 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1453 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1454 GFP_KERNEL);
1455
1456 if (!vendor_event)
1457 {
1458 hddLog(VOS_TRACE_LEVEL_ERROR,
1459 FL("cfg80211_vendor_event_alloc failed") );
1460 return;
1461 }
1462
1463 if (nla_put_u32(vendor_event,
1464 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1465 pWifiRadioStat->radio) ||
1466 nla_put_u32(vendor_event,
1467 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1468 pWifiRadioStat->onTime) ||
1469 nla_put_u32(vendor_event,
1470 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1471 pWifiRadioStat->txTime) ||
1472 nla_put_u32(vendor_event,
1473 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1474 pWifiRadioStat->rxTime) ||
1475 nla_put_u32(vendor_event,
1476 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1477 pWifiRadioStat->onTimeScan) ||
1478 nla_put_u32(vendor_event,
1479 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1480 pWifiRadioStat->onTimeNbd) ||
1481 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301482 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1483 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301484 nla_put_u32(vendor_event,
1485 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1486 pWifiRadioStat->onTimeRoamScan) ||
1487 nla_put_u32(vendor_event,
1488 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1489 pWifiRadioStat->onTimePnoScan) ||
1490 nla_put_u32(vendor_event,
1491 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1492 pWifiRadioStat->onTimeHs20) ||
1493 nla_put_u32(vendor_event,
1494 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1495 pWifiRadioStat->numChannels))
1496 {
1497 hddLog(VOS_TRACE_LEVEL_ERROR,
1498 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1499 kfree_skb(vendor_event);
1500 return ;
1501 }
1502
1503 chList = nla_nest_start(vendor_event,
1504 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301505 if(!chList)
1506 {
1507 hddLog(VOS_TRACE_LEVEL_ERROR,
1508 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1509 __func__);
1510 kfree_skb(vendor_event);
1511 return;
1512 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301513 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1514 {
1515 struct nlattr *chInfo;
1516
1517 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1518 pWifiRadioStat->channels +
1519 (i * sizeof(tSirWifiChannelStats)));
1520
1521 hddLog(VOS_TRACE_LEVEL_INFO,
1522 " %d) Channel Info"
1523 " width is %u "
1524 " CenterFreq %u "
1525 " CenterFreq0 %u "
1526 " CenterFreq1 %u "
1527 " onTime %u "
1528 " ccaBusyTime %u",
1529 i,
1530 pWifiChannelStats->channel.width,
1531 pWifiChannelStats->channel.centerFreq,
1532 pWifiChannelStats->channel.centerFreq0,
1533 pWifiChannelStats->channel.centerFreq1,
1534 pWifiChannelStats->onTime,
1535 pWifiChannelStats->ccaBusyTime);
1536
1537
1538 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301539 if(!chInfo)
1540 {
1541 hddLog(VOS_TRACE_LEVEL_ERROR,
1542 "%s: failed to put chInfo",
1543 __func__);
1544 kfree_skb(vendor_event);
1545 return;
1546 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301547
1548 if (nla_put_u32(vendor_event,
1549 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1550 pWifiChannelStats->channel.width) ||
1551 nla_put_u32(vendor_event,
1552 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1553 pWifiChannelStats->channel.centerFreq) ||
1554 nla_put_u32(vendor_event,
1555 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1556 pWifiChannelStats->channel.centerFreq0) ||
1557 nla_put_u32(vendor_event,
1558 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1559 pWifiChannelStats->channel.centerFreq1) ||
1560 nla_put_u32(vendor_event,
1561 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1562 pWifiChannelStats->onTime) ||
1563 nla_put_u32(vendor_event,
1564 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1565 pWifiChannelStats->ccaBusyTime))
1566 {
1567 hddLog(VOS_TRACE_LEVEL_ERROR,
1568 FL("cfg80211_vendor_event_alloc failed") );
1569 kfree_skb(vendor_event);
1570 return ;
1571 }
1572 nla_nest_end(vendor_event, chInfo);
1573 }
1574 nla_nest_end(vendor_event, chList);
1575
1576 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301577
1578 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301579 return;
1580}
1581
1582/*
1583 * hdd_link_layer_stats_ind_callback () - This function is called after
1584 * receiving Link Layer indications from FW.This callback converts the firmware
1585 * data to the NL data and send the same to the kernel/upper layers.
1586 */
1587static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1588 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301589 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301590{
Dino Mycled3d50022014-07-07 12:58:25 +05301591 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1592 hdd_adapter_t *pAdapter = NULL;
1593 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301594 int status;
1595
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301596 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301597
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301598 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301599 if (0 != status)
1600 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301601 return;
1602 }
1603
Dino Mycled3d50022014-07-07 12:58:25 +05301604 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1605 if (NULL == pAdapter)
1606 {
1607 hddLog(VOS_TRACE_LEVEL_ERROR,
1608 FL(" MAC address %pM does not exist with host"),
1609 macAddr);
1610 return;
1611 }
1612
Sunil Duttc69bccb2014-05-26 21:30:20 +05301613 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301614 "%s: Interface: %s LLStats indType: %d", __func__,
1615 pAdapter->dev->name, indType);
1616
Sunil Duttc69bccb2014-05-26 21:30:20 +05301617 switch (indType)
1618 {
1619 case SIR_HAL_LL_STATS_RESULTS_RSP:
1620 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301621 hddLog(VOS_TRACE_LEVEL_INFO,
1622 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1623 hddLog(VOS_TRACE_LEVEL_INFO,
1624 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1625 linkLayerStatsResults->paramId);
1626 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301627 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1628 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301629 hddLog(VOS_TRACE_LEVEL_INFO,
1630 "LL_STATS RESULTS RESPONSE respId = %u",
1631 linkLayerStatsResults->respId);
1632 hddLog(VOS_TRACE_LEVEL_INFO,
1633 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1634 linkLayerStatsResults->moreResultToFollow);
1635 hddLog(VOS_TRACE_LEVEL_INFO,
1636 "LL_STATS RESULTS RESPONSE result = %p",
1637 linkLayerStatsResults->result);
1638 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1639 {
1640 hdd_link_layer_process_radio_stats(pAdapter,
1641 (v_VOID_t *)linkLayerStatsResults->result);
1642 }
1643 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1644 {
1645 hdd_link_layer_process_iface_stats(pAdapter,
1646 (v_VOID_t *)linkLayerStatsResults->result);
1647 }
1648 else if ( linkLayerStatsResults->paramId &
1649 WMI_LINK_STATS_ALL_PEER )
1650 {
1651 hdd_link_layer_process_peer_stats(pAdapter,
1652 (v_VOID_t *)linkLayerStatsResults->result);
1653 } /* WMI_LINK_STATS_ALL_PEER */
1654 else
1655 {
1656 hddLog(VOS_TRACE_LEVEL_ERROR,
1657 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1658 }
1659
1660 break;
1661 }
1662 default:
1663 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1664 break;
1665 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301666
1667 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301668 return;
1669}
1670
1671const struct
1672nla_policy
1673qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1674{
1675 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1676 { .type = NLA_U32 },
1677 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1678 { .type = NLA_U32 },
1679};
1680
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301681static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1682 struct wireless_dev *wdev,
1683 const void *data,
1684 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301685{
1686 int status;
1687 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301688 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301689 struct net_device *dev = wdev->netdev;
1690 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1691 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Srinivas Dasari98947432014-11-07 19:41:24 +05301692 hdd_station_ctx_t *pHddStaCtx;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301693
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301694 ENTER();
1695
Sunil Duttc69bccb2014-05-26 21:30:20 +05301696 status = wlan_hdd_validate_context(pHddCtx);
1697 if (0 != status)
1698 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301699 return -EINVAL;
1700 }
1701
1702 if (NULL == pAdapter)
1703 {
1704 hddLog(VOS_TRACE_LEVEL_ERROR,
1705 FL("HDD adapter is Null"));
1706 return -ENODEV;
1707 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301708 /* check the LLStats Capability */
1709 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1710 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1711 {
1712 hddLog(VOS_TRACE_LEVEL_ERROR,
1713 FL("Link Layer Statistics not supported by Firmware"));
1714 return -EINVAL;
1715 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301716
1717 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1718 (struct nlattr *)data,
1719 data_len, qca_wlan_vendor_ll_set_policy))
1720 {
1721 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1722 return -EINVAL;
1723 }
1724 if (!tb_vendor
1725 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1726 {
1727 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1728 return -EINVAL;
1729 }
1730 if (!tb_vendor[
1731 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1732 {
1733 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1734 return -EINVAL;
1735 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301736 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301737 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301738
Dino Mycledf0a5d92014-07-04 09:41:55 +05301739 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301740 nla_get_u32(
1741 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1742
Dino Mycledf0a5d92014-07-04 09:41:55 +05301743 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301744 nla_get_u32(
1745 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1746
Dino Mycled3d50022014-07-07 12:58:25 +05301747 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1748 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301749
1750
1751 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301752 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301753 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301754 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301755 hddLog(VOS_TRACE_LEVEL_INFO,
1756 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301757 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301758 hddLog(VOS_TRACE_LEVEL_INFO,
1759 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301760 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301761
1762 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1763 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301764 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301765 {
1766 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1767 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301768 return -EINVAL;
1769
1770 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301771
1772 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1773 if (VOS_STATUS_SUCCESS !=
1774 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1775 pHddStaCtx->conn_info.staId[0], WIFI_STATS_IFACE))
1776 {
1777 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1778 "WLANTL_ClearInterfaceStats Failed", __func__);
1779 return -EINVAL;
1780 }
1781
1782 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
1783 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
1784 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
1785 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
1786
Sunil Duttc69bccb2014-05-26 21:30:20 +05301787 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301788 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301789 {
1790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1791 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301792 return -EINVAL;
1793 }
1794
1795 pAdapter->isLinkLayerStatsSet = 1;
1796
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301797 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301798 return 0;
1799}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301800static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1801 struct wireless_dev *wdev,
1802 const void *data,
1803 int data_len)
1804{
1805 int ret = 0;
1806
1807 vos_ssr_protect(__func__);
1808 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1809 vos_ssr_unprotect(__func__);
1810
1811 return ret;
1812}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301813
1814const struct
1815nla_policy
1816qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1817{
1818 /* Unsigned 32bit value provided by the caller issuing the GET stats
1819 * command. When reporting
1820 * the stats results, the driver uses the same value to indicate
1821 * which GET request the results
1822 * correspond to.
1823 */
1824 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1825
1826 /* Unsigned 32bit value . bit mask to identify what statistics are
1827 requested for retrieval */
1828 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1829};
1830
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301831static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1832 struct wireless_dev *wdev,
1833 const void *data,
1834 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301835{
1836 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1837 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301838 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301839 struct net_device *dev = wdev->netdev;
1840 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1841 int status;
1842
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301843 ENTER();
1844
Sunil Duttc69bccb2014-05-26 21:30:20 +05301845 status = wlan_hdd_validate_context(pHddCtx);
1846 if (0 != status)
1847 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301848 return -EINVAL ;
1849 }
1850
1851 if (NULL == pAdapter)
1852 {
1853 hddLog(VOS_TRACE_LEVEL_FATAL,
1854 "%s: HDD adapter is Null", __func__);
1855 return -ENODEV;
1856 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301857 /* check the LLStats Capability */
1858 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1859 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1860 {
1861 hddLog(VOS_TRACE_LEVEL_ERROR,
1862 FL("Link Layer Statistics not supported by Firmware"));
1863 return -EINVAL;
1864 }
1865
Sunil Duttc69bccb2014-05-26 21:30:20 +05301866
1867 if (!pAdapter->isLinkLayerStatsSet)
1868 {
1869 hddLog(VOS_TRACE_LEVEL_FATAL,
1870 "%s: isLinkLayerStatsSet : %d",
1871 __func__, pAdapter->isLinkLayerStatsSet);
1872 return -EINVAL;
1873 }
1874
1875 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1876 (struct nlattr *)data,
1877 data_len, qca_wlan_vendor_ll_get_policy))
1878 {
1879 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1880 return -EINVAL;
1881 }
1882
1883 if (!tb_vendor
1884 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1885 {
1886 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1887 return -EINVAL;
1888 }
1889
1890 if (!tb_vendor
1891 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1892 {
1893 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1894 return -EINVAL;
1895 }
1896
Sunil Duttc69bccb2014-05-26 21:30:20 +05301897
Dino Mycledf0a5d92014-07-04 09:41:55 +05301898 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301899 nla_get_u32( tb_vendor[
1900 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301901 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301902 nla_get_u32( tb_vendor[
1903 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1904
Dino Mycled3d50022014-07-07 12:58:25 +05301905 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1906 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301907
1908 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301909 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301910 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301911 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301912 hddLog(VOS_TRACE_LEVEL_INFO,
1913 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301914 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301915
1916 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301917 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301918 {
1919 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1920 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301921 return -EINVAL;
1922 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301923
1924 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301925 return 0;
1926}
1927
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301928static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1929 struct wireless_dev *wdev,
1930 const void *data,
1931 int data_len)
1932{
1933 int ret = 0;
1934
1935 vos_ssr_protect(__func__);
1936 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1937 vos_ssr_unprotect(__func__);
1938
1939 return ret;
1940}
1941
Sunil Duttc69bccb2014-05-26 21:30:20 +05301942const struct
1943nla_policy
1944qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1945{
1946 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1947 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1948 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1949 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1950};
1951
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301952static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1953 struct wireless_dev *wdev,
1954 const void *data,
1955 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301956{
1957 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1958 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301959 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301960 struct net_device *dev = wdev->netdev;
1961 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1962 u32 statsClearReqMask;
1963 u8 stopReq;
1964 int status;
1965
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301966 ENTER();
1967
Sunil Duttc69bccb2014-05-26 21:30:20 +05301968 status = wlan_hdd_validate_context(pHddCtx);
1969 if (0 != status)
1970 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301971 return -EINVAL;
1972 }
1973
1974 if (NULL == pAdapter)
1975 {
1976 hddLog(VOS_TRACE_LEVEL_FATAL,
1977 "%s: HDD adapter is Null", __func__);
1978 return -ENODEV;
1979 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301980 /* check the LLStats Capability */
1981 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1982 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1983 {
1984 hddLog(VOS_TRACE_LEVEL_ERROR,
1985 FL("Enable LLStats Capability"));
1986 return -EINVAL;
1987 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301988
1989 if (!pAdapter->isLinkLayerStatsSet)
1990 {
1991 hddLog(VOS_TRACE_LEVEL_FATAL,
1992 "%s: isLinkLayerStatsSet : %d",
1993 __func__, pAdapter->isLinkLayerStatsSet);
1994 return -EINVAL;
1995 }
1996
1997 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1998 (struct nlattr *)data,
1999 data_len, qca_wlan_vendor_ll_clr_policy))
2000 {
2001 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2002 return -EINVAL;
2003 }
2004
2005 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2006
2007 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2008 {
2009 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2010 return -EINVAL;
2011
2012 }
2013
Sunil Duttc69bccb2014-05-26 21:30:20 +05302014
Dino Mycledf0a5d92014-07-04 09:41:55 +05302015 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302016 nla_get_u32(
2017 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2018
Dino Mycledf0a5d92014-07-04 09:41:55 +05302019 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302020 nla_get_u8(
2021 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2022
2023 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302024 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302025
Dino Mycled3d50022014-07-07 12:58:25 +05302026 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2027 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302028
2029 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302030 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302031 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302032 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302033 hddLog(VOS_TRACE_LEVEL_INFO,
2034 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302035 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302036 hddLog(VOS_TRACE_LEVEL_INFO,
2037 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302038 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302039
2040 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302041 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302042 {
2043 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302044 hdd_station_ctx_t *pHddStaCtx;
2045
2046 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2047 if (VOS_STATUS_SUCCESS !=
2048 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2049 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2050 {
2051 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2052 "WLANTL_ClearInterfaceStats Failed", __func__);
2053 return -EINVAL;
2054 }
2055 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2056 (statsClearReqMask & WIFI_STATS_IFACE)) {
2057 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2058 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2059 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2060 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2061 }
2062
Sunil Duttc69bccb2014-05-26 21:30:20 +05302063 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2064 2 * sizeof(u32) +
2065 NLMSG_HDRLEN);
2066
2067 if (temp_skbuff != NULL)
2068 {
2069
2070 if (nla_put_u32(temp_skbuff,
2071 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2072 statsClearReqMask) ||
2073 nla_put_u32(temp_skbuff,
2074 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2075 stopReq))
2076 {
2077 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2078 kfree_skb(temp_skbuff);
2079 return -EINVAL;
2080 }
2081 /* If the ask is to stop the stats collection as part of clear
2082 * (stopReq = 1) , ensure that no further requests of get
2083 * go to the firmware by having isLinkLayerStatsSet set to 0.
2084 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302085 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302086 * case the firmware is just asked to clear the statistics.
2087 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302088 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302089 pAdapter->isLinkLayerStatsSet = 0;
2090 return cfg80211_vendor_cmd_reply(temp_skbuff);
2091 }
2092 return -ENOMEM;
2093 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302094
2095 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302096 return -EINVAL;
2097}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302098static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2099 struct wireless_dev *wdev,
2100 const void *data,
2101 int data_len)
2102{
2103 int ret = 0;
2104
2105 vos_ssr_protect(__func__);
2106 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2107 vos_ssr_unprotect(__func__);
2108
2109 return ret;
2110
2111
2112}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302113#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2114
Dino Mycle6fb96c12014-06-10 11:52:40 +05302115#ifdef WLAN_FEATURE_EXTSCAN
2116static const struct nla_policy
2117wlan_hdd_extscan_config_policy
2118 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2119{
2120 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2121 { .type = NLA_U32 },
2122 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2123 { .type = NLA_U32 },
2124 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2125 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2126 { .type = NLA_U32 },
2127 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2128 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2129
2130 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2131 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2132 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2133 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2134 { .type = NLA_U8 },
2135 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2136 { .type = NLA_U32 },
2137 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2138 { .type = NLA_U32 },
2139 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2140 { .type = NLA_U32 },
2141 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
2142 { .type = NLA_U8 },
2143 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2144 { .type = NLA_U8 },
2145 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2146 { .type = NLA_U8 },
2147
2148 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2149 { .type = NLA_U32 },
2150 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2151 { .type = NLA_UNSPEC },
2152 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2153 { .type = NLA_S32 },
2154 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2155 { .type = NLA_S32 },
2156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2157 { .type = NLA_U32 },
2158 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2159 { .type = NLA_U32 },
2160 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2161 { .type = NLA_U32 },
2162 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2163 = { .type = NLA_U32 },
2164 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2165 { .type = NLA_U32 },
2166 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2167 NLA_U32 },
2168};
2169
2170static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
2171{
2172 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2173 struct sk_buff *skb = NULL;
2174 tpSirEXTScanCapabilitiesEvent pData =
2175 (tpSirEXTScanCapabilitiesEvent) pMsg;
2176
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302177 ENTER();
2178
2179 if (wlan_hdd_validate_context(pHddCtx))
2180 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302181 return;
2182 }
2183
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302184 if (!pMsg)
2185 {
2186 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2187 return;
2188 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302189 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2190 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2191 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
2192 GFP_KERNEL);
2193
2194 if (!skb) {
2195 hddLog(VOS_TRACE_LEVEL_ERROR,
2196 FL("cfg80211_vendor_event_alloc failed"));
2197 return;
2198 }
2199
2200 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2201 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
2202 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
2203 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
2204 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
2205 pData->maxRssiSampleSize);
2206 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
2207 pData->maxScanReportingThreshold);
2208 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
2209 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
2210 pData->maxSignificantWifiChangeAPs);
2211 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
2212 pData->maxBsidHistoryEntries);
2213
2214 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2215 pData->requestId) ||
2216 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
2217 nla_put_u32(skb,
2218 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
2219 pData->scanCacheSize) ||
2220 nla_put_u32(skb,
2221 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
2222 pData->scanBuckets) ||
2223 nla_put_u32(skb,
2224 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
2225 pData->maxApPerScan) ||
2226 nla_put_u32(skb,
2227 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
2228 pData->maxRssiSampleSize) ||
2229 nla_put_u32(skb,
2230 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
2231 pData->maxScanReportingThreshold) ||
2232 nla_put_u32(skb,
2233 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
2234 pData->maxHotlistAPs) ||
2235 nla_put_u32(skb,
2236 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
2237 pData->maxSignificantWifiChangeAPs) ||
2238 nla_put_u32(skb,
2239 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2240 pData->maxBsidHistoryEntries)) {
2241 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2242 goto nla_put_failure;
2243 }
2244
2245 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302246 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302247 return;
2248
2249nla_put_failure:
2250 kfree_skb(skb);
2251 return;
2252}
2253
2254
2255static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2256{
2257 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2258 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2259 struct sk_buff *skb = NULL;
2260 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2261
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302262 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302263
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302264 if (wlan_hdd_validate_context(pHddCtx)){
2265 return;
2266 }
2267 if (!pMsg)
2268 {
2269 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302270 return;
2271 }
2272
2273 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2274 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2275 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2276 GFP_KERNEL);
2277
2278 if (!skb) {
2279 hddLog(VOS_TRACE_LEVEL_ERROR,
2280 FL("cfg80211_vendor_event_alloc failed"));
2281 return;
2282 }
2283 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2284 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2285 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2286
2287 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2288 pData->requestId) ||
2289 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2290 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2291 goto nla_put_failure;
2292 }
2293
2294 /*
2295 * Store the Request ID for comparing with the requestID obtained
2296 * in other requests.HDD shall return a failure is the extscan_stop
2297 * request is issued with a different requestId as that of the
2298 * extscan_start request. Also, This requestId shall be used while
2299 * indicating the full scan results to the upper layers.
2300 * The requestId is stored with the assumption that the firmware
2301 * shall return the ext scan start request's requestId in ext scan
2302 * start response.
2303 */
2304 if (pData->status == 0)
2305 pMac->sme.extScanStartReqId = pData->requestId;
2306
2307
2308 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302309 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302310 return;
2311
2312nla_put_failure:
2313 kfree_skb(skb);
2314 return;
2315}
2316
2317
2318static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2319{
2320 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2321 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2322 struct sk_buff *skb = NULL;
2323
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302324 ENTER();
2325
2326 if (wlan_hdd_validate_context(pHddCtx)){
2327 return;
2328 }
2329 if (!pMsg)
2330 {
2331 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302332 return;
2333 }
2334
2335 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2336 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2337 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2338 GFP_KERNEL);
2339
2340 if (!skb) {
2341 hddLog(VOS_TRACE_LEVEL_ERROR,
2342 FL("cfg80211_vendor_event_alloc failed"));
2343 return;
2344 }
2345 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2346 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2347
2348 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2349 pData->requestId) ||
2350 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2352 goto nla_put_failure;
2353 }
2354
2355 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302356 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302357 return;
2358
2359nla_put_failure:
2360 kfree_skb(skb);
2361 return;
2362}
2363
2364
2365static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2366 void *pMsg)
2367{
2368 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2369 struct sk_buff *skb = NULL;
2370 tpSirEXTScanSetBssidHotListRspParams pData =
2371 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2372
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302373 ENTER();
2374
2375 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302376 return;
2377 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302378 if (!pMsg)
2379 {
2380 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2381 return;
2382 }
2383
Dino Mycle6fb96c12014-06-10 11:52:40 +05302384 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2385 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2386 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2387 GFP_KERNEL);
2388
2389 if (!skb) {
2390 hddLog(VOS_TRACE_LEVEL_ERROR,
2391 FL("cfg80211_vendor_event_alloc failed"));
2392 return;
2393 }
2394 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2395 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2396 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2397
2398 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2399 pData->requestId) ||
2400 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2401 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2402 goto nla_put_failure;
2403 }
2404
2405 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302406 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302407 return;
2408
2409nla_put_failure:
2410 kfree_skb(skb);
2411 return;
2412}
2413
2414static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2415 void *pMsg)
2416{
2417 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2418 struct sk_buff *skb = NULL;
2419 tpSirEXTScanResetBssidHotlistRspParams pData =
2420 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2421
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302422 ENTER();
2423
2424 if (wlan_hdd_validate_context(pHddCtx)) {
2425 return;
2426 }
2427 if (!pMsg)
2428 {
2429 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302430 return;
2431 }
2432
2433 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2434 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2435 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2436 GFP_KERNEL);
2437
2438 if (!skb) {
2439 hddLog(VOS_TRACE_LEVEL_ERROR,
2440 FL("cfg80211_vendor_event_alloc failed"));
2441 return;
2442 }
2443 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2444 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2445
2446 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2447 pData->requestId) ||
2448 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2449 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2450 goto nla_put_failure;
2451 }
2452
2453 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302454 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302455 return;
2456
2457nla_put_failure:
2458 kfree_skb(skb);
2459 return;
2460}
2461
2462
2463static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2464 void *pMsg)
2465{
2466 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2467 struct sk_buff *skb = NULL;
2468 tpSirEXTScanSetSignificantChangeRspParams pData =
2469 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2470
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302471 ENTER();
2472
2473 if (wlan_hdd_validate_context(pHddCtx)) {
2474 return;
2475 }
2476 if (!pMsg)
2477 {
2478 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302479 return;
2480 }
2481
2482 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2483 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2484 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2485 GFP_KERNEL);
2486
2487 if (!skb) {
2488 hddLog(VOS_TRACE_LEVEL_ERROR,
2489 FL("cfg80211_vendor_event_alloc failed"));
2490 return;
2491 }
2492 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2493 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2494 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2495
2496 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2497 pData->requestId) ||
2498 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2499 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2500 goto nla_put_failure;
2501 }
2502
2503 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302504 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302505 return;
2506
2507nla_put_failure:
2508 kfree_skb(skb);
2509 return;
2510}
2511
2512
2513static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2514 void *pMsg)
2515{
2516 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2517 struct sk_buff *skb = NULL;
2518 tpSirEXTScanResetSignificantChangeRspParams pData =
2519 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2520
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302521 ENTER();
2522
2523 if (wlan_hdd_validate_context(pHddCtx)) {
2524 return;
2525 }
2526 if (!pMsg)
2527 {
2528 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302529 return;
2530 }
2531
2532 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2533 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2534 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2535 GFP_KERNEL);
2536
2537 if (!skb) {
2538 hddLog(VOS_TRACE_LEVEL_ERROR,
2539 FL("cfg80211_vendor_event_alloc failed"));
2540 return;
2541 }
2542 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2543 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2544 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2545
2546 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2547 pData->requestId) ||
2548 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2549 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2550 goto nla_put_failure;
2551 }
2552
2553 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302554 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302555 return;
2556
2557nla_put_failure:
2558 kfree_skb(skb);
2559 return;
2560}
2561
2562static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2563 void *pMsg)
2564{
2565 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2566 struct sk_buff *skb = NULL;
2567 tANI_U32 i = 0, j, resultsPerEvent;
2568 tANI_S32 totalResults;
2569 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2570 tpSirWifiScanResult pSirWifiScanResult;
2571
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302572 ENTER();
2573
2574 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302575 return;
2576 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302577 if (!pMsg)
2578 {
2579 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2580 return;
2581 }
2582
Dino Mycle6fb96c12014-06-10 11:52:40 +05302583 totalResults = pData->numOfAps;
2584 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2585 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2586 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2587
2588 do{
2589 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2590 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2591 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2592
2593 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2594 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2595 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2596 GFP_KERNEL);
2597
2598 if (!skb) {
2599 hddLog(VOS_TRACE_LEVEL_ERROR,
2600 FL("cfg80211_vendor_event_alloc failed"));
2601 return;
2602 }
2603
2604 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2605
2606 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2607 pData->requestId) ||
2608 nla_put_u32(skb,
2609 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2610 resultsPerEvent)) {
2611 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2612 goto fail;
2613 }
2614 if (nla_put_u8(skb,
2615 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2616 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2617 {
2618 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2619 goto fail;
2620 }
2621
2622 if (resultsPerEvent) {
2623 struct nlattr *aps;
2624
2625 aps = nla_nest_start(skb,
2626 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2627 if (!aps)
2628 {
2629 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2630 goto fail;
2631 }
2632
2633 for (j = 0; j < resultsPerEvent; j++, i++) {
2634 struct nlattr *ap;
2635 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2636 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2637
2638 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2639 "Ssid (%s)"
2640 "Bssid: %pM "
2641 "Channel (%u)"
2642 "Rssi (%d)"
2643 "RTT (%u)"
2644 "RTT_SD (%u)",
2645 i,
2646 pSirWifiScanResult->ts,
2647 pSirWifiScanResult->ssid,
2648 pSirWifiScanResult->bssid,
2649 pSirWifiScanResult->channel,
2650 pSirWifiScanResult->rssi,
2651 pSirWifiScanResult->rtt,
2652 pSirWifiScanResult->rtt_sd);
2653
2654 ap = nla_nest_start(skb, j + 1);
2655 if (!ap)
2656 {
2657 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2658 goto fail;
2659 }
2660
2661 if (nla_put_u64(skb,
2662 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2663 pSirWifiScanResult->ts) )
2664 {
2665 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2666 goto fail;
2667 }
2668 if (nla_put(skb,
2669 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2670 sizeof(pSirWifiScanResult->ssid),
2671 pSirWifiScanResult->ssid) )
2672 {
2673 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2674 goto fail;
2675 }
2676 if (nla_put(skb,
2677 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2678 sizeof(pSirWifiScanResult->bssid),
2679 pSirWifiScanResult->bssid) )
2680 {
2681 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2682 goto fail;
2683 }
2684 if (nla_put_u32(skb,
2685 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2686 pSirWifiScanResult->channel) )
2687 {
2688 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2689 goto fail;
2690 }
Dasari Srinivas90747d72014-10-08 12:16:15 +05302691 if (nla_put_s32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302692 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2693 pSirWifiScanResult->rssi) )
2694 {
2695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2696 goto fail;
2697 }
2698 if (nla_put_u32(skb,
2699 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2700 pSirWifiScanResult->rtt) )
2701 {
2702 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2703 goto fail;
2704 }
2705 if (nla_put_u32(skb,
2706 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2707 pSirWifiScanResult->rtt_sd))
2708 {
2709 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2710 goto fail;
2711 }
2712
2713 nla_nest_end(skb, ap);
2714 }
2715 nla_nest_end(skb, aps);
2716
2717 }
2718 cfg80211_vendor_event(skb, GFP_KERNEL);
2719 } while (totalResults > 0);
2720
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302721 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302722 return;
2723fail:
2724 kfree_skb(skb);
2725 return;
2726}
2727
2728static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2729 void *pMsg)
2730{
2731 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2732 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2733 struct sk_buff *skb = NULL;
2734 tANI_U32 i;
2735
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302736 ENTER();
2737
2738 if (wlan_hdd_validate_context(pHddCtx)) {
2739 return;
2740 }
2741 if (!pMsg)
2742 {
2743 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302744 return;
2745 }
2746
2747 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2748 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2749 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2750 GFP_KERNEL);
2751
2752 if (!skb) {
2753 hddLog(VOS_TRACE_LEVEL_ERROR,
2754 FL("cfg80211_vendor_event_alloc failed"));
2755 return;
2756 }
2757 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2758 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2759 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2760 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2761
2762 for (i = 0; i < pData->numOfAps; i++) {
2763 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2764 "Ssid (%s) "
2765 "Bssid (" MAC_ADDRESS_STR ") "
2766 "Channel (%u) "
2767 "Rssi (%d) "
2768 "RTT (%u) "
2769 "RTT_SD (%u) ",
2770 i,
2771 pData->ap[i].ts,
2772 pData->ap[i].ssid,
2773 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2774 pData->ap[i].channel,
2775 pData->ap[i].rssi,
2776 pData->ap[i].rtt,
2777 pData->ap[i].rtt_sd);
2778 }
2779
2780 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2781 pData->requestId) ||
2782 nla_put_u32(skb,
2783 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2784 pData->numOfAps)) {
2785 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2786 goto fail;
2787 }
2788 if (pData->numOfAps) {
2789 struct nlattr *aps;
2790
2791 aps = nla_nest_start(skb,
2792 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2793 if (!aps)
2794 goto fail;
2795
2796 for (i = 0; i < pData->numOfAps; i++) {
2797 struct nlattr *ap;
2798
2799 ap = nla_nest_start(skb, i + 1);
2800 if (!ap)
2801 goto fail;
2802
2803 if (nla_put_u64(skb,
2804 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2805 pData->ap[i].ts) ||
2806 nla_put(skb,
2807 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2808 sizeof(pData->ap[i].ssid),
2809 pData->ap[i].ssid) ||
2810 nla_put(skb,
2811 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2812 sizeof(pData->ap[i].bssid),
2813 pData->ap[i].bssid) ||
2814 nla_put_u32(skb,
2815 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2816 pData->ap[i].channel) ||
2817 nla_put_s32(skb,
2818 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2819 pData->ap[i].rssi) ||
2820 nla_put_u32(skb,
2821 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2822 pData->ap[i].rtt) ||
2823 nla_put_u32(skb,
2824 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2825 pData->ap[i].rtt_sd))
2826 goto fail;
2827
2828 nla_nest_end(skb, ap);
2829 }
2830 nla_nest_end(skb, aps);
2831
2832 if (nla_put_u8(skb,
2833 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2834 pData->moreData))
2835 goto fail;
2836 }
2837
2838 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302839 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302840 return;
2841
2842fail:
2843 kfree_skb(skb);
2844 return;
2845
2846}
2847static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2848 void *pMsg)
2849{
2850 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2851 struct sk_buff *skb = NULL;
2852 tANI_U32 i, j;
2853 tpSirWifiSignificantChangeEvent pData =
2854 (tpSirWifiSignificantChangeEvent) pMsg;
2855
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302856 ENTER();
2857
2858 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302859 return;
2860 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302861 if (!pMsg)
2862 {
2863 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2864 return;
2865 }
2866
Dino Mycle6fb96c12014-06-10 11:52:40 +05302867 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2868 EXTSCAN_EVENT_BUF_SIZE,
2869 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2870 GFP_KERNEL);
2871
2872 if (!skb) {
2873 hddLog(VOS_TRACE_LEVEL_ERROR,
2874 FL("cfg80211_vendor_event_alloc failed"));
2875 return;
2876 }
2877 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2878 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2879 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2880 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2881 pData->numSigRssiBss);
2882 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2883
2884 for (i = 0; i < pData->numSigRssiBss; i++) {
2885 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2886 " num RSSI %u ",
2887 i, pData->sigRssiResult[i].bssid,
2888 pData->sigRssiResult[i].channel,
2889 pData->sigRssiResult[i].numRssi);
2890
2891 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2892
2893 hddLog(VOS_TRACE_LEVEL_INFO,
2894 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05302895 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302896
2897 }
2898 }
2899
2900
2901 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2902 pData->requestId) ||
2903 nla_put_u32(skb,
2904 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2905 pData->numSigRssiBss)) {
2906 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2907 goto fail;
2908 }
2909
2910 if (pData->numSigRssiBss) {
2911 struct nlattr *aps;
2912 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2913 if (!aps)
2914 goto fail;
2915 for (i = 0; i < pData->numSigRssiBss; i++) {
2916 struct nlattr *ap;
2917
2918 ap = nla_nest_start(skb, i);
2919 if (!ap)
2920 goto fail;
2921 if (nla_put(skb,
2922 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2923 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2924 nla_put_u32(skb,
2925 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2926 pData->sigRssiResult[i].channel) ||
2927 nla_put_u32(skb,
2928 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2929 pData->sigRssiResult[i].numRssi) ||
2930 nla_put(skb,
2931 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2932 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2933 pData->sigRssiResult[i].rssi))
2934 goto fail;
2935 nla_nest_end(skb, ap);
2936 }
2937 nla_nest_end(skb, aps);
2938 if (nla_put_u8(skb,
2939 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2940 pData->moreData))
2941 goto fail;
2942 }
2943 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302944 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302945 return;
2946fail:
2947 kfree_skb(skb);
2948 return;
2949}
2950
2951static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2952 void *pMsg)
2953{
2954 struct sk_buff *skb;
2955 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2956 tpSirWifiFullScanResultEvent pData =
2957 (tpSirWifiFullScanResultEvent) (pMsg);
2958
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302959 ENTER();
2960
2961 if (wlan_hdd_validate_context(pHddCtx)) {
2962 return;
2963 }
2964 if (!pMsg)
2965 {
2966 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302967 return;
2968 }
2969
2970 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2971 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2972 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2973 GFP_KERNEL);
2974
2975 if (!skb) {
2976 hddLog(VOS_TRACE_LEVEL_ERROR,
2977 FL("cfg80211_vendor_event_alloc failed"));
2978 return;
2979 }
2980
2981 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2982 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2983 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2984 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2985 "Ssid (%s)"
2986 "Bssid (" MAC_ADDRESS_STR ")"
2987 "Channel (%u)"
2988 "Rssi (%d)"
2989 "RTT (%u)"
2990 "RTT_SD (%u)"),
2991 pData->ap.ts,
2992 pData->ap.ssid,
2993 MAC_ADDR_ARRAY(pData->ap.bssid),
2994 pData->ap.channel,
2995 pData->ap.rssi,
2996 pData->ap.rtt,
2997 pData->ap.rtt_sd);
2998 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2999 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3000 pData->requestId) ||
3001 nla_put_u64(skb,
3002 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3003 pData->ap.ts) ||
3004 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3005 sizeof(pData->ap.ssid),
3006 pData->ap.ssid) ||
3007 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3008 WNI_CFG_BSSID_LEN,
3009 pData->ap.bssid) ||
3010 nla_put_u32(skb,
3011 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3012 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303013 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303014 pData->ap.rssi) ||
3015 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3016 pData->ap.rtt) ||
3017 nla_put_u32(skb,
3018 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3019 pData->ap.rtt_sd) ||
3020 nla_put_u16(skb,
3021 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3022 pData->ap.beaconPeriod) ||
3023 nla_put_u16(skb,
3024 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3025 pData->ap.capability) ||
3026 nla_put_u32(skb,
3027 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3028 pData->ieLength))
3029 {
3030 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3031 goto nla_put_failure;
3032 }
3033 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3034 pData->ieLength,
3035 pData->ie))
3036 {
3037 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3038 goto nla_put_failure;
3039 }
3040
3041 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303042 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303043 return;
3044
3045nla_put_failure:
3046 kfree_skb(skb);
3047 return;
3048}
3049
3050static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3051 void *pMsg)
3052{
3053 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3054 struct sk_buff *skb = NULL;
3055 tpSirEXTScanResultsAvailableIndParams pData =
3056 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3057
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303058 ENTER();
3059
3060 if (wlan_hdd_validate_context(pHddCtx)){
3061 return;
3062 }
3063 if (!pMsg)
3064 {
3065 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303066 return;
3067 }
3068
3069 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
3070 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3071 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3072 GFP_KERNEL);
3073
3074 if (!skb) {
3075 hddLog(VOS_TRACE_LEVEL_ERROR,
3076 FL("cfg80211_vendor_event_alloc failed"));
3077 return;
3078 }
3079
3080 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3081 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3082 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3083 pData->numResultsAvailable);
3084 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3085 pData->requestId) ||
3086 nla_put_u32(skb,
3087 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3088 pData->numResultsAvailable)) {
3089 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3090 goto nla_put_failure;
3091 }
3092
3093 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303094 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303095 return;
3096
3097nla_put_failure:
3098 kfree_skb(skb);
3099 return;
3100}
3101
3102static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3103{
3104 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3105 struct sk_buff *skb = NULL;
3106 tpSirEXTScanProgressIndParams pData =
3107 (tpSirEXTScanProgressIndParams) pMsg;
3108
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303109 ENTER();
3110
3111 if (wlan_hdd_validate_context(pHddCtx)){
3112 return;
3113 }
3114 if (!pMsg)
3115 {
3116 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303117 return;
3118 }
3119
3120 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
3121 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3122 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3123 GFP_KERNEL);
3124
3125 if (!skb) {
3126 hddLog(VOS_TRACE_LEVEL_ERROR,
3127 FL("cfg80211_vendor_event_alloc failed"));
3128 return;
3129 }
3130 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3131 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3132 pData->extScanEventType);
3133 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3134 pData->status);
3135
3136 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3137 pData->extScanEventType) ||
3138 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303139 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3140 pData->requestId) ||
3141 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303142 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3143 pData->status)) {
3144 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3145 goto nla_put_failure;
3146 }
3147
3148 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303149 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303150 return;
3151
3152nla_put_failure:
3153 kfree_skb(skb);
3154 return;
3155}
3156
3157void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3158 void *pMsg)
3159{
3160 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3161
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303162 ENTER();
3163
Dino Mycle6fb96c12014-06-10 11:52:40 +05303164 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303165 return;
3166 }
3167
3168 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3169
3170
3171 switch(evType) {
3172 case SIR_HAL_EXTSCAN_START_RSP:
3173 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3174 break;
3175
3176 case SIR_HAL_EXTSCAN_STOP_RSP:
3177 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3178 break;
3179 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3180 /* There is no need to send this response to upper layer
3181 Just log the message */
3182 hddLog(VOS_TRACE_LEVEL_INFO,
3183 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3184 break;
3185 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3186 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3187 break;
3188
3189 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3190 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3191 break;
3192
3193 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
3194 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
3195 break;
3196
3197 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
3198 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
3199 break;
3200 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
3201 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
3202 break;
3203 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3204 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3205 break;
3206 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3207 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3208 break;
3209 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3210 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3211 break;
3212 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3213 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3214 break;
3215 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
3216 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
3217 break;
3218 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3219 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3220 break;
3221 default:
3222 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3223 break;
3224 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303225 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303226}
3227
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303228static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3229 struct wireless_dev *wdev,
3230 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303231{
Dino Myclee8843b32014-07-04 14:21:45 +05303232 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303233 struct net_device *dev = wdev->netdev;
3234 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3235 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3236 struct nlattr
3237 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3238 eHalStatus status;
3239
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303240 ENTER();
3241
Dino Mycle6fb96c12014-06-10 11:52:40 +05303242 status = wlan_hdd_validate_context(pHddCtx);
3243 if (0 != status)
3244 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303245 return -EINVAL;
3246 }
Dino Myclee8843b32014-07-04 14:21:45 +05303247 /* check the EXTScan Capability */
3248 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3249 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3250 {
3251 hddLog(VOS_TRACE_LEVEL_ERROR,
3252 FL("EXTScan not enabled/supported by Firmware"));
3253 return -EINVAL;
3254 }
3255
Dino Mycle6fb96c12014-06-10 11:52:40 +05303256 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3257 data, dataLen,
3258 wlan_hdd_extscan_config_policy)) {
3259 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3260 return -EINVAL;
3261 }
3262
3263 /* Parse and fetch request Id */
3264 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3265 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3266 return -EINVAL;
3267 }
3268
Dino Mycle6fb96c12014-06-10 11:52:40 +05303269
Dino Myclee8843b32014-07-04 14:21:45 +05303270 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303271 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303272 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303273
Dino Myclee8843b32014-07-04 14:21:45 +05303274 reqMsg.sessionId = pAdapter->sessionId;
3275 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303276
Dino Myclee8843b32014-07-04 14:21:45 +05303277 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303278 if (!HAL_STATUS_SUCCESS(status)) {
3279 hddLog(VOS_TRACE_LEVEL_ERROR,
3280 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303281 return -EINVAL;
3282 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303283 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303284 return 0;
3285}
3286
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303287static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3288 struct wireless_dev *wdev,
3289 const void *data, int dataLen)
3290{
3291 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303292
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303293 vos_ssr_protect(__func__);
3294 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3295 vos_ssr_unprotect(__func__);
3296
3297 return ret;
3298}
3299
3300static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3301 struct wireless_dev *wdev,
3302 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303303{
Dino Myclee8843b32014-07-04 14:21:45 +05303304 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303305 struct net_device *dev = wdev->netdev;
3306 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3307 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3308 struct nlattr
3309 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3310 eHalStatus status;
3311
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303312 ENTER();
3313
Dino Mycle6fb96c12014-06-10 11:52:40 +05303314 status = wlan_hdd_validate_context(pHddCtx);
3315 if (0 != status)
3316 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303317 return -EINVAL;
3318 }
Dino Myclee8843b32014-07-04 14:21:45 +05303319 /* check the EXTScan Capability */
3320 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3321 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3322 {
3323 hddLog(VOS_TRACE_LEVEL_ERROR,
3324 FL("EXTScan not enabled/supported by Firmware"));
3325 return -EINVAL;
3326 }
3327
Dino Mycle6fb96c12014-06-10 11:52:40 +05303328 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3329 data, dataLen,
3330 wlan_hdd_extscan_config_policy)) {
3331 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3332 return -EINVAL;
3333 }
3334 /* Parse and fetch request Id */
3335 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3337 return -EINVAL;
3338 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303339
Dino Myclee8843b32014-07-04 14:21:45 +05303340 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303341 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3342
Dino Myclee8843b32014-07-04 14:21:45 +05303343 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303344
Dino Myclee8843b32014-07-04 14:21:45 +05303345 reqMsg.sessionId = pAdapter->sessionId;
3346 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303347
3348 /* Parse and fetch flush parameter */
3349 if (!tb
3350 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3351 {
3352 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3353 goto failed;
3354 }
Dino Myclee8843b32014-07-04 14:21:45 +05303355 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303356 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3357
Dino Myclee8843b32014-07-04 14:21:45 +05303358 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303359
Dino Myclee8843b32014-07-04 14:21:45 +05303360 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303361 if (!HAL_STATUS_SUCCESS(status)) {
3362 hddLog(VOS_TRACE_LEVEL_ERROR,
3363 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303364 return -EINVAL;
3365 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303366 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303367 return 0;
3368
3369failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303370 return -EINVAL;
3371}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303372static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3373 struct wireless_dev *wdev,
3374 const void *data, int dataLen)
3375{
3376 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303377
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303378 vos_ssr_protect(__func__);
3379 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3380 vos_ssr_unprotect(__func__);
3381
3382 return ret;
3383}
3384
3385static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303386 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303387 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303388{
3389 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3390 struct net_device *dev = wdev->netdev;
3391 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3392 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3393 struct nlattr
3394 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3395 struct nlattr
3396 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3397 struct nlattr *apTh;
3398 eHalStatus status;
3399 tANI_U8 i = 0;
3400 int rem;
3401
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303402 ENTER();
3403
Dino Mycle6fb96c12014-06-10 11:52:40 +05303404 status = wlan_hdd_validate_context(pHddCtx);
3405 if (0 != status)
3406 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303407 return -EINVAL;
3408 }
Dino Myclee8843b32014-07-04 14:21:45 +05303409 /* check the EXTScan Capability */
3410 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3411 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3412 {
3413 hddLog(VOS_TRACE_LEVEL_ERROR,
3414 FL("EXTScan not enabled/supported by Firmware"));
3415 return -EINVAL;
3416 }
3417
Dino Mycle6fb96c12014-06-10 11:52:40 +05303418 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3419 data, dataLen,
3420 wlan_hdd_extscan_config_policy)) {
3421 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3422 return -EINVAL;
3423 }
3424
3425 /* Parse and fetch request Id */
3426 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3427 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3428 return -EINVAL;
3429 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303430 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3431 vos_mem_malloc(sizeof(*pReqMsg));
3432 if (!pReqMsg) {
3433 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3434 return -ENOMEM;
3435 }
3436
Dino Myclee8843b32014-07-04 14:21:45 +05303437
Dino Mycle6fb96c12014-06-10 11:52:40 +05303438 pReqMsg->requestId = nla_get_u32(
3439 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3440 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3441
3442 /* Parse and fetch number of APs */
3443 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3444 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3445 goto fail;
3446 }
3447
3448 pReqMsg->sessionId = pAdapter->sessionId;
3449 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3450
3451 pReqMsg->numAp = nla_get_u32(
3452 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3453 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3454
3455 nla_for_each_nested(apTh,
3456 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3457 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3458 nla_data(apTh), nla_len(apTh),
3459 NULL)) {
3460 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3461 goto fail;
3462 }
3463
3464 /* Parse and fetch MAC address */
3465 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3467 goto fail;
3468 }
3469 memcpy(pReqMsg->ap[i].bssid, nla_data(
3470 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3471 sizeof(tSirMacAddr));
3472 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3473
3474 /* Parse and fetch low RSSI */
3475 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3476 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3477 goto fail;
3478 }
3479 pReqMsg->ap[i].low = nla_get_s32(
3480 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3481 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3482
3483 /* Parse and fetch high RSSI */
3484 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3485 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3486 goto fail;
3487 }
3488 pReqMsg->ap[i].high = nla_get_s32(
3489 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3490 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3491 pReqMsg->ap[i].high);
3492
3493 /* Parse and fetch channel */
3494 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3495 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3496 goto fail;
3497 }
3498 pReqMsg->ap[i].channel = nla_get_u32(
3499 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3500 hddLog(VOS_TRACE_LEVEL_INFO,
3501 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3502 i++;
3503 }
3504 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3505 if (!HAL_STATUS_SUCCESS(status)) {
3506 hddLog(VOS_TRACE_LEVEL_ERROR,
3507 FL("sme_SetBssHotlist failed(err=%d)"), status);
3508 vos_mem_free(pReqMsg);
3509 return -EINVAL;
3510 }
3511
Dino Myclee8843b32014-07-04 14:21:45 +05303512 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303513 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303514 return 0;
3515
3516fail:
3517 vos_mem_free(pReqMsg);
3518 return -EINVAL;
3519}
3520
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303521static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3522 struct wireless_dev *wdev,
3523 const void *data, int dataLen)
3524{
3525 int ret = 0;
3526
3527 vos_ssr_protect(__func__);
3528 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3529 dataLen);
3530 vos_ssr_unprotect(__func__);
3531
3532 return ret;
3533}
3534
3535static int __wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303536 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303537 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303538{
3539 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3540 struct net_device *dev = wdev->netdev;
3541 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3542 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3543 struct nlattr
3544 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3545 struct nlattr
3546 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3547 struct nlattr *apTh;
3548 eHalStatus status;
3549 int i = 0;
3550 int rem;
3551
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303552 ENTER();
3553
Dino Mycle6fb96c12014-06-10 11:52:40 +05303554 status = wlan_hdd_validate_context(pHddCtx);
3555 if (0 != status)
3556 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303557 return -EINVAL;
3558 }
Dino Myclee8843b32014-07-04 14:21:45 +05303559 /* check the EXTScan Capability */
3560 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3561 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3562 {
3563 hddLog(VOS_TRACE_LEVEL_ERROR,
3564 FL("EXTScan not enabled/supported by Firmware"));
3565 return -EINVAL;
3566 }
3567
Dino Mycle6fb96c12014-06-10 11:52:40 +05303568 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3569 data, dataLen,
3570 wlan_hdd_extscan_config_policy)) {
3571 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3572 return -EINVAL;
3573 }
3574
3575 /* Parse and fetch request Id */
3576 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3577 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3578 return -EINVAL;
3579 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303580 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303581 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303582 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303583 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3584 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303585 }
3586
Dino Myclee8843b32014-07-04 14:21:45 +05303587
3588
Dino Mycle6fb96c12014-06-10 11:52:40 +05303589 pReqMsg->requestId = nla_get_u32(
3590 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3591 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3592
3593 /* Parse and fetch RSSI sample size */
3594 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3595 {
3596 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3597 goto fail;
3598 }
3599 pReqMsg->rssiSampleSize = nla_get_u32(
3600 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3601 hddLog(VOS_TRACE_LEVEL_INFO,
3602 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3603
3604 /* Parse and fetch lost AP sample size */
3605 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3606 {
3607 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3608 goto fail;
3609 }
3610 pReqMsg->lostApSampleSize = nla_get_u32(
3611 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3612 hddLog(VOS_TRACE_LEVEL_INFO,
3613 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3614 /* Parse and fetch minimum Breaching */
3615 if (!tb
3616 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3618 goto fail;
3619 }
3620 pReqMsg->minBreaching = nla_get_u32(
3621 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3622 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3623
3624 /* Parse and fetch number of APs */
3625 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3626 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3627 goto fail;
3628 }
3629 pReqMsg->numAp = nla_get_u32(
3630 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3631 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3632
3633 pReqMsg->sessionId = pAdapter->sessionId;
3634 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3635
3636 nla_for_each_nested(apTh,
3637 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3638 if(nla_parse(tb2,
3639 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3640 nla_data(apTh), nla_len(apTh),
3641 NULL)) {
3642 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3643 goto fail;
3644 }
3645
3646 /* Parse and fetch MAC address */
3647 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3648 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3649 goto fail;
3650 }
3651 memcpy(pReqMsg->ap[i].bssid, nla_data(
3652 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3653 sizeof(tSirMacAddr));
3654
3655 /* Parse and fetch low RSSI */
3656 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3657 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3658 goto fail;
3659 }
3660 pReqMsg->ap[i].low = nla_get_s32(
3661 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3662 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3663
3664 /* Parse and fetch high RSSI */
3665 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3666 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3667 goto fail;
3668 }
3669 pReqMsg->ap[i].high = nla_get_s32(
3670 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3671 hddLog(VOS_TRACE_LEVEL_INFO,
3672 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3673
3674 /* Parse and fetch channel */
3675 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3676 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3677 goto fail;
3678 }
3679 pReqMsg->ap[i].channel = nla_get_u32(
3680 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3681 hddLog(VOS_TRACE_LEVEL_INFO,
3682 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3683 i++;
3684 }
3685
3686 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3687 if (!HAL_STATUS_SUCCESS(status)) {
3688 hddLog(VOS_TRACE_LEVEL_ERROR,
3689 FL("sme_SetSignificantChange failed(err=%d)"), status);
3690 vos_mem_free(pReqMsg);
3691 return -EINVAL;
3692 }
Dino Myclee8843b32014-07-04 14:21:45 +05303693 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303694 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303695 return 0;
3696
3697fail:
3698 vos_mem_free(pReqMsg);
3699 return -EINVAL;
3700}
3701
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303702static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3703 struct wireless_dev *wdev,
3704 const void *data, int dataLen)
3705{
3706 int ret = 0;
3707
3708 vos_ssr_protect(__func__);
3709 ret = __wlan_hdd_cfg80211_extscan_set_significant_change(wiphy, wdev, data,
3710 dataLen);
3711 vos_ssr_unprotect(__func__);
3712
3713 return ret;
3714}
3715
3716static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303717 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303718 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303719{
3720 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3721 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3722 tANI_U8 numChannels = 0;
3723 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3724 tANI_U32 requestId;
3725 tWifiBand wifiBand;
3726 eHalStatus status;
3727 struct sk_buff *replySkb;
3728 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303729 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303730
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303731 ENTER();
3732
Dino Mycle6fb96c12014-06-10 11:52:40 +05303733 status = wlan_hdd_validate_context(pHddCtx);
3734 if (0 != status)
3735 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303736 return -EINVAL;
3737 }
Dino Myclee8843b32014-07-04 14:21:45 +05303738 /* check the EXTScan Capability */
3739 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3740 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3741 {
3742 hddLog(VOS_TRACE_LEVEL_ERROR,
3743 FL("EXTScan not enabled/supported by Firmware"));
3744 return -EINVAL;
3745 }
3746
Dino Mycle6fb96c12014-06-10 11:52:40 +05303747 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3748 data, dataLen,
3749 wlan_hdd_extscan_config_policy)) {
3750 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3751 return -EINVAL;
3752 }
3753
3754 /* Parse and fetch request Id */
3755 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3757 return -EINVAL;
3758 }
3759 requestId = nla_get_u32(
3760 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3761 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3762
3763 /* Parse and fetch wifi band */
3764 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3765 {
3766 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3767 return -EINVAL;
3768 }
3769 wifiBand = nla_get_u32(
3770 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3771 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3772
3773 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3774 wifiBand, ChannelList,
3775 &numChannels);
3776 if (eHAL_STATUS_SUCCESS != status) {
3777 hddLog(VOS_TRACE_LEVEL_ERROR,
3778 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3779 return -EINVAL;
3780 }
3781 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3782 for (i = 0; i < numChannels; i++)
3783 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3784
3785 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3786 sizeof(u32) * numChannels +
3787 NLMSG_HDRLEN);
3788
3789 if (!replySkb) {
3790 hddLog(VOS_TRACE_LEVEL_ERROR,
3791 FL("valid channels: buffer alloc fail"));
3792 return -EINVAL;
3793 }
3794 if (nla_put_u32(replySkb,
3795 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3796 numChannels) ||
3797 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3798 sizeof(u32) * numChannels, ChannelList)) {
3799
3800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3801 kfree_skb(replySkb);
3802 return -EINVAL;
3803 }
3804
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303805 ret = cfg80211_vendor_cmd_reply(replySkb);
3806
3807 EXIT();
3808 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303809}
3810
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303811static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3812 struct wireless_dev *wdev,
3813 const void *data, int dataLen)
3814{
3815 int ret = 0;
3816
3817 vos_ssr_protect(__func__);
3818 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
3819 dataLen);
3820 vos_ssr_unprotect(__func__);
3821
3822 return ret;
3823}
3824
3825static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303826 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303827 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303828{
Dino Myclee8843b32014-07-04 14:21:45 +05303829 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303830 struct net_device *dev = wdev->netdev;
3831 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3832 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3833 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3834 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3835 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3836 struct nlattr *buckets;
3837 struct nlattr *channels;
3838 int rem1;
3839 int rem2;
3840 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303841 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303842
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303843 ENTER();
3844
Dino Mycle6fb96c12014-06-10 11:52:40 +05303845 status = wlan_hdd_validate_context(pHddCtx);
3846 if (0 != status)
3847 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303848 return -EINVAL;
3849 }
Dino Myclee8843b32014-07-04 14:21:45 +05303850 /* check the EXTScan Capability */
3851 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3852 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3853 {
3854 hddLog(VOS_TRACE_LEVEL_ERROR,
3855 FL("EXTScan not enabled/supported by Firmware"));
3856 return -EINVAL;
3857 }
3858
Dino Mycle6fb96c12014-06-10 11:52:40 +05303859 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3860 data, dataLen,
3861 wlan_hdd_extscan_config_policy)) {
3862 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3863 return -EINVAL;
3864 }
3865
3866 /* Parse and fetch request Id */
3867 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3868 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3869 return -EINVAL;
3870 }
3871
Dino Myclee8843b32014-07-04 14:21:45 +05303872 pReqMsg = (tpSirEXTScanStartReqParams)
3873 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303874 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303875 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3876 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303877 }
3878
3879 pReqMsg->requestId = nla_get_u32(
3880 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3881 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3882
3883 pReqMsg->sessionId = pAdapter->sessionId;
3884 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3885
3886 /* Parse and fetch base period */
3887 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3888 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3889 goto fail;
3890 }
3891 pReqMsg->basePeriod = nla_get_u32(
3892 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3893 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3894 pReqMsg->basePeriod);
3895
3896 /* Parse and fetch max AP per scan */
3897 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3898 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3899 goto fail;
3900 }
3901 pReqMsg->maxAPperScan = nla_get_u32(
3902 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3903 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3904 pReqMsg->maxAPperScan);
3905
3906 /* Parse and fetch report threshold */
3907 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3908 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3909 goto fail;
3910 }
3911 pReqMsg->reportThreshold = nla_get_u8(
3912 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3913 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3914 pReqMsg->reportThreshold);
3915
3916 /* Parse and fetch number of buckets */
3917 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3918 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3919 goto fail;
3920 }
3921 pReqMsg->numBuckets = nla_get_u8(
3922 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3923 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3924 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3925 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3926 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3927 }
3928 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3929 pReqMsg->numBuckets);
3930 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3931 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3932 goto fail;
3933 }
3934
3935 nla_for_each_nested(buckets,
3936 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3937 if(nla_parse(bucket,
3938 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3939 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3940 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3941 goto fail;
3942 }
3943
3944 /* Parse and fetch bucket spec */
3945 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3946 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3947 goto fail;
3948 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303949
3950 pReqMsg->buckets[index].bucket = nla_get_u8(
3951 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3952
3953 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
3954 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303955
3956 /* Parse and fetch wifi band */
3957 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3958 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3959 goto fail;
3960 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303961 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303962 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3963 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303964 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303965
3966 /* Parse and fetch period */
3967 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3968 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3969 goto fail;
3970 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303971 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303972 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3973 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303974 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303975
3976 /* Parse and fetch report events */
3977 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3978 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3979 goto fail;
3980 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303981 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303982 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3983 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303984 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303985
3986 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303987 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
3988 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303989 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3990 goto fail;
3991 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303992 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303993 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3994 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303995 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303996
3997 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3998 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3999 goto fail;
4000 }
4001
4002 j = 0;
4003 nla_for_each_nested(channels,
4004 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4005 if(nla_parse(channel,
4006 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4007 nla_data(channels), nla_len(channels),
4008 NULL)) { //wlan_hdd_extscan_config_policy here
4009 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4010 goto fail;
4011 }
4012
4013 /* Parse and fetch channel */
4014 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4015 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4016 goto fail;
4017 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304018 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304019 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4020 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304021 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304022
4023 /* Parse and fetch dwell time */
4024 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4025 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
4026 goto fail;
4027 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304028 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304029 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4030 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304031 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304032
4033 /* Parse and fetch channel spec passive */
4034 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4035 hddLog(VOS_TRACE_LEVEL_ERROR,
4036 FL("attr channel spec passive failed"));
4037 goto fail;
4038 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304039 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304040 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4041 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304042 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304043 j++;
4044 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304045 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304046 }
4047 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4048 if (!HAL_STATUS_SUCCESS(status)) {
4049 hddLog(VOS_TRACE_LEVEL_ERROR,
4050 FL("sme_EXTScanStart failed(err=%d)"), status);
4051 vos_mem_free(pReqMsg);
4052 return -EINVAL;
4053 }
4054
Dino Myclee8843b32014-07-04 14:21:45 +05304055 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304056 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304057 return 0;
4058
4059fail:
4060 vos_mem_free(pReqMsg);
4061 return -EINVAL;
4062}
4063
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304064static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4065 struct wireless_dev *wdev,
4066 const void *data, int dataLen)
4067{
4068 int ret = 0;
4069
4070 vos_ssr_protect(__func__);
4071 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4072 vos_ssr_unprotect(__func__);
4073
4074 return ret;
4075}
4076
4077static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304078 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304079 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304080{
Dino Myclee8843b32014-07-04 14:21:45 +05304081 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304082 struct net_device *dev = wdev->netdev;
4083 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4084 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4085 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4086 eHalStatus status;
4087
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304088 ENTER();
4089
Dino Mycle6fb96c12014-06-10 11:52:40 +05304090 status = wlan_hdd_validate_context(pHddCtx);
4091 if (0 != status)
4092 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304093 return -EINVAL;
4094 }
Dino Myclee8843b32014-07-04 14:21:45 +05304095 /* check the EXTScan Capability */
4096 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4097 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4098 {
4099 hddLog(VOS_TRACE_LEVEL_ERROR,
4100 FL("EXTScan not enabled/supported by Firmware"));
4101 return -EINVAL;
4102 }
4103
Dino Mycle6fb96c12014-06-10 11:52:40 +05304104 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4105 data, dataLen,
4106 wlan_hdd_extscan_config_policy)) {
4107 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4108 return -EINVAL;
4109 }
4110
4111 /* Parse and fetch request Id */
4112 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4113 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4114 return -EINVAL;
4115 }
4116
Dino Myclee8843b32014-07-04 14:21:45 +05304117 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304118 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304119 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304120
Dino Myclee8843b32014-07-04 14:21:45 +05304121 reqMsg.sessionId = pAdapter->sessionId;
4122 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304123
Dino Myclee8843b32014-07-04 14:21:45 +05304124 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304125 if (!HAL_STATUS_SUCCESS(status)) {
4126 hddLog(VOS_TRACE_LEVEL_ERROR,
4127 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304128 return -EINVAL;
4129 }
4130
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304131 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304132 return 0;
4133}
4134
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304135static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4136 struct wireless_dev *wdev,
4137 const void *data, int dataLen)
4138{
4139 int ret = 0;
4140
4141 vos_ssr_protect(__func__);
4142 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4143 vos_ssr_unprotect(__func__);
4144
4145 return ret;
4146}
4147
4148static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304149 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304150 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304151{
Dino Myclee8843b32014-07-04 14:21:45 +05304152 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304153 struct net_device *dev = wdev->netdev;
4154 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4155 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4156 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4157 eHalStatus status;
4158
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304159 ENTER();
4160
Dino Mycle6fb96c12014-06-10 11:52:40 +05304161 status = wlan_hdd_validate_context(pHddCtx);
4162 if (0 != status)
4163 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304164 return -EINVAL;
4165 }
Dino Myclee8843b32014-07-04 14:21:45 +05304166 /* check the EXTScan Capability */
4167 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4168 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4169 {
4170 hddLog(VOS_TRACE_LEVEL_ERROR,
4171 FL("EXTScan not enabled/supported by Firmware"));
4172 return -EINVAL;
4173 }
4174
Dino Mycle6fb96c12014-06-10 11:52:40 +05304175 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4176 data, dataLen,
4177 wlan_hdd_extscan_config_policy)) {
4178 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4179 return -EINVAL;
4180 }
4181
4182 /* Parse and fetch request Id */
4183 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4184 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4185 return -EINVAL;
4186 }
4187
Dino Myclee8843b32014-07-04 14:21:45 +05304188 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304189 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304190 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304191
Dino Myclee8843b32014-07-04 14:21:45 +05304192 reqMsg.sessionId = pAdapter->sessionId;
4193 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304194
Dino Myclee8843b32014-07-04 14:21:45 +05304195 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304196 if (!HAL_STATUS_SUCCESS(status)) {
4197 hddLog(VOS_TRACE_LEVEL_ERROR,
4198 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304199 return -EINVAL;
4200 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304201 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304202 return 0;
4203}
4204
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304205static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4206 struct wireless_dev *wdev,
4207 const void *data, int dataLen)
4208{
4209 int ret = 0;
4210
4211 vos_ssr_protect(__func__);
4212 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4213 vos_ssr_unprotect(__func__);
4214
4215 return ret;
4216}
4217
4218static int __wlan_hdd_cfg80211_extscan_reset_significant_change(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304219 struct wiphy *wiphy,
4220 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304221 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304222{
Dino Myclee8843b32014-07-04 14:21:45 +05304223 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304224 struct net_device *dev = wdev->netdev;
4225 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4226 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4227 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4228 eHalStatus status;
4229
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304230 ENTER();
4231
Dino Mycle6fb96c12014-06-10 11:52:40 +05304232 status = wlan_hdd_validate_context(pHddCtx);
4233 if (0 != status)
4234 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304235 return -EINVAL;
4236 }
Dino Myclee8843b32014-07-04 14:21:45 +05304237 /* check the EXTScan Capability */
4238 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4239 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4240 {
4241 hddLog(VOS_TRACE_LEVEL_ERROR,
4242 FL("EXTScan not enabled/supported by Firmware"));
4243 return -EINVAL;
4244 }
4245
Dino Mycle6fb96c12014-06-10 11:52:40 +05304246 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4247 data, dataLen,
4248 wlan_hdd_extscan_config_policy)) {
4249 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4250 return -EINVAL;
4251 }
4252
4253 /* Parse and fetch request Id */
4254 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4255 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4256 return -EINVAL;
4257 }
4258
Dino Mycle6fb96c12014-06-10 11:52:40 +05304259
Dino Myclee8843b32014-07-04 14:21:45 +05304260 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304261 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304262 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304263
Dino Myclee8843b32014-07-04 14:21:45 +05304264 reqMsg.sessionId = pAdapter->sessionId;
4265 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304266
Dino Myclee8843b32014-07-04 14:21:45 +05304267 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304268 if (!HAL_STATUS_SUCCESS(status)) {
4269 hddLog(VOS_TRACE_LEVEL_ERROR,
4270 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304271 return -EINVAL;
4272 }
4273
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304274 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304275 return 0;
4276}
4277
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304278static int wlan_hdd_cfg80211_extscan_reset_significant_change(
4279 struct wiphy *wiphy,
4280 struct wireless_dev *wdev,
4281 const void *data, int dataLen)
4282{
4283 int ret = 0;
4284
4285 vos_ssr_protect(__func__);
4286 ret = __wlan_hdd_cfg80211_extscan_reset_significant_change(wiphy,
4287 wdev, data,
4288 dataLen);
4289 vos_ssr_unprotect(__func__);
4290
4291 return ret;
4292}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304293#endif /* WLAN_FEATURE_EXTSCAN */
4294
Atul Mittal115287b2014-07-08 13:26:33 +05304295/*EXT TDLS*/
4296static const struct nla_policy
4297wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4298{
4299 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4300 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4301 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4302 {.type = NLA_S32 },
4303 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4304 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4305
4306};
4307
4308static const struct nla_policy
4309wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4310{
4311 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4312
4313};
4314
4315static const struct nla_policy
4316wlan_hdd_tdls_config_state_change_policy[
4317 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4318{
4319 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4320 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4321 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304322 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4323 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4324 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304325
4326};
4327
4328static const struct nla_policy
4329wlan_hdd_tdls_config_get_status_policy[
4330 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4331{
4332 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4333 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4334 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304335 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4336 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4337 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304338
4339};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304340
4341static const struct nla_policy
4342wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4343{
4344 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4345};
4346
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304347static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304348 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304349 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304350 int data_len)
4351{
4352
4353 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4354 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4355
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304356 ENTER();
4357
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304358 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304359 return -EINVAL;
4360 }
4361 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
4362 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN disabled in ini"));
4363 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304364 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304365 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
4366 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN not supported by FW"));
4367 return -ENOTSUPP;
4368 }
4369
4370 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4371 data, data_len, wlan_hdd_mac_config)) {
4372 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4373 return -EINVAL;
4374 }
4375
4376 /* Parse and fetch mac address */
4377 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4378 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4379 return -EINVAL;
4380 }
4381
4382 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4383 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4384 VOS_MAC_ADDR_LAST_3_BYTES);
4385
Siddharth Bhal76972212014-10-15 16:22:51 +05304386 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4387
4388 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304389 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4390 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304391 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4392 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4393 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4394 {
4395 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4396 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4397 VOS_MAC_ADDRESS_LEN);
4398 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304399 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304400
Siddharth Bhal76972212014-10-15 16:22:51 +05304401 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
4402 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304403 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4404 }
4405
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304406 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304407 return 0;
4408}
4409
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304410static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
4411 struct wireless_dev *wdev,
4412 const void *data,
4413 int data_len)
4414{
4415 int ret = 0;
4416
4417 vos_ssr_protect(__func__);
4418 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
4419 vos_ssr_unprotect(__func__);
4420
4421 return ret;
4422}
4423
4424static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304425 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304426 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304427 int data_len)
4428{
4429 u8 peer[6] = {0};
4430 struct net_device *dev = wdev->netdev;
4431 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4432 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4433 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4434 eHalStatus ret;
4435 tANI_S32 state;
4436 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304437 tANI_S32 global_operating_class = 0;
4438 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304439 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304440 int retVal;
4441
4442 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304443
4444 ret = wlan_hdd_validate_context(pHddCtx);
4445 if (0 != ret) {
Atul Mittal115287b2014-07-08 13:26:33 +05304446 return -EINVAL;
4447 }
4448 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4449
4450 return -ENOTSUPP;
4451 }
4452 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4453 data, data_len,
4454 wlan_hdd_tdls_config_get_status_policy)) {
4455 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4456 return -EINVAL;
4457 }
4458
4459 /* Parse and fetch mac address */
4460 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4461 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4462 return -EINVAL;
4463 }
4464
4465 memcpy(peer, nla_data(
4466 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4467 sizeof(peer));
4468 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4469
4470 ret = wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
4471
4472 if (0 != ret) {
4473 hddLog(VOS_TRACE_LEVEL_ERROR,
4474 FL("get status Failed"));
4475 return -EINVAL;
4476 }
4477 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304478 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304479 NLMSG_HDRLEN);
4480
4481 if (!skb) {
4482 hddLog(VOS_TRACE_LEVEL_ERROR,
4483 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4484 return -EINVAL;
4485 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304486 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 +05304487 reason,
4488 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304489 global_operating_class,
4490 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304491 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304492 if (nla_put_s32(skb,
4493 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4494 state) ||
4495 nla_put_s32(skb,
4496 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4497 reason) ||
4498 nla_put_s32(skb,
4499 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4500 global_operating_class) ||
4501 nla_put_s32(skb,
4502 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4503 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304504
4505 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4506 goto nla_put_failure;
4507 }
4508
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304509 retVal = cfg80211_vendor_cmd_reply(skb);
4510 EXIT();
4511 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05304512
4513nla_put_failure:
4514 kfree_skb(skb);
4515 return -EINVAL;
4516}
4517
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304518static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4519 struct wireless_dev *wdev,
4520 const void *data,
4521 int data_len)
4522{
4523 int ret = 0;
4524
4525 vos_ssr_protect(__func__);
4526 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
4527 vos_ssr_unprotect(__func__);
4528
4529 return ret;
4530}
4531
Atul Mittal115287b2014-07-08 13:26:33 +05304532static int wlan_hdd_cfg80211_exttdls_callback(tANI_U8* mac,
4533 tANI_S32 state,
4534 tANI_S32 reason,
4535 void *ctx)
4536{
4537 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
4538 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4539 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304540 tANI_S32 global_operating_class = 0;
4541 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304542
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304543 ENTER();
4544
Atul Mittal115287b2014-07-08 13:26:33 +05304545 if (wlan_hdd_validate_context(pHddCtx)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304546 return -EINVAL;
4547 }
4548
4549 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4550
4551 return -ENOTSUPP;
4552 }
4553 skb = cfg80211_vendor_event_alloc(
4554 pHddCtx->wiphy,
4555 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4556 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4557 GFP_KERNEL);
4558
4559 if (!skb) {
4560 hddLog(VOS_TRACE_LEVEL_ERROR,
4561 FL("cfg80211_vendor_event_alloc failed"));
4562 return -EINVAL;
4563 }
4564 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304565 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4566 reason,
4567 state,
4568 global_operating_class,
4569 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304570 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4571 MAC_ADDR_ARRAY(mac));
4572
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304573 if (nla_put(skb,
4574 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4575 VOS_MAC_ADDR_SIZE, mac) ||
4576 nla_put_s32(skb,
4577 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4578 state) ||
4579 nla_put_s32(skb,
4580 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4581 reason) ||
4582 nla_put_s32(skb,
4583 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4584 channel) ||
4585 nla_put_s32(skb,
4586 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4587 global_operating_class)
4588 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304589 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4590 goto nla_put_failure;
4591 }
4592
4593 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304594 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05304595 return (0);
4596
4597nla_put_failure:
4598 kfree_skb(skb);
4599 return -EINVAL;
4600}
4601
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304602static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304603 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304604 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304605 int data_len)
4606{
4607 u8 peer[6] = {0};
4608 struct net_device *dev = wdev->netdev;
4609 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4610 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4611 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4612 eHalStatus status;
4613 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304614 int ret;
4615
4616 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304617
4618 status = wlan_hdd_validate_context(pHddCtx);
4619 if (0 != status) {
Atul Mittal115287b2014-07-08 13:26:33 +05304620 return -EINVAL;
4621 }
4622 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4623
4624 return -ENOTSUPP;
4625 }
4626 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4627 data, data_len,
4628 wlan_hdd_tdls_config_enable_policy)) {
4629 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4630 return -EINVAL;
4631 }
4632
4633 /* Parse and fetch mac address */
4634 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4635 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4636 return -EINVAL;
4637 }
4638
4639 memcpy(peer, nla_data(
4640 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4641 sizeof(peer));
4642 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4643
4644 /* Parse and fetch channel */
4645 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4646 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4647 return -EINVAL;
4648 }
4649 pReqMsg.channel = nla_get_s32(
4650 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4651 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4652
4653 /* Parse and fetch global operating class */
4654 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4655 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4656 return -EINVAL;
4657 }
4658 pReqMsg.global_operating_class = nla_get_s32(
4659 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4660 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4661 pReqMsg.global_operating_class);
4662
4663 /* Parse and fetch latency ms */
4664 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4665 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4666 return -EINVAL;
4667 }
4668 pReqMsg.max_latency_ms = nla_get_s32(
4669 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4670 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4671 pReqMsg.max_latency_ms);
4672
4673 /* Parse and fetch required bandwidth kbps */
4674 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4675 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4676 return -EINVAL;
4677 }
4678
4679 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4680 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4681 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4682 pReqMsg.min_bandwidth_kbps);
4683
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304684 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05304685 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05304686 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304687 wlan_hdd_cfg80211_exttdls_callback);
4688
4689 EXIT();
4690 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304691}
4692
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304693static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4694 struct wireless_dev *wdev,
4695 const void *data,
4696 int data_len)
4697{
4698 int ret = 0;
4699
4700 vos_ssr_protect(__func__);
4701 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
4702 vos_ssr_unprotect(__func__);
4703
4704 return ret;
4705}
4706
4707static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304708 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304709 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304710 int data_len)
4711{
4712 u8 peer[6] = {0};
4713 struct net_device *dev = wdev->netdev;
4714 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4715 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4716 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4717 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304718 int ret;
4719
4720 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304721
4722 status = wlan_hdd_validate_context(pHddCtx);
4723 if (0 != status) {
Atul Mittal115287b2014-07-08 13:26:33 +05304724 return -EINVAL;
4725 }
4726 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4727
4728 return -ENOTSUPP;
4729 }
4730 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4731 data, data_len,
4732 wlan_hdd_tdls_config_disable_policy)) {
4733 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4734 return -EINVAL;
4735 }
4736 /* Parse and fetch mac address */
4737 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4738 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4739 return -EINVAL;
4740 }
4741
4742 memcpy(peer, nla_data(
4743 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4744 sizeof(peer));
4745 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4746
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304747 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
4748
4749 EXIT();
4750 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304751}
4752
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304753static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4754 struct wireless_dev *wdev,
4755 const void *data,
4756 int data_len)
4757{
4758 int ret = 0;
4759
4760 vos_ssr_protect(__func__);
4761 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
4762 vos_ssr_unprotect(__func__);
4763
4764 return ret;
4765}
4766
Dasari Srinivas7875a302014-09-26 17:50:57 +05304767static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304768__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05304769 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304770 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05304771{
4772 struct net_device *dev = wdev->netdev;
4773 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4774 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4775 struct sk_buff *skb = NULL;
4776 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304777 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05304778
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304779 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304780
4781 ret = wlan_hdd_validate_context(pHddCtx);
4782 if (0 != ret)
4783 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304784 return ret;
4785 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05304786 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
4787 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
4788 fset |= WIFI_FEATURE_INFRA;
4789 }
4790
4791 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
4792 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
4793 fset |= WIFI_FEATURE_INFRA_5G;
4794 }
4795
4796#ifdef WLAN_FEATURE_P2P
4797 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
4798 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
4799 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
4800 fset |= WIFI_FEATURE_P2P;
4801 }
4802#endif
4803
4804 /* Soft-AP is supported currently by default */
4805 fset |= WIFI_FEATURE_SOFT_AP;
4806
4807#ifdef WLAN_FEATURE_EXTSCAN
4808 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
4809 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
4810 hddLog(LOG1, FL("EXTScan is supported by firmware"));
4811 fset |= WIFI_FEATURE_EXTSCAN;
4812 }
4813#endif
4814
4815#ifdef WLAN_FEATURE_NAN
4816 if (sme_IsFeatureSupportedByFW(NAN)) {
4817 hddLog(LOG1, FL("NAN is supported by firmware"));
4818 fset |= WIFI_FEATURE_NAN;
4819 }
4820#endif
4821
4822 /* D2D RTT is not supported currently by default */
4823 if (sme_IsFeatureSupportedByFW(RTT)) {
4824 hddLog(LOG1, FL("RTT is supported by firmware"));
4825 fset |= WIFI_FEATURE_D2AP_RTT;
4826 }
4827
4828#ifdef FEATURE_WLAN_BATCH_SCAN
4829 if (fset & WIFI_FEATURE_EXTSCAN) {
4830 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
4831 fset &= ~WIFI_FEATURE_BATCH_SCAN;
4832 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
4833 hddLog(LOG1, FL("Batch scan is supported by firmware"));
4834 fset |= WIFI_FEATURE_BATCH_SCAN;
4835 }
4836#endif
4837
4838#ifdef FEATURE_WLAN_SCAN_PNO
4839 if (pHddCtx->cfg_ini->configPNOScanSupport &&
4840 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
4841 hddLog(LOG1, FL("PNO is supported by firmware"));
4842 fset |= WIFI_FEATURE_PNO;
4843 }
4844#endif
4845
4846 /* STA+STA is supported currently by default */
4847 fset |= WIFI_FEATURE_ADDITIONAL_STA;
4848
4849#ifdef FEATURE_WLAN_TDLS
4850 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
4851 sme_IsFeatureSupportedByFW(TDLS)) {
4852 hddLog(LOG1, FL("TDLS is supported by firmware"));
4853 fset |= WIFI_FEATURE_TDLS;
4854 }
4855
4856 /* TDLS_OFFCHANNEL is not supported currently by default */
4857#endif
4858
4859#ifdef WLAN_AP_STA_CONCURRENCY
4860 /* AP+STA concurrency is supported currently by default */
4861 fset |= WIFI_FEATURE_AP_STA;
4862#endif
4863
4864 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
4865 NLMSG_HDRLEN);
4866
4867 if (!skb) {
4868 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4869 return -EINVAL;
4870 }
4871 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
4872
4873 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
4874 hddLog(LOGE, FL("nla put fail"));
4875 goto nla_put_failure;
4876 }
4877
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304878 ret = cfg80211_vendor_cmd_reply(skb);
4879 EXIT();
4880 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05304881
4882nla_put_failure:
4883 kfree_skb(skb);
4884 return -EINVAL;
4885}
4886
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304887static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304888wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
4889 struct wireless_dev *wdev,
4890 const void *data, int data_len)
4891{
4892 int ret = 0;
4893
4894 vos_ssr_protect(__func__);
4895 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
4896 vos_ssr_unprotect(__func__);
4897
4898 return ret;
4899}
4900
4901static int
4902__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304903 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304904 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304905{
4906 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
4907 uint8_t i, feature_sets, max_feature_sets;
4908 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
4909 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304910 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4911 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304912
4913 ENTER();
4914
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304915 ret = wlan_hdd_validate_context(pHddCtx);
4916 if (0 != ret)
4917 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304918 return ret;
4919 }
4920
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304921 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
4922 data, data_len, NULL)) {
4923 hddLog(LOGE, FL("Invalid ATTR"));
4924 return -EINVAL;
4925 }
4926
4927 /* Parse and fetch max feature set */
4928 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
4929 hddLog(LOGE, FL("Attr max feature set size failed"));
4930 return -EINVAL;
4931 }
4932 max_feature_sets = nla_get_u32(
4933 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
4934 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
4935
4936 /* Fill feature combination matrix */
4937 feature_sets = 0;
4938 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4939 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4940 WIFI_FEATURE_P2P;
4941
4942 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4943 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4944 WIFI_FEATURE_SOFT_AP;
4945
4946 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4947 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
4948 WIFI_FEATURE_SOFT_AP;
4949
4950 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4951 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4952 WIFI_FEATURE_SOFT_AP |
4953 WIFI_FEATURE_P2P;
4954
4955 /* Add more feature combinations here */
4956
4957 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
4958 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
4959 hddLog(LOG1, "Feature set matrix");
4960 for (i = 0; i < feature_sets; i++)
4961 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
4962
4963 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4964 sizeof(u32) * feature_sets +
4965 NLMSG_HDRLEN);
4966
4967 if (reply_skb) {
4968 if (nla_put_u32(reply_skb,
4969 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
4970 feature_sets) ||
4971 nla_put(reply_skb,
4972 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
4973 sizeof(u32) * feature_sets, feature_set_matrix)) {
4974 hddLog(LOGE, FL("nla put fail"));
4975 kfree_skb(reply_skb);
4976 return -EINVAL;
4977 }
4978
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304979 ret = cfg80211_vendor_cmd_reply(reply_skb);
4980 EXIT();
4981 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304982 }
4983 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
4984 return -ENOMEM;
4985
4986max_buffer_err:
4987 hddLog(LOGE, FL("Feature set max buffer size reached. feature_sets(%d) max(%d)"),
4988 feature_sets, WLAN_HDD_MAX_FEATURE_SET);
4989 return -EINVAL;
4990}
4991
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304992static int
4993wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
4994 struct wireless_dev *wdev,
4995 const void *data, int data_len)
4996{
4997 int ret = 0;
4998
4999 vos_ssr_protect(__func__);
5000 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5001 data_len);
5002 vos_ssr_unprotect(__func__);
5003
5004 return ret;
5005}
5006
Agarwal Ashish738843c2014-09-25 12:27:56 +05305007static const struct nla_policy
5008wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5009 +1] =
5010{
5011 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5012};
5013
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305014static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305015 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305016 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305017 int data_len)
5018{
5019 struct net_device *dev = wdev->netdev;
5020 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5021 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5022 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5023 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5024 eHalStatus status;
5025 u32 dfsFlag = 0;
5026
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305027 ENTER();
5028
Agarwal Ashish738843c2014-09-25 12:27:56 +05305029 status = wlan_hdd_validate_context(pHddCtx);
5030 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305031 return -EINVAL;
5032 }
5033 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5034 data, data_len,
5035 wlan_hdd_set_no_dfs_flag_config_policy)) {
5036 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5037 return -EINVAL;
5038 }
5039
5040 /* Parse and fetch required bandwidth kbps */
5041 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5042 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5043 return -EINVAL;
5044 }
5045
5046 dfsFlag = nla_get_u32(
5047 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5048 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5049 dfsFlag);
5050
5051 pHddCtx->disable_dfs_flag = dfsFlag;
5052
5053 sme_disable_dfs_channel(hHal, dfsFlag);
5054 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305055
5056 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305057 return 0;
5058}
Atul Mittal115287b2014-07-08 13:26:33 +05305059
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305060static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5061 struct wireless_dev *wdev,
5062 const void *data,
5063 int data_len)
5064{
5065 int ret = 0;
5066
5067 vos_ssr_protect(__func__);
5068 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5069 vos_ssr_unprotect(__func__);
5070
5071 return ret;
5072
5073}
5074
Mukul Sharma2a271632014-10-13 14:59:01 +05305075const struct
5076nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5077{
5078 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5079 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5080};
5081
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305082static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305083 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305084{
5085
5086 u8 bssid[6] = {0};
5087 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5088 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5089 eHalStatus status = eHAL_STATUS_SUCCESS;
5090 v_U32_t isFwrRoamEnabled = FALSE;
5091 int ret;
5092
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305093 ENTER();
5094
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305095 ret = wlan_hdd_validate_context(pHddCtx);
5096 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305097 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305098 }
5099
5100 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5101 data, data_len,
5102 qca_wlan_vendor_attr);
5103 if (ret){
5104 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5105 return -EINVAL;
5106 }
5107
5108 /* Parse and fetch Enable flag */
5109 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5110 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5111 return -EINVAL;
5112 }
5113
5114 isFwrRoamEnabled = nla_get_u32(
5115 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5116
5117 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5118
5119 /* Parse and fetch bssid */
5120 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5121 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5122 return -EINVAL;
5123 }
5124
5125 memcpy(bssid, nla_data(
5126 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5127 sizeof(bssid));
5128 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5129
5130 //Update roaming
5131 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305132 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305133 return status;
5134}
5135
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305136static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5137 struct wireless_dev *wdev, const void *data, int data_len)
5138{
5139 int ret = 0;
5140
5141 vos_ssr_protect(__func__);
5142 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5143 vos_ssr_unprotect(__func__);
5144
5145 return ret;
5146}
5147
Sunil Duttc69bccb2014-05-26 21:30:20 +05305148const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
5149{
Mukul Sharma2a271632014-10-13 14:59:01 +05305150 {
5151 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5152 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
5153 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5154 WIPHY_VENDOR_CMD_NEED_NETDEV |
5155 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305156 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05305157 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305158#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5159 {
5160 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5161 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
5162 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5163 WIPHY_VENDOR_CMD_NEED_NETDEV |
5164 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305165 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05305166 },
5167
5168 {
5169 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5170 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
5171 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5172 WIPHY_VENDOR_CMD_NEED_NETDEV |
5173 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305174 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05305175 },
5176
5177 {
5178 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5179 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
5180 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5181 WIPHY_VENDOR_CMD_NEED_NETDEV |
5182 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305183 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05305184 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305185#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305186#ifdef WLAN_FEATURE_EXTSCAN
5187 {
5188 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5189 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
5190 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5191 WIPHY_VENDOR_CMD_NEED_NETDEV |
5192 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305193 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05305194 },
5195 {
5196 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5197 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
5198 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5199 WIPHY_VENDOR_CMD_NEED_NETDEV |
5200 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305201 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05305202 },
5203 {
5204 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5205 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
5206 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5207 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305208 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05305209 },
5210 {
5211 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5212 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
5213 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5214 WIPHY_VENDOR_CMD_NEED_NETDEV |
5215 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305216 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05305217 },
5218 {
5219 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5220 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
5221 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5222 WIPHY_VENDOR_CMD_NEED_NETDEV |
5223 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305224 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05305225 },
5226 {
5227 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5228 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
5229 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5230 WIPHY_VENDOR_CMD_NEED_NETDEV |
5231 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305232 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305233 },
5234 {
5235 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5236 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
5237 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5238 WIPHY_VENDOR_CMD_NEED_NETDEV |
5239 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305240 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305241 },
5242 {
5243 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5244 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
5245 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5246 WIPHY_VENDOR_CMD_NEED_NETDEV |
5247 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305248 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305249 },
5250 {
5251 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5252 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
5253 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5254 WIPHY_VENDOR_CMD_NEED_NETDEV |
5255 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305256 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305257 },
5258#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305259/*EXT TDLS*/
5260 {
5261 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5262 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
5263 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5264 WIPHY_VENDOR_CMD_NEED_NETDEV |
5265 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305266 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05305267 },
5268 {
5269 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5270 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
5271 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5272 WIPHY_VENDOR_CMD_NEED_NETDEV |
5273 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305274 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05305275 },
5276 {
5277 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5278 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
5279 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5280 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305281 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05305282 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05305283 {
5284 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5285 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
5286 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5287 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305288 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05305289 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05305290 {
5291 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5292 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
5293 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5294 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305295 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05305296 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305297 {
5298 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5299 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
5300 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5301 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305302 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305303 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305304 {
5305 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5306 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
5307 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5308 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305309 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305310 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305311};
5312
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005313/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05305314static const
5315struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005316{
5317#ifdef FEATURE_WLAN_CH_AVOID
5318 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05305319 .vendor_id = QCA_NL80211_VENDOR_ID,
5320 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005321 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305322#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
5323#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5324 {
5325 /* Index = 1*/
5326 .vendor_id = QCA_NL80211_VENDOR_ID,
5327 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
5328 },
5329 {
5330 /* Index = 2*/
5331 .vendor_id = QCA_NL80211_VENDOR_ID,
5332 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
5333 },
5334 {
5335 /* Index = 3*/
5336 .vendor_id = QCA_NL80211_VENDOR_ID,
5337 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
5338 },
5339 {
5340 /* Index = 4*/
5341 .vendor_id = QCA_NL80211_VENDOR_ID,
5342 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
5343 },
5344 {
5345 /* Index = 5*/
5346 .vendor_id = QCA_NL80211_VENDOR_ID,
5347 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
5348 },
5349 {
5350 /* Index = 6*/
5351 .vendor_id = QCA_NL80211_VENDOR_ID,
5352 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
5353 },
5354#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305355#ifdef WLAN_FEATURE_EXTSCAN
5356 {
5357 .vendor_id = QCA_NL80211_VENDOR_ID,
5358 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
5359 },
5360 {
5361 .vendor_id = QCA_NL80211_VENDOR_ID,
5362 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
5363 },
5364 {
5365 .vendor_id = QCA_NL80211_VENDOR_ID,
5366 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
5367 },
5368 {
5369 .vendor_id = QCA_NL80211_VENDOR_ID,
5370 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
5371 },
5372 {
5373 .vendor_id = QCA_NL80211_VENDOR_ID,
5374 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
5375 },
5376 {
5377 .vendor_id = QCA_NL80211_VENDOR_ID,
5378 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
5379 },
5380 {
5381 .vendor_id = QCA_NL80211_VENDOR_ID,
5382 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
5383 },
5384 {
5385 .vendor_id = QCA_NL80211_VENDOR_ID,
5386 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
5387 },
5388 {
5389 .vendor_id = QCA_NL80211_VENDOR_ID,
5390 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
5391 },
5392 {
5393 .vendor_id = QCA_NL80211_VENDOR_ID,
5394 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
5395 },
5396 {
5397 .vendor_id = QCA_NL80211_VENDOR_ID,
5398 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
5399 },
5400 {
5401 .vendor_id = QCA_NL80211_VENDOR_ID,
5402 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
5403 },
5404 {
5405 .vendor_id = QCA_NL80211_VENDOR_ID,
5406 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
5407 },
5408#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305409/*EXT TDLS*/
5410 {
5411 .vendor_id = QCA_NL80211_VENDOR_ID,
5412 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
5413 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005414};
5415
Jeff Johnson295189b2012-06-20 16:38:30 -07005416/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305417 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305418 * This function is called by hdd_wlan_startup()
5419 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305420 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07005421 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305422struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07005423{
5424 struct wiphy *wiphy;
5425 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305426 /*
5427 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07005428 */
5429 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
5430
5431 if (!wiphy)
5432 {
5433 /* Print error and jump into err label and free the memory */
5434 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
5435 return NULL;
5436 }
5437
Sunil Duttc69bccb2014-05-26 21:30:20 +05305438
Jeff Johnson295189b2012-06-20 16:38:30 -07005439 return wiphy;
5440}
5441
5442/*
5443 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305444 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07005445 * private ioctl to change the band value
5446 */
5447int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
5448{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305449 int i, j;
5450 eNVChannelEnabledType channelEnabledState;
5451
Jeff Johnsone7245742012-09-05 17:12:55 -07005452 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305453
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305454 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005455 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305456
5457 if (NULL == wiphy->bands[i])
5458 {
5459 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5460 __func__, i);
5461 continue;
5462 }
5463
5464 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5465 {
5466 struct ieee80211_supported_band *band = wiphy->bands[i];
5467
5468 channelEnabledState = vos_nv_getChannelEnabledState(
5469 band->channels[j].hw_value);
5470
5471 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
5472 {
Abhishek Singh678227a2014-11-04 10:52:38 +05305473 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305474 continue;
5475 }
5476 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
5477 {
5478 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5479 continue;
5480 }
5481
5482 if (NV_CHANNEL_DISABLE == channelEnabledState ||
5483 NV_CHANNEL_INVALID == channelEnabledState)
5484 {
5485 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5486 }
5487 else if (NV_CHANNEL_DFS == channelEnabledState)
5488 {
5489 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5490 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
5491 }
5492 else
5493 {
5494 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
5495 |IEEE80211_CHAN_RADAR);
5496 }
5497 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005498 }
5499 return 0;
5500}
5501/*
5502 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305503 * This function is called by hdd_wlan_startup()
5504 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005505 * This function is used to initialize and register wiphy structure.
5506 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305507int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005508 struct wiphy *wiphy,
5509 hdd_config_t *pCfg
5510 )
5511{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305512 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305513 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5514
Jeff Johnsone7245742012-09-05 17:12:55 -07005515 ENTER();
5516
Jeff Johnson295189b2012-06-20 16:38:30 -07005517 /* Now bind the underlying wlan device with wiphy */
5518 set_wiphy_dev(wiphy, dev);
5519
5520 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005521
Kiet Lam6c583332013-10-14 05:37:09 +05305522#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005523 /* the flag for the other case would be initialzed in
5524 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005525 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305526#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005527
Amar Singhalfddc28c2013-09-05 13:03:40 -07005528 /* This will disable updating of NL channels from passive to
5529 * active if a beacon is received on passive channel. */
5530 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07005531
Amar Singhalfddc28c2013-09-05 13:03:40 -07005532
Amar Singhala49cbc52013-10-08 18:37:44 -07005533
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005534#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005535 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5536 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5537 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005538 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05305539 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005540#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005541
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005542#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005543 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005544#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005545 || pCfg->isFastRoamIniFeatureEnabled
5546#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005547#ifdef FEATURE_WLAN_ESE
5548 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005549#endif
5550 )
5551 {
5552 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5553 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005554#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005555#ifdef FEATURE_WLAN_TDLS
5556 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5557 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5558#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305559#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305560 if (pCfg->configPNOScanSupport)
5561 {
5562 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5563 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5564 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5565 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5566 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305567#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005568
Amar Singhalfddc28c2013-09-05 13:03:40 -07005569#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005570 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5571 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005572 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005573 driver need to determine what to do with both
5574 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005575
5576 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005577#else
5578 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005579#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005580
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305581 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5582
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05305583 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005584
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305585 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5586
Jeff Johnson295189b2012-06-20 16:38:30 -07005587 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305588 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07005589 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07005590 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5591 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005592 | BIT(NL80211_IFTYPE_AP);
5593
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305594 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005595 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305596#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5597 if( pCfg->enableMCC )
5598 {
5599 /* Currently, supports up to two channels */
5600 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005601
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305602 if( !pCfg->allowMCCGODiffBI )
5603 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005604
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305605 }
5606 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5607 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005608#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305609 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005610
Jeff Johnson295189b2012-06-20 16:38:30 -07005611 /* Before registering we need to update the ht capabilitied based
5612 * on ini values*/
5613 if( !pCfg->ShortGI20MhzEnable )
5614 {
5615 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5616 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5617 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5618 }
5619
5620 if( !pCfg->ShortGI40MhzEnable )
5621 {
5622 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5623 }
5624
5625 if( !pCfg->nChannelBondingMode5GHz )
5626 {
5627 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5628 }
5629
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305630 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305631 if (true == hdd_is_5g_supported(pHddCtx))
5632 {
5633 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5634 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305635
5636 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5637 {
5638
5639 if (NULL == wiphy->bands[i])
5640 {
5641 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5642 __func__, i);
5643 continue;
5644 }
5645
5646 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5647 {
5648 struct ieee80211_supported_band *band = wiphy->bands[i];
5649
5650 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5651 {
5652 // Enable social channels for P2P
5653 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5654 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5655 else
5656 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5657 continue;
5658 }
5659 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5660 {
5661 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5662 continue;
5663 }
5664 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005665 }
5666 /*Initialise the supported cipher suite details*/
5667 wiphy->cipher_suites = hdd_cipher_suites;
5668 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5669
5670 /*signal strength in mBm (100*dBm) */
5671 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5672
5673#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305674 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005675#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005676
Sunil Duttc69bccb2014-05-26 21:30:20 +05305677 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
5678 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005679 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
5680 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
5681
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305682 EXIT();
5683 return 0;
5684}
5685
5686/* In this function we are registering wiphy. */
5687int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
5688{
5689 ENTER();
5690 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005691 if (0 > wiphy_register(wiphy))
5692 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305693 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07005694 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
5695 return -EIO;
5696 }
5697
5698 EXIT();
5699 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305700}
Jeff Johnson295189b2012-06-20 16:38:30 -07005701
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305702/* In this function we are updating channel list when,
5703 regulatory domain is FCC and country code is US.
5704 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
5705 As per FCC smart phone is not a indoor device.
5706 GO should not opeate on indoor channels */
5707void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
5708{
5709 int j;
5710 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5711 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
5712 //Default counrtycode from NV at the time of wiphy initialization.
5713 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
5714 &defaultCountryCode[0]))
5715 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005716 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305717 }
5718 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
5719 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305720 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
5721 {
5722 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
5723 return;
5724 }
5725 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
5726 {
5727 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
5728 // Mark UNII -1 band channel as passive
5729 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
5730 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
5731 }
5732 }
5733}
5734
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305735/* This function registers for all frame which supplicant is interested in */
5736void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005737{
Jeff Johnson295189b2012-06-20 16:38:30 -07005738 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5739 /* Register for all P2P action, public action etc frames */
5740 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5741
Jeff Johnsone7245742012-09-05 17:12:55 -07005742 ENTER();
5743
Jeff Johnson295189b2012-06-20 16:38:30 -07005744 /* Right now we are registering these frame when driver is getting
5745 initialized. Once we will move to 2.6.37 kernel, in which we have
5746 frame register ops, we will move this code as a part of that */
5747 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305748 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07005749 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5750
5751 /* GAS Initial Response */
5752 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5753 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305754
Jeff Johnson295189b2012-06-20 16:38:30 -07005755 /* GAS Comeback Request */
5756 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5757 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5758
5759 /* GAS Comeback Response */
5760 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5761 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5762
5763 /* P2P Public Action */
5764 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305765 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005766 P2P_PUBLIC_ACTION_FRAME_SIZE );
5767
5768 /* P2P Action */
5769 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5770 (v_U8_t*)P2P_ACTION_FRAME,
5771 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07005772
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05305773 /* WNM BSS Transition Request frame */
5774 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5775 (v_U8_t*)WNM_BSS_ACTION_FRAME,
5776 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005777
5778 /* WNM-Notification */
5779 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5780 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5781 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005782}
5783
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305784void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005785{
Jeff Johnson295189b2012-06-20 16:38:30 -07005786 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5787 /* Register for all P2P action, public action etc frames */
5788 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5789
Jeff Johnsone7245742012-09-05 17:12:55 -07005790 ENTER();
5791
Jeff Johnson295189b2012-06-20 16:38:30 -07005792 /* Right now we are registering these frame when driver is getting
5793 initialized. Once we will move to 2.6.37 kernel, in which we have
5794 frame register ops, we will move this code as a part of that */
5795 /* GAS Initial Request */
5796
5797 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5798 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5799
5800 /* GAS Initial Response */
5801 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5802 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305803
Jeff Johnson295189b2012-06-20 16:38:30 -07005804 /* GAS Comeback Request */
5805 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5806 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5807
5808 /* GAS Comeback Response */
5809 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5810 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5811
5812 /* P2P Public Action */
5813 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305814 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005815 P2P_PUBLIC_ACTION_FRAME_SIZE );
5816
5817 /* P2P Action */
5818 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5819 (v_U8_t*)P2P_ACTION_FRAME,
5820 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005821 /* WNM-Notification */
5822 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5823 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5824 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005825}
5826
5827#ifdef FEATURE_WLAN_WAPI
5828void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
5829 const u8 *mac_addr, u8 *key , int key_Len)
5830{
5831 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5832 tCsrRoamSetKey setKey;
5833 v_BOOL_t isConnected = TRUE;
5834 int status = 0;
5835 v_U32_t roamId= 0xFF;
5836 tANI_U8 *pKeyPtr = NULL;
5837 int n = 0;
5838
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305839 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
5840 __func__, hdd_device_modetoString(pAdapter->device_mode),
5841 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005842
Gopichand Nakkalae7480202013-02-11 15:24:22 +05305843 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005844 setKey.keyId = key_index; // Store Key ID
5845 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
5846 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
5847 setKey.paeRole = 0 ; // the PAE role
5848 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
5849 {
5850 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
5851 }
5852 else
5853 {
5854 isConnected = hdd_connIsConnected(pHddStaCtx);
5855 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
5856 }
5857 setKey.keyLength = key_Len;
5858 pKeyPtr = setKey.Key;
5859 memcpy( pKeyPtr, key, key_Len);
5860
Arif Hussain6d2a3322013-11-17 19:50:10 -08005861 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005862 __func__, key_Len);
5863 for (n = 0 ; n < key_Len; n++)
5864 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
5865 __func__,n,setKey.Key[n]);
5866
5867 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
5868 if ( isConnected )
5869 {
5870 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
5871 pAdapter->sessionId, &setKey, &roamId );
5872 }
5873 if ( status != 0 )
5874 {
5875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5876 "[%4d] sme_RoamSetKey returned ERROR status= %d",
5877 __LINE__, status );
5878 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
5879 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05305880 /* Need to clear any trace of key value in the memory.
5881 * Thus zero out the memory even though it is local
5882 * variable.
5883 */
5884 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005885}
5886#endif /* FEATURE_WLAN_WAPI*/
5887
5888#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305889int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005890 beacon_data_t **ppBeacon,
5891 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005892#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305893int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005894 beacon_data_t **ppBeacon,
5895 struct cfg80211_beacon_data *params,
5896 int dtim_period)
5897#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305898{
Jeff Johnson295189b2012-06-20 16:38:30 -07005899 int size;
5900 beacon_data_t *beacon = NULL;
5901 beacon_data_t *old = NULL;
5902 int head_len,tail_len;
5903
Jeff Johnsone7245742012-09-05 17:12:55 -07005904 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005905 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305906 {
5907 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5908 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005909 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305910 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005911
5912 old = pAdapter->sessionCtx.ap.beacon;
5913
5914 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305915 {
5916 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5917 FL("session(%d) old and new heads points to NULL"),
5918 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005919 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305920 }
5921
5922 if (params->tail && !params->tail_len)
5923 {
5924 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5925 FL("tail_len is zero but tail is not NULL"));
5926 return -EINVAL;
5927 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005928
Jeff Johnson295189b2012-06-20 16:38:30 -07005929#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
5930 /* Kernel 3.0 is not updating dtim_period for set beacon */
5931 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305932 {
5933 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5934 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005935 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305936 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005937#endif
5938
5939 if(params->head)
5940 head_len = params->head_len;
5941 else
5942 head_len = old->head_len;
5943
5944 if(params->tail || !old)
5945 tail_len = params->tail_len;
5946 else
5947 tail_len = old->tail_len;
5948
5949 size = sizeof(beacon_data_t) + head_len + tail_len;
5950
5951 beacon = kzalloc(size, GFP_KERNEL);
5952
5953 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305954 {
5955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5956 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005957 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305958 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005959
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005960#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005961 if(params->dtim_period || !old )
5962 beacon->dtim_period = params->dtim_period;
5963 else
5964 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005965#else
5966 if(dtim_period || !old )
5967 beacon->dtim_period = dtim_period;
5968 else
5969 beacon->dtim_period = old->dtim_period;
5970#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305971
Jeff Johnson295189b2012-06-20 16:38:30 -07005972 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
5973 beacon->tail = beacon->head + head_len;
5974 beacon->head_len = head_len;
5975 beacon->tail_len = tail_len;
5976
5977 if(params->head) {
5978 memcpy (beacon->head,params->head,beacon->head_len);
5979 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305980 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07005981 if(old)
5982 memcpy (beacon->head,old->head,beacon->head_len);
5983 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305984
Jeff Johnson295189b2012-06-20 16:38:30 -07005985 if(params->tail) {
5986 memcpy (beacon->tail,params->tail,beacon->tail_len);
5987 }
5988 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305989 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07005990 memcpy (beacon->tail,old->tail,beacon->tail_len);
5991 }
5992
5993 *ppBeacon = beacon;
5994
5995 kfree(old);
5996
5997 return 0;
5998
5999}
Jeff Johnson295189b2012-06-20 16:38:30 -07006000
6001v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
6002{
6003 int left = length;
6004 v_U8_t *ptr = pIes;
6005 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306006
Jeff Johnson295189b2012-06-20 16:38:30 -07006007 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306008 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006009 elem_id = ptr[0];
6010 elem_len = ptr[1];
6011 left -= 2;
6012 if(elem_len > left)
6013 {
6014 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006015 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006016 eid,elem_len,left);
6017 return NULL;
6018 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306019 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006020 {
6021 return ptr;
6022 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306023
Jeff Johnson295189b2012-06-20 16:38:30 -07006024 left -= elem_len;
6025 ptr += (elem_len + 2);
6026 }
6027 return NULL;
6028}
6029
Jeff Johnson295189b2012-06-20 16:38:30 -07006030/* Check if rate is 11g rate or not */
6031static int wlan_hdd_rate_is_11g(u8 rate)
6032{
Sanjay Devnani28322e22013-06-21 16:13:40 -07006033 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006034 u8 i;
6035 for (i = 0; i < 8; i++)
6036 {
6037 if(rate == gRateArray[i])
6038 return TRUE;
6039 }
6040 return FALSE;
6041}
6042
6043/* Check for 11g rate and set proper 11g only mode */
6044static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
6045 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
6046{
6047 u8 i, num_rates = pIe[0];
6048
6049 pIe += 1;
6050 for ( i = 0; i < num_rates; i++)
6051 {
6052 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
6053 {
6054 /* If rate set have 11g rate than change the mode to 11G */
6055 *pSapHw_mode = eSAP_DOT11_MODE_11g;
6056 if (pIe[i] & BASIC_RATE_MASK)
6057 {
6058 /* If we have 11g rate as basic rate, it means mode
6059 is 11g only mode.
6060 */
6061 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
6062 *pCheckRatesfor11g = FALSE;
6063 }
6064 }
6065 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6066 {
6067 *require_ht = TRUE;
6068 }
6069 }
6070 return;
6071}
6072
6073static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
6074{
6075 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6076 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6077 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6078 u8 checkRatesfor11g = TRUE;
6079 u8 require_ht = FALSE;
6080 u8 *pIe=NULL;
6081
6082 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
6083
6084 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6085 pBeacon->head_len, WLAN_EID_SUPP_RATES);
6086 if (pIe != NULL)
6087 {
6088 pIe += 1;
6089 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6090 &pConfig->SapHw_mode);
6091 }
6092
6093 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6094 WLAN_EID_EXT_SUPP_RATES);
6095 if (pIe != NULL)
6096 {
6097
6098 pIe += 1;
6099 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6100 &pConfig->SapHw_mode);
6101 }
6102
6103 if( pConfig->channel > 14 )
6104 {
6105 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
6106 }
6107
6108 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6109 WLAN_EID_HT_CAPABILITY);
6110
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306111 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006112 {
6113 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
6114 if(require_ht)
6115 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
6116 }
6117}
6118
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306119static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
6120 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
6121{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006122 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306123 v_U8_t *pIe = NULL;
6124 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6125
6126 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6127 pBeacon->tail, pBeacon->tail_len);
6128
6129 if (pIe)
6130 {
6131 ielen = pIe[1] + 2;
6132 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6133 {
6134 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
6135 }
6136 else
6137 {
6138 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
6139 return -EINVAL;
6140 }
6141 *total_ielen += ielen;
6142 }
6143 return 0;
6144}
6145
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006146static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
6147 v_U8_t *genie, v_U8_t *total_ielen)
6148{
6149 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6150 int left = pBeacon->tail_len;
6151 v_U8_t *ptr = pBeacon->tail;
6152 v_U8_t elem_id, elem_len;
6153 v_U16_t ielen = 0;
6154
6155 if ( NULL == ptr || 0 == left )
6156 return;
6157
6158 while (left >= 2)
6159 {
6160 elem_id = ptr[0];
6161 elem_len = ptr[1];
6162 left -= 2;
6163 if (elem_len > left)
6164 {
6165 hddLog( VOS_TRACE_LEVEL_ERROR,
6166 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
6167 elem_id, elem_len, left);
6168 return;
6169 }
6170 if (IE_EID_VENDOR == elem_id)
6171 {
6172 /* skipping the VSIE's which we don't want to include or
6173 * it will be included by existing code
6174 */
6175 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
6176#ifdef WLAN_FEATURE_WFD
6177 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
6178#endif
6179 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6180 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6181 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
6182 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6183 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
6184 {
6185 ielen = ptr[1] + 2;
6186 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6187 {
6188 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
6189 *total_ielen += ielen;
6190 }
6191 else
6192 {
6193 hddLog( VOS_TRACE_LEVEL_ERROR,
6194 "IE Length is too big "
6195 "IEs eid=%d elem_len=%d total_ie_lent=%d",
6196 elem_id, elem_len, *total_ielen);
6197 }
6198 }
6199 }
6200
6201 left -= elem_len;
6202 ptr += (elem_len + 2);
6203 }
6204 return;
6205}
6206
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006207#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006208static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6209 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006210#else
6211static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6212 struct cfg80211_beacon_data *params)
6213#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006214{
6215 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306216 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006217 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07006218 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006219
6220 genie = vos_mem_malloc(MAX_GENIE_LEN);
6221
6222 if(genie == NULL) {
6223
6224 return -ENOMEM;
6225 }
6226
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306227 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6228 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006229 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306230 hddLog(LOGE,
6231 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306232 ret = -EINVAL;
6233 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006234 }
6235
6236#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306237 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6238 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
6239 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306240 hddLog(LOGE,
6241 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306242 ret = -EINVAL;
6243 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006244 }
6245#endif
6246
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306247 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6248 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006249 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306250 hddLog(LOGE,
6251 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306252 ret = -EINVAL;
6253 goto done;
6254 }
6255
6256 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
6257 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006258 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07006259 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006260
6261 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6262 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
6263 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6264 {
6265 hddLog(LOGE,
6266 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006267 ret = -EINVAL;
6268 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006269 }
6270
6271 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6272 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6273 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6274 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6275 ==eHAL_STATUS_FAILURE)
6276 {
6277 hddLog(LOGE,
6278 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006279 ret = -EINVAL;
6280 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006281 }
6282
6283 // Added for ProResp IE
6284 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
6285 {
6286 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
6287 u8 probe_rsp_ie_len[3] = {0};
6288 u8 counter = 0;
6289 /* Check Probe Resp Length if it is greater then 255 then Store
6290 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
6291 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
6292 Store More then 255 bytes into One Variable.
6293 */
6294 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6295 {
6296 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6297 {
6298 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6299 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6300 }
6301 else
6302 {
6303 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6304 rem_probe_resp_ie_len = 0;
6305 }
6306 }
6307
6308 rem_probe_resp_ie_len = 0;
6309
6310 if (probe_rsp_ie_len[0] > 0)
6311 {
6312 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6313 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6314 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6315 probe_rsp_ie_len[0], NULL,
6316 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6317 {
6318 hddLog(LOGE,
6319 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006320 ret = -EINVAL;
6321 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006322 }
6323 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6324 }
6325
6326 if (probe_rsp_ie_len[1] > 0)
6327 {
6328 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6329 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6330 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6331 probe_rsp_ie_len[1], NULL,
6332 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6333 {
6334 hddLog(LOGE,
6335 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006336 ret = -EINVAL;
6337 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006338 }
6339 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6340 }
6341
6342 if (probe_rsp_ie_len[2] > 0)
6343 {
6344 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6345 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6346 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6347 probe_rsp_ie_len[2], NULL,
6348 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6349 {
6350 hddLog(LOGE,
6351 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006352 ret = -EINVAL;
6353 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006354 }
6355 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6356 }
6357
6358 if (probe_rsp_ie_len[1] == 0 )
6359 {
6360 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6361 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6362 eANI_BOOLEAN_FALSE) )
6363 {
6364 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006365 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006366 }
6367 }
6368
6369 if (probe_rsp_ie_len[2] == 0 )
6370 {
6371 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6372 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6373 eANI_BOOLEAN_FALSE) )
6374 {
6375 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006376 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006377 }
6378 }
6379
6380 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6381 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6382 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6383 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6384 == eHAL_STATUS_FAILURE)
6385 {
6386 hddLog(LOGE,
6387 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006388 ret = -EINVAL;
6389 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006390 }
6391 }
6392 else
6393 {
6394 // Reset WNI_CFG_PROBE_RSP Flags
6395 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
6396
6397 hddLog(VOS_TRACE_LEVEL_INFO,
6398 "%s: No Probe Response IE received in set beacon",
6399 __func__);
6400 }
6401
6402 // Added for AssocResp IE
6403 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
6404 {
6405 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6406 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
6407 params->assocresp_ies_len, NULL,
6408 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6409 {
6410 hddLog(LOGE,
6411 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006412 ret = -EINVAL;
6413 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006414 }
6415
6416 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6417 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
6418 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6419 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6420 == eHAL_STATUS_FAILURE)
6421 {
6422 hddLog(LOGE,
6423 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006424 ret = -EINVAL;
6425 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006426 }
6427 }
6428 else
6429 {
6430 hddLog(VOS_TRACE_LEVEL_INFO,
6431 "%s: No Assoc Response IE received in set beacon",
6432 __func__);
6433
6434 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6435 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6436 eANI_BOOLEAN_FALSE) )
6437 {
6438 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006439 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006440 }
6441 }
6442
Jeff Johnsone7245742012-09-05 17:12:55 -07006443done:
Jeff Johnson295189b2012-06-20 16:38:30 -07006444 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306445 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006446}
Jeff Johnson295189b2012-06-20 16:38:30 -07006447
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306448/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006449 * FUNCTION: wlan_hdd_validate_operation_channel
6450 * called by wlan_hdd_cfg80211_start_bss() and
6451 * wlan_hdd_cfg80211_set_channel()
6452 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306453 * channel list.
6454 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006455VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006456{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306457
Jeff Johnson295189b2012-06-20 16:38:30 -07006458 v_U32_t num_ch = 0;
6459 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6460 u32 indx = 0;
6461 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306462 v_U8_t fValidChannel = FALSE, count = 0;
6463 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306464
Jeff Johnson295189b2012-06-20 16:38:30 -07006465 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6466
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306467 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006468 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306469 /* Validate the channel */
6470 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006471 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306472 if ( channel == rfChannels[count].channelNum )
6473 {
6474 fValidChannel = TRUE;
6475 break;
6476 }
6477 }
6478 if (fValidChannel != TRUE)
6479 {
6480 hddLog(VOS_TRACE_LEVEL_ERROR,
6481 "%s: Invalid Channel [%d]", __func__, channel);
6482 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006483 }
6484 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306485 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006486 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306487 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6488 valid_ch, &num_ch))
6489 {
6490 hddLog(VOS_TRACE_LEVEL_ERROR,
6491 "%s: failed to get valid channel list", __func__);
6492 return VOS_STATUS_E_FAILURE;
6493 }
6494 for (indx = 0; indx < num_ch; indx++)
6495 {
6496 if (channel == valid_ch[indx])
6497 {
6498 break;
6499 }
6500 }
6501
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306502 if (indx >= num_ch)
6503 {
6504 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6505 {
6506 eCsrBand band;
6507 unsigned int freq;
6508
6509 sme_GetFreqBand(hHal, &band);
6510
6511 if (eCSR_BAND_5G == band)
6512 {
6513#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6514 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6515 {
6516 freq = ieee80211_channel_to_frequency(channel,
6517 IEEE80211_BAND_2GHZ);
6518 }
6519 else
6520 {
6521 freq = ieee80211_channel_to_frequency(channel,
6522 IEEE80211_BAND_5GHZ);
6523 }
6524#else
6525 freq = ieee80211_channel_to_frequency(channel);
6526#endif
6527 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6528 return VOS_STATUS_SUCCESS;
6529 }
6530 }
6531
6532 hddLog(VOS_TRACE_LEVEL_ERROR,
6533 "%s: Invalid Channel [%d]", __func__, channel);
6534 return VOS_STATUS_E_FAILURE;
6535 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006536 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306537
Jeff Johnson295189b2012-06-20 16:38:30 -07006538 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306539
Jeff Johnson295189b2012-06-20 16:38:30 -07006540}
6541
Viral Modi3a32cc52013-02-08 11:14:52 -08006542/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306543 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08006544 * This function is used to set the channel number
6545 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306546static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08006547 struct ieee80211_channel *chan,
6548 enum nl80211_channel_type channel_type
6549 )
6550{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306551 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006552 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006553 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006554 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306555 hdd_context_t *pHddCtx;
6556 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006557
6558 ENTER();
6559
6560 if( NULL == dev )
6561 {
6562 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006563 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006564 return -ENODEV;
6565 }
6566 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306567
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306568 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6569 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6570 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006571 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306572 "%s: device_mode = %s (%d) freq = %d", __func__,
6573 hdd_device_modetoString(pAdapter->device_mode),
6574 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306575
6576 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6577 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306578 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006579 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306580 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006581 }
6582
6583 /*
6584 * Do freq to chan conversion
6585 * TODO: for 11a
6586 */
6587
6588 channel = ieee80211_frequency_to_channel(freq);
6589
6590 /* Check freq range */
6591 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6592 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6593 {
6594 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006595 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006596 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6597 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6598 return -EINVAL;
6599 }
6600
6601 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6602
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306603 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6604 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006605 {
6606 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6607 {
6608 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006609 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006610 return -EINVAL;
6611 }
6612 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6613 "%s: set channel to [%d] for device mode =%d",
6614 __func__, channel,pAdapter->device_mode);
6615 }
6616 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006617 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006618 )
6619 {
6620 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6621 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6622 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6623
6624 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6625 {
6626 /* Link is up then return cant set channel*/
6627 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006628 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006629 return -EINVAL;
6630 }
6631
6632 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6633 pHddStaCtx->conn_info.operationChannel = channel;
6634 pRoamProfile->ChannelInfo.ChannelList =
6635 &pHddStaCtx->conn_info.operationChannel;
6636 }
6637 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006638 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006639 )
6640 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306641 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6642 {
6643 if(VOS_STATUS_SUCCESS !=
6644 wlan_hdd_validate_operation_channel(pAdapter,channel))
6645 {
6646 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006647 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306648 return -EINVAL;
6649 }
6650 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6651 }
6652 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006653 {
6654 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6655
6656 /* If auto channel selection is configured as enable/ 1 then ignore
6657 channel set by supplicant
6658 */
6659 if ( cfg_param->apAutoChannelSelection )
6660 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306661 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6662 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006663 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306664 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6665 __func__, hdd_device_modetoString(pAdapter->device_mode),
6666 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006667 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306668 else
6669 {
6670 if(VOS_STATUS_SUCCESS !=
6671 wlan_hdd_validate_operation_channel(pAdapter,channel))
6672 {
6673 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006674 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306675 return -EINVAL;
6676 }
6677 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6678 }
Viral Modi3a32cc52013-02-08 11:14:52 -08006679 }
6680 }
6681 else
6682 {
6683 hddLog(VOS_TRACE_LEVEL_FATAL,
6684 "%s: Invalid device mode failed to set valid channel", __func__);
6685 return -EINVAL;
6686 }
6687 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306688 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006689}
6690
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306691static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
6692 struct net_device *dev,
6693 struct ieee80211_channel *chan,
6694 enum nl80211_channel_type channel_type
6695 )
6696{
6697 int ret;
6698
6699 vos_ssr_protect(__func__);
6700 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
6701 vos_ssr_unprotect(__func__);
6702
6703 return ret;
6704}
6705
Jeff Johnson295189b2012-06-20 16:38:30 -07006706#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6707static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6708 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006709#else
6710static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6711 struct cfg80211_beacon_data *params,
6712 const u8 *ssid, size_t ssid_len,
6713 enum nl80211_hidden_ssid hidden_ssid)
6714#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006715{
6716 tsap_Config_t *pConfig;
6717 beacon_data_t *pBeacon = NULL;
6718 struct ieee80211_mgmt *pMgmt_frame;
6719 v_U8_t *pIe=NULL;
6720 v_U16_t capab_info;
6721 eCsrAuthType RSNAuthType;
6722 eCsrEncryptionType RSNEncryptType;
6723 eCsrEncryptionType mcRSNEncryptType;
6724 int status = VOS_STATUS_SUCCESS;
6725 tpWLAN_SAPEventCB pSapEventCallback;
6726 hdd_hostapd_state_t *pHostapdState;
6727 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
6728 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306729 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006730 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306731 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07006732 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08006733 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05306734 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07006735 v_BOOL_t MFPCapable = VOS_FALSE;
6736 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05306737 v_BOOL_t sapEnable11AC =
6738 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07006739 ENTER();
6740
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306741 iniConfig = pHddCtx->cfg_ini;
6742
Jeff Johnson295189b2012-06-20 16:38:30 -07006743 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
6744
6745 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6746
6747 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6748
6749 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6750
6751 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
6752
6753 //channel is already set in the set_channel Call back
6754 //pConfig->channel = pCommitConfig->channel;
6755
6756 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306757 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07006758 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
6759
6760 pConfig->dtim_period = pBeacon->dtim_period;
6761
Arif Hussain6d2a3322013-11-17 19:50:10 -08006762 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07006763 pConfig->dtim_period);
6764
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08006765 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07006766 {
6767 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006768 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05306769 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
6770 {
6771 tANI_BOOLEAN restartNeeded;
6772 pConfig->ieee80211d = 1;
6773 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
6774 sme_setRegInfo(hHal, pConfig->countryCode);
6775 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
6776 }
6777 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006778 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07006779 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07006780 pConfig->ieee80211d = 1;
6781 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
6782 sme_setRegInfo(hHal, pConfig->countryCode);
6783 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07006784 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006785 else
6786 {
6787 pConfig->ieee80211d = 0;
6788 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306789 /*
6790 * If auto channel is configured i.e. channel is 0,
6791 * so skip channel validation.
6792 */
6793 if( AUTO_CHANNEL_SELECT != pConfig->channel )
6794 {
6795 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
6796 {
6797 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006798 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306799 return -EINVAL;
6800 }
6801 }
6802 else
6803 {
6804 if(1 != pHddCtx->is_dynamic_channel_range_set)
6805 {
6806 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
6807 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
6808 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
6809 }
6810 pHddCtx->is_dynamic_channel_range_set = 0;
6811 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006812 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006813 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006814 {
6815 pConfig->ieee80211d = 0;
6816 }
6817 pConfig->authType = eSAP_AUTO_SWITCH;
6818
6819 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306820
6821 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07006822 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
6823
6824 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
6825
6826 /*Set wps station to configured*/
6827 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
6828
6829 if(pIe)
6830 {
6831 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
6832 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006833 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07006834 return -EINVAL;
6835 }
6836 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
6837 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006838 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07006839 /* Check 15 bit of WPS IE as it contain information for wps state
6840 * WPS state
6841 */
6842 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
6843 {
6844 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
6845 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
6846 {
6847 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
6848 }
6849 }
6850 }
6851 else
6852 {
6853 pConfig->wps_state = SAP_WPS_DISABLED;
6854 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306855 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07006856
c_hpothufe599e92014-06-16 11:38:55 +05306857 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6858 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6859 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
6860 eCSR_ENCRYPT_TYPE_NONE;
6861
Jeff Johnson295189b2012-06-20 16:38:30 -07006862 pConfig->RSNWPAReqIELength = 0;
6863 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306864 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006865 WLAN_EID_RSN);
6866 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306867 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006868 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6869 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6870 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306871 /* The actual processing may eventually be more extensive than
6872 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07006873 * by the app.
6874 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306875 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006876 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6877 &RSNEncryptType,
6878 &mcRSNEncryptType,
6879 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006880 &MFPCapable,
6881 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006882 pConfig->pRSNWPAReqIE[1]+2,
6883 pConfig->pRSNWPAReqIE );
6884
6885 if( VOS_STATUS_SUCCESS == status )
6886 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306887 /* Now copy over all the security attributes you have
6888 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006889 * */
6890 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6891 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6892 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6893 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306894 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006895 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006896 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6897 }
6898 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306899
Jeff Johnson295189b2012-06-20 16:38:30 -07006900 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6901 pBeacon->tail, pBeacon->tail_len);
6902
6903 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
6904 {
6905 if (pConfig->pRSNWPAReqIE)
6906 {
6907 /*Mixed mode WPA/WPA2*/
6908 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
6909 pConfig->RSNWPAReqIELength += pIe[1] + 2;
6910 }
6911 else
6912 {
6913 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6914 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6915 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306916 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006917 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6918 &RSNEncryptType,
6919 &mcRSNEncryptType,
6920 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006921 &MFPCapable,
6922 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006923 pConfig->pRSNWPAReqIE[1]+2,
6924 pConfig->pRSNWPAReqIE );
6925
6926 if( VOS_STATUS_SUCCESS == status )
6927 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306928 /* Now copy over all the security attributes you have
6929 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006930 * */
6931 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6932 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6933 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6934 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306935 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006936 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006937 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6938 }
6939 }
6940 }
6941
Jeff Johnson4416a782013-03-25 14:17:50 -07006942 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
6943 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
6944 return -EINVAL;
6945 }
6946
Jeff Johnson295189b2012-06-20 16:38:30 -07006947 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
6948
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006949#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006950 if (params->ssid != NULL)
6951 {
6952 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
6953 pConfig->SSIDinfo.ssid.length = params->ssid_len;
6954 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6955 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6956 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006957#else
6958 if (ssid != NULL)
6959 {
6960 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
6961 pConfig->SSIDinfo.ssid.length = ssid_len;
6962 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6963 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6964 }
6965#endif
6966
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306967 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07006968 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306969
Jeff Johnson295189b2012-06-20 16:38:30 -07006970 /* default value */
6971 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
6972 pConfig->num_accept_mac = 0;
6973 pConfig->num_deny_mac = 0;
6974
6975 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6976 pBeacon->tail, pBeacon->tail_len);
6977
6978 /* pIe for black list is following form:
6979 type : 1 byte
6980 length : 1 byte
6981 OUI : 4 bytes
6982 acl type : 1 byte
6983 no of mac addr in black list: 1 byte
6984 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306985 */
6986 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006987 {
6988 pConfig->SapMacaddr_acl = pIe[6];
6989 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006990 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006991 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306992 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
6993 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006994 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6995 for (i = 0; i < pConfig->num_deny_mac; i++)
6996 {
6997 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6998 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306999 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007000 }
7001 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7002 pBeacon->tail, pBeacon->tail_len);
7003
7004 /* pIe for white list is following form:
7005 type : 1 byte
7006 length : 1 byte
7007 OUI : 4 bytes
7008 acl type : 1 byte
7009 no of mac addr in white list: 1 byte
7010 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307011 */
7012 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007013 {
7014 pConfig->SapMacaddr_acl = pIe[6];
7015 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007016 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007017 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307018 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7019 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007020 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7021 for (i = 0; i < pConfig->num_accept_mac; i++)
7022 {
7023 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7024 acl_entry++;
7025 }
7026 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307027
Jeff Johnson295189b2012-06-20 16:38:30 -07007028 wlan_hdd_set_sapHwmode(pHostapdAdapter);
7029
Jeff Johnsone7245742012-09-05 17:12:55 -07007030#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007031 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307032 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
7033 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05307034 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
7035 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007036 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
7037 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307038 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
7039 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07007040 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307041 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07007042 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307043 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007044
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307045 /* If ACS disable and selected channel <= 14
7046 * OR
7047 * ACS enabled and ACS operating band is choosen as 2.4
7048 * AND
7049 * VHT in 2.4G Disabled
7050 * THEN
7051 * Fallback to 11N mode
7052 */
7053 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
7054 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05307055 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307056 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007057 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307058 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
7059 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007060 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
7061 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007062 }
7063#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307064
Jeff Johnson295189b2012-06-20 16:38:30 -07007065 // ht_capab is not what the name conveys,this is used for protection bitmap
7066 pConfig->ht_capab =
7067 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
7068
7069 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
7070 {
7071 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7072 return -EINVAL;
7073 }
7074
7075 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307076 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07007077 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
7078 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307079 pConfig->obssProtEnabled =
7080 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07007081
Chet Lanctot8cecea22014-02-11 19:09:36 -08007082#ifdef WLAN_FEATURE_11W
7083 pConfig->mfpCapable = MFPCapable;
7084 pConfig->mfpRequired = MFPRequired;
7085 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
7086 pConfig->mfpCapable, pConfig->mfpRequired);
7087#endif
7088
Arif Hussain6d2a3322013-11-17 19:50:10 -08007089 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07007090 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007091 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
7092 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7093 (int)pConfig->channel);
7094 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
7095 pConfig->SapHw_mode, pConfig->privacy,
7096 pConfig->authType);
7097 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
7098 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7099 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7100 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07007101
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307102 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007103 {
7104 //Bss already started. just return.
7105 //TODO Probably it should update some beacon params.
7106 hddLog( LOGE, "Bss Already started...Ignore the request");
7107 EXIT();
7108 return 0;
7109 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307110
Agarwal Ashish51325b52014-06-16 16:50:49 +05307111 if (vos_max_concurrent_connections_reached()) {
7112 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7113 return -EINVAL;
7114 }
7115
Jeff Johnson295189b2012-06-20 16:38:30 -07007116 pConfig->persona = pHostapdAdapter->device_mode;
7117
Peng Xu2446a892014-09-05 17:21:18 +05307118 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
7119 if ( NULL != psmeConfig)
7120 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307121 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05307122 sme_GetConfigParam(hHal, psmeConfig);
7123 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307124#ifdef WLAN_FEATURE_AP_HT40_24G
7125 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7126 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
7127 && pHddCtx->cfg_ini->apHT40_24GEnabled)
7128 {
7129 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
7130 sme_UpdateConfig (hHal, psmeConfig);
7131 }
7132#endif
Peng Xu2446a892014-09-05 17:21:18 +05307133 vos_mem_free(psmeConfig);
7134 }
Peng Xuafc34e32014-09-25 13:23:55 +05307135 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05307136
Jeff Johnson295189b2012-06-20 16:38:30 -07007137 pSapEventCallback = hdd_hostapd_SAPEventCB;
7138 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
7139 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
7140 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007141 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007142 return -EINVAL;
7143 }
7144
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307145 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07007146 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7147
7148 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307149
Jeff Johnson295189b2012-06-20 16:38:30 -07007150 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307151 {
7152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007153 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07007154 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07007155 VOS_ASSERT(0);
7156 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307157
Jeff Johnson295189b2012-06-20 16:38:30 -07007158 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05307159 /* Initialize WMM configuation */
7160 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307161 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007162
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007163#ifdef WLAN_FEATURE_P2P_DEBUG
7164 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
7165 {
7166 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
7167 {
7168 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7169 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007170 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007171 }
7172 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
7173 {
7174 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7175 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007176 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007177 }
7178 }
7179#endif
7180
Jeff Johnson295189b2012-06-20 16:38:30 -07007181 pHostapdState->bCommit = TRUE;
7182 EXIT();
7183
7184 return 0;
7185}
7186
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007187#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307188static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307189 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007190 struct beacon_parameters *params)
7191{
7192 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307193 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307194 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007195
7196 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307197
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307198 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7199 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
7200 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307201 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
7202 hdd_device_modetoString(pAdapter->device_mode),
7203 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007204
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307205 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7206 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307207 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007208 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307209 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007210 }
7211
Agarwal Ashish51325b52014-06-16 16:50:49 +05307212 if (vos_max_concurrent_connections_reached()) {
7213 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7214 return -EINVAL;
7215 }
7216
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307217 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007218 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007219 )
7220 {
7221 beacon_data_t *old,*new;
7222
7223 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307224
Jeff Johnson295189b2012-06-20 16:38:30 -07007225 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307226 {
7227 hddLog(VOS_TRACE_LEVEL_WARN,
7228 FL("already beacon info added to session(%d)"),
7229 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007230 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307231 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007232
7233 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7234
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307235 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07007236 {
7237 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007238 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007239 return -EINVAL;
7240 }
7241
7242 pAdapter->sessionCtx.ap.beacon = new;
7243
7244 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7245 }
7246
7247 EXIT();
7248 return status;
7249}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307250
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307251static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
7252 struct net_device *dev,
7253 struct beacon_parameters *params)
7254{
7255 int ret;
7256
7257 vos_ssr_protect(__func__);
7258 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
7259 vos_ssr_unprotect(__func__);
7260
7261 return ret;
7262}
7263
7264static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007265 struct net_device *dev,
7266 struct beacon_parameters *params)
7267{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307268 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307269 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7270 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307271 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007272
7273 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307274
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307275 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7276 TRACE_CODE_HDD_CFG80211_SET_BEACON,
7277 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
7278 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7279 __func__, hdd_device_modetoString(pAdapter->device_mode),
7280 pAdapter->device_mode);
7281
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307282 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7283 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307284 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007285 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307286 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007287 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307288
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307289 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007290 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307291 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007292 {
7293 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307294
Jeff Johnson295189b2012-06-20 16:38:30 -07007295 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307296
Jeff Johnson295189b2012-06-20 16:38:30 -07007297 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307298 {
7299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7300 FL("session(%d) old and new heads points to NULL"),
7301 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007302 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307303 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007304
7305 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7306
7307 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307308 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007309 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007310 return -EINVAL;
7311 }
7312
7313 pAdapter->sessionCtx.ap.beacon = new;
7314
7315 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7316 }
7317
7318 EXIT();
7319 return status;
7320}
7321
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307322static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
7323 struct net_device *dev,
7324 struct beacon_parameters *params)
7325{
7326 int ret;
7327
7328 vos_ssr_protect(__func__);
7329 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
7330 vos_ssr_unprotect(__func__);
7331
7332 return ret;
7333}
7334
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007335#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7336
7337#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307338static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007339 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007340#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307341static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007342 struct net_device *dev)
7343#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007344{
7345 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07007346 hdd_context_t *pHddCtx = NULL;
7347 hdd_scaninfo_t *pScanInfo = NULL;
7348 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307349 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307350 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007351
7352 ENTER();
7353
7354 if (NULL == pAdapter)
7355 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007357 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007358 return -ENODEV;
7359 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007360
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307361 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7362 TRACE_CODE_HDD_CFG80211_STOP_AP,
7363 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307364 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7365 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307366 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007367 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307368 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07007369 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007370
7371 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
7372 if (NULL == staAdapter)
7373 {
7374 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
7375 if (NULL == staAdapter)
7376 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07007377 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7378 "%s: HDD adapter context for STA/P2P-CLI is Null",
7379 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007380 }
7381 }
7382
7383 pScanInfo = &pHddCtx->scan_info;
7384
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307385 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7386 __func__, hdd_device_modetoString(pAdapter->device_mode),
7387 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007388
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307389 ret = wlan_hdd_scan_abort(pAdapter);
7390
Girish Gowli4bf7a632014-06-12 13:42:11 +05307391 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07007392 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307393 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7394 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307395
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307396 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07007397 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7399 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08007400
Jeff Johnsone7245742012-09-05 17:12:55 -07007401 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307402 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07007403 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307404 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07007405 }
7406
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05307407 /* Delete all associated STAs before stopping AP/P2P GO */
7408 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05307409 hdd_hostapd_stop(dev);
7410
Jeff Johnson295189b2012-06-20 16:38:30 -07007411 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007412 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007413 )
7414 {
7415 beacon_data_t *old;
7416
7417 old = pAdapter->sessionCtx.ap.beacon;
7418
7419 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307420 {
7421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7422 FL("session(%d) beacon data points to NULL"),
7423 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007424 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307425 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007426
Jeff Johnson295189b2012-06-20 16:38:30 -07007427 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007428
7429 mutex_lock(&pHddCtx->sap_lock);
7430 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7431 {
Jeff Johnson4416a782013-03-25 14:17:50 -07007432 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007433 {
7434 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7435
7436 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7437
7438 if (!VOS_IS_STATUS_SUCCESS(status))
7439 {
7440 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007441 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007442 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307443 }
7444 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007445 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307446 /* BSS stopped, clear the active sessions for this device mode */
7447 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007448 }
7449 mutex_unlock(&pHddCtx->sap_lock);
7450
7451 if(status != VOS_STATUS_SUCCESS)
7452 {
7453 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007454 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007455 return -EINVAL;
7456 }
7457
Jeff Johnson4416a782013-03-25 14:17:50 -07007458 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007459 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
7460 ==eHAL_STATUS_FAILURE)
7461 {
7462 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007463 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007464 }
7465
Jeff Johnson4416a782013-03-25 14:17:50 -07007466 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007467 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7468 eANI_BOOLEAN_FALSE) )
7469 {
7470 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007471 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007472 }
7473
7474 // Reset WNI_CFG_PROBE_RSP Flags
7475 wlan_hdd_reset_prob_rspies(pAdapter);
7476
7477 pAdapter->sessionCtx.ap.beacon = NULL;
7478 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007479#ifdef WLAN_FEATURE_P2P_DEBUG
7480 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7481 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
7482 {
7483 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
7484 "GO got removed");
7485 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
7486 }
7487#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007488 }
7489 EXIT();
7490 return status;
7491}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007492
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307493#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7494static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
7495 struct net_device *dev)
7496{
7497 int ret;
7498
7499 vos_ssr_protect(__func__);
7500 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
7501 vos_ssr_unprotect(__func__);
7502
7503 return ret;
7504}
7505#else
7506static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7507 struct net_device *dev)
7508{
7509 int ret;
7510
7511 vos_ssr_protect(__func__);
7512 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7513 vos_ssr_unprotect(__func__);
7514
7515 return ret;
7516}
7517#endif
7518
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007519#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7520
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307521static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307522 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007523 struct cfg80211_ap_settings *params)
7524{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307525 hdd_adapter_t *pAdapter;
7526 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307527 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007528
7529 ENTER();
7530
Girish Gowlib143d7a2015-02-18 19:39:55 +05307531 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007532 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05307534 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307535 return -ENODEV;
7536 }
7537
7538 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7539 if (NULL == pAdapter)
7540 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307541 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307542 "%s: HDD adapter is Null", __func__);
7543 return -ENODEV;
7544 }
7545
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307546 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7547 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
7548 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307549 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7550 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307552 "%s: HDD adapter magic is invalid", __func__);
7553 return -ENODEV;
7554 }
7555
7556 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307557 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307558 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307559 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307560 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307561 }
7562
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307563 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7564 __func__, hdd_device_modetoString(pAdapter->device_mode),
7565 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307566
7567 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007568 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007569 )
7570 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307571 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007572
7573 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307574
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007575 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307576 {
7577 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7578 FL("already beacon info added to session(%d)"),
7579 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007580 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307581 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007582
Girish Gowlib143d7a2015-02-18 19:39:55 +05307583#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7584 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7585 &new,
7586 &params->beacon);
7587#else
7588 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7589 &new,
7590 &params->beacon,
7591 params->dtim_period);
7592#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007593
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307594 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007595 {
7596 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307597 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007598 return -EINVAL;
7599 }
7600 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007601#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007602 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7603#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7604 params->channel, params->channel_type);
7605#else
7606 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7607#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007608#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007609 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
7610 params->ssid_len, params->hidden_ssid);
7611 }
7612
7613 EXIT();
7614 return status;
7615}
7616
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307617static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7618 struct net_device *dev,
7619 struct cfg80211_ap_settings *params)
7620{
7621 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007622
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307623 vos_ssr_protect(__func__);
7624 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
7625 vos_ssr_unprotect(__func__);
7626
7627 return ret;
7628}
7629
7630static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007631 struct net_device *dev,
7632 struct cfg80211_beacon_data *params)
7633{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307634 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307635 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307636 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007637
7638 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307639
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307640 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7641 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7642 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007643 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007644 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307645
7646 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7647 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307648 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007649 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307650 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007651 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007652
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307653 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007654 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307655 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007656 {
7657 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307658
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007659 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307660
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007661 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307662 {
7663 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7664 FL("session(%d) beacon data points to NULL"),
7665 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007666 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307667 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007668
7669 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
7670
7671 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307672 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007673 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007674 return -EINVAL;
7675 }
7676
7677 pAdapter->sessionCtx.ap.beacon = new;
7678
7679 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
7680 }
7681
7682 EXIT();
7683 return status;
7684}
7685
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307686static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
7687 struct net_device *dev,
7688 struct cfg80211_beacon_data *params)
7689{
7690 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007691
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307692 vos_ssr_protect(__func__);
7693 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
7694 vos_ssr_unprotect(__func__);
7695
7696 return ret;
7697}
7698
7699#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007700
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307701static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007702 struct net_device *dev,
7703 struct bss_parameters *params)
7704{
7705 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307706 hdd_context_t *pHddCtx;
7707 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007708
7709 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307710
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307711 if (NULL == pAdapter)
7712 {
7713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7714 "%s: HDD adapter is Null", __func__);
7715 return -ENODEV;
7716 }
7717 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307718 ret = wlan_hdd_validate_context(pHddCtx);
7719 if (0 != ret)
7720 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307721 return ret;
7722 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307723 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7724 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
7725 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307726 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7727 __func__, hdd_device_modetoString(pAdapter->device_mode),
7728 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007729
7730 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007731 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307732 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007733 {
7734 /* ap_isolate == -1 means that in change bss, upper layer doesn't
7735 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307736 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07007737 {
7738 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307739 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007740 }
7741
7742 EXIT();
7743 return 0;
7744}
7745
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307746static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
7747 struct net_device *dev,
7748 struct bss_parameters *params)
7749{
7750 int ret;
7751
7752 vos_ssr_protect(__func__);
7753 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
7754 vos_ssr_unprotect(__func__);
7755
7756 return ret;
7757}
Kiet Lam10841362013-11-01 11:36:50 +05307758/* FUNCTION: wlan_hdd_change_country_code_cd
7759* to wait for contry code completion
7760*/
7761void* wlan_hdd_change_country_code_cb(void *pAdapter)
7762{
7763 hdd_adapter_t *call_back_pAdapter = pAdapter;
7764 complete(&call_back_pAdapter->change_country_code);
7765 return NULL;
7766}
7767
Jeff Johnson295189b2012-06-20 16:38:30 -07007768/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307769 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07007770 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
7771 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307772int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007773 struct net_device *ndev,
7774 enum nl80211_iftype type,
7775 u32 *flags,
7776 struct vif_params *params
7777 )
7778{
7779 struct wireless_dev *wdev;
7780 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007781 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07007782 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007783 tCsrRoamProfile *pRoamProfile = NULL;
7784 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307785 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007786 eMib_dot11DesiredBssType connectedBssType;
7787 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307788 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007789
7790 ENTER();
7791
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307792 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007793 {
7794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7795 "%s: Adapter context is null", __func__);
7796 return VOS_STATUS_E_FAILURE;
7797 }
7798
7799 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7800 if (!pHddCtx)
7801 {
7802 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7803 "%s: HDD context is null", __func__);
7804 return VOS_STATUS_E_FAILURE;
7805 }
7806
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307807 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7808 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
7809 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307810 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307811 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007812 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307813 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007814 }
7815
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307816 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7817 __func__, hdd_device_modetoString(pAdapter->device_mode),
7818 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007819
Agarwal Ashish51325b52014-06-16 16:50:49 +05307820 if (vos_max_concurrent_connections_reached()) {
7821 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7822 return -EINVAL;
7823 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307824 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007825 wdev = ndev->ieee80211_ptr;
7826
7827#ifdef WLAN_BTAMP_FEATURE
7828 if((NL80211_IFTYPE_P2P_CLIENT == type)||
7829 (NL80211_IFTYPE_ADHOC == type)||
7830 (NL80211_IFTYPE_AP == type)||
7831 (NL80211_IFTYPE_P2P_GO == type))
7832 {
7833 pHddCtx->isAmpAllowed = VOS_FALSE;
7834 // stop AMP traffic
7835 status = WLANBAP_StopAmp();
7836 if(VOS_STATUS_SUCCESS != status )
7837 {
7838 pHddCtx->isAmpAllowed = VOS_TRUE;
7839 hddLog(VOS_TRACE_LEVEL_FATAL,
7840 "%s: Failed to stop AMP", __func__);
7841 return -EINVAL;
7842 }
7843 }
7844#endif //WLAN_BTAMP_FEATURE
7845 /* Reset the current device mode bit mask*/
7846 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7847
7848 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007849 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07007850 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07007851 )
7852 {
7853 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007854 if (!pWextState)
7855 {
7856 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7857 "%s: pWextState is null", __func__);
7858 return VOS_STATUS_E_FAILURE;
7859 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007860 pRoamProfile = &pWextState->roamProfile;
7861 LastBSSType = pRoamProfile->BSSType;
7862
7863 switch (type)
7864 {
7865 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007866 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007867 hddLog(VOS_TRACE_LEVEL_INFO,
7868 "%s: setting interface Type to INFRASTRUCTURE", __func__);
7869 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07007870#ifdef WLAN_FEATURE_11AC
7871 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
7872 {
7873 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
7874 }
7875#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307876 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07007877 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007878 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007879 //Check for sub-string p2p to confirm its a p2p interface
7880 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307881 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007882 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7883 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7884 }
7885 else
7886 {
7887 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007888 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007889 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007890 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05307891
Jeff Johnson295189b2012-06-20 16:38:30 -07007892 case NL80211_IFTYPE_ADHOC:
7893 hddLog(VOS_TRACE_LEVEL_INFO,
7894 "%s: setting interface Type to ADHOC", __func__);
7895 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
7896 pRoamProfile->phyMode =
7897 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07007898 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007899 wdev->iftype = type;
7900 break;
7901
7902 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007903 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007904 {
7905 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7906 "%s: setting interface Type to %s", __func__,
7907 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
7908
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007909 //Cancel any remain on channel for GO mode
7910 if (NL80211_IFTYPE_P2P_GO == type)
7911 {
7912 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
7913 }
Mohit Khanna0f232092012-09-11 14:46:08 -07007914 if (NL80211_IFTYPE_AP == type)
7915 {
7916 /* As Loading WLAN Driver one interface being created for p2p device
7917 * address. This will take one HW STA and the max number of clients
7918 * that can connect to softAP will be reduced by one. so while changing
7919 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
7920 * interface as it is not required in SoftAP mode.
7921 */
7922
7923 // Get P2P Adapter
7924 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
7925
7926 if (pP2pAdapter)
7927 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307928 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05307929 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07007930 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
7931 }
7932 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05307933 //Disable IMPS & BMPS for SAP/GO
7934 if(VOS_STATUS_E_FAILURE ==
7935 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
7936 {
7937 //Fail to Exit BMPS
7938 VOS_ASSERT(0);
7939 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05307940
7941 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
7942
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307943#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07007944
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307945 /* A Mutex Lock is introduced while changing the mode to
7946 * protect the concurrent access for the Adapters by TDLS
7947 * module.
7948 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307949 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307950#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007951 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05307952 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07007953 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07007954 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7955 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307956#ifdef FEATURE_WLAN_TDLS
7957 mutex_unlock(&pHddCtx->tdls_lock);
7958#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007959 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
7960 (pConfig->apRandomBssidEnabled))
7961 {
7962 /* To meet Android requirements create a randomized
7963 MAC address of the form 02:1A:11:Fx:xx:xx */
7964 get_random_bytes(&ndev->dev_addr[3], 3);
7965 ndev->dev_addr[0] = 0x02;
7966 ndev->dev_addr[1] = 0x1A;
7967 ndev->dev_addr[2] = 0x11;
7968 ndev->dev_addr[3] |= 0xF0;
7969 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
7970 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08007971 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
7972 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007973 }
7974
Jeff Johnson295189b2012-06-20 16:38:30 -07007975 hdd_set_ap_ops( pAdapter->dev );
7976
Kiet Lam10841362013-11-01 11:36:50 +05307977 /* This is for only SAP mode where users can
7978 * control country through ini.
7979 * P2P GO follows station country code
7980 * acquired during the STA scanning. */
7981 if((NL80211_IFTYPE_AP == type) &&
7982 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
7983 {
7984 int status = 0;
7985 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
7986 "%s: setting country code from INI ", __func__);
7987 init_completion(&pAdapter->change_country_code);
7988 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
7989 (void *)(tSmeChangeCountryCallback)
7990 wlan_hdd_change_country_code_cb,
7991 pConfig->apCntryCode, pAdapter,
7992 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05307993 eSIR_FALSE,
7994 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05307995 if (eHAL_STATUS_SUCCESS == status)
7996 {
7997 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307998 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05307999 &pAdapter->change_country_code,
8000 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308001 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05308002 {
8003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308004 FL("SME Timed out while setting country code %ld"),
8005 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08008006
8007 if (pHddCtx->isLogpInProgress)
8008 {
8009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8010 "%s: LOGP in Progress. Ignore!!!", __func__);
8011 return -EAGAIN;
8012 }
Kiet Lam10841362013-11-01 11:36:50 +05308013 }
8014 }
8015 else
8016 {
8017 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008018 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05308019 return -EINVAL;
8020 }
8021 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008022 status = hdd_init_ap_mode(pAdapter);
8023 if(status != VOS_STATUS_SUCCESS)
8024 {
8025 hddLog(VOS_TRACE_LEVEL_FATAL,
8026 "%s: Error initializing the ap mode", __func__);
8027 return -EINVAL;
8028 }
8029 hdd_set_conparam(1);
8030
Jeff Johnson295189b2012-06-20 16:38:30 -07008031 /*interface type changed update in wiphy structure*/
8032 if(wdev)
8033 {
8034 wdev->iftype = type;
8035 pHddCtx->change_iface = type;
8036 }
8037 else
8038 {
8039 hddLog(VOS_TRACE_LEVEL_ERROR,
8040 "%s: ERROR !!!! Wireless dev is NULL", __func__);
8041 return -EINVAL;
8042 }
8043 goto done;
8044 }
8045
8046 default:
8047 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8048 __func__);
8049 return -EOPNOTSUPP;
8050 }
8051 }
8052 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008053 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008054 )
8055 {
8056 switch(type)
8057 {
8058 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008059 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008060 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05308061
8062 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308063#ifdef FEATURE_WLAN_TDLS
8064
8065 /* A Mutex Lock is introduced while changing the mode to
8066 * protect the concurrent access for the Adapters by TDLS
8067 * module.
8068 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308069 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308070#endif
c_hpothu002231a2015-02-05 14:58:51 +05308071 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008072 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008073 //Check for sub-string p2p to confirm its a p2p interface
8074 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008075 {
8076 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8077 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8078 }
8079 else
8080 {
8081 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008082 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008083 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008084 hdd_set_conparam(0);
8085 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008086 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
8087 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308088#ifdef FEATURE_WLAN_TDLS
8089 mutex_unlock(&pHddCtx->tdls_lock);
8090#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308091 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008092 if( VOS_STATUS_SUCCESS != status )
8093 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07008094 /* In case of JB, for P2P-GO, only change interface will be called,
8095 * This is the right place to enable back bmps_imps()
8096 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308097 if (pHddCtx->hdd_wlan_suspended)
8098 {
8099 hdd_set_pwrparams(pHddCtx);
8100 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008101 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008102 goto done;
8103 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008104 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008105 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008106 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8107 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008108 goto done;
8109 default:
8110 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8111 __func__);
8112 return -EOPNOTSUPP;
8113
8114 }
8115
8116 }
8117 else
8118 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308119 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
8120 __func__, hdd_device_modetoString(pAdapter->device_mode),
8121 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008122 return -EOPNOTSUPP;
8123 }
8124
8125
8126 if(pRoamProfile)
8127 {
8128 if ( LastBSSType != pRoamProfile->BSSType )
8129 {
8130 /*interface type changed update in wiphy structure*/
8131 wdev->iftype = type;
8132
8133 /*the BSS mode changed, We need to issue disconnect
8134 if connected or in IBSS disconnect state*/
8135 if ( hdd_connGetConnectedBssType(
8136 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
8137 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
8138 {
8139 /*need to issue a disconnect to CSR.*/
8140 INIT_COMPLETION(pAdapter->disconnect_comp_var);
8141 if( eHAL_STATUS_SUCCESS ==
8142 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
8143 pAdapter->sessionId,
8144 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
8145 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308146 ret = wait_for_completion_interruptible_timeout(
8147 &pAdapter->disconnect_comp_var,
8148 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
8149 if (ret <= 0)
8150 {
8151 hddLog(VOS_TRACE_LEVEL_ERROR,
8152 FL("wait on disconnect_comp_var failed %ld"), ret);
8153 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008154 }
8155 }
8156 }
8157 }
8158
8159done:
8160 /*set bitmask based on updated value*/
8161 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07008162
8163 /* Only STA mode support TM now
8164 * all other mode, TM feature should be disabled */
8165 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
8166 (~VOS_STA & pHddCtx->concurrency_mode) )
8167 {
8168 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
8169 }
8170
Jeff Johnson295189b2012-06-20 16:38:30 -07008171#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308172 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05308173 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07008174 {
8175 //we are ok to do AMP
8176 pHddCtx->isAmpAllowed = VOS_TRUE;
8177 }
8178#endif //WLAN_BTAMP_FEATURE
8179 EXIT();
8180 return 0;
8181}
8182
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308183/*
8184 * FUNCTION: wlan_hdd_cfg80211_change_iface
8185 * wrapper function to protect the actual implementation from SSR.
8186 */
8187int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
8188 struct net_device *ndev,
8189 enum nl80211_iftype type,
8190 u32 *flags,
8191 struct vif_params *params
8192 )
8193{
8194 int ret;
8195
8196 vos_ssr_protect(__func__);
8197 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
8198 vos_ssr_unprotect(__func__);
8199
8200 return ret;
8201}
8202
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008203#ifdef FEATURE_WLAN_TDLS
8204static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
8205 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
8206{
8207 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8208 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8209 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008210 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308211 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308212 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008213
8214 ENTER();
8215
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308216 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008217 {
8218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8219 "Invalid arguments");
8220 return -EINVAL;
8221 }
Hoonki Lee27511902013-03-14 18:19:06 -07008222
8223 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
8224 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
8225 {
8226 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8227 "%s: TDLS mode is disabled OR not enabled in FW."
8228 MAC_ADDRESS_STR " Request declined.",
8229 __func__, MAC_ADDR_ARRAY(mac));
8230 return -ENOTSUPP;
8231 }
8232
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008233 if (pHddCtx->isLogpInProgress)
8234 {
8235 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8236 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05308237 wlan_hdd_tdls_set_link_status(pAdapter,
8238 mac,
8239 eTDLS_LINK_IDLE,
8240 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008241 return -EBUSY;
8242 }
8243
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05308244 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008245
8246 if ( NULL == pTdlsPeer ) {
8247 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8248 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
8249 __func__, MAC_ADDR_ARRAY(mac), update);
8250 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008251 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008252
8253 /* in add station, we accept existing valid staId if there is */
8254 if ((0 == update) &&
8255 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
8256 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008257 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008258 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008259 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008260 " link_status %d. staId %d. add station ignored.",
8261 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
8262 return 0;
8263 }
8264 /* in change station, we accept only when staId is valid */
8265 if ((1 == update) &&
8266 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
8267 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
8268 {
8269 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8270 "%s: " MAC_ADDRESS_STR
8271 " link status %d. staId %d. change station %s.",
8272 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
8273 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
8274 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008275 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008276
8277 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308278 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008279 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8281 "%s: " MAC_ADDRESS_STR
8282 " TDLS setup is ongoing. Request declined.",
8283 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07008284 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008285 }
8286
8287 /* first to check if we reached to maximum supported TDLS peer.
8288 TODO: for now, return -EPERM looks working fine,
8289 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308290 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8291 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008292 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8294 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308295 " TDLS Max peer already connected. Request declined."
8296 " Num of peers (%d), Max allowed (%d).",
8297 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
8298 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008299 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008300 }
8301 else
8302 {
8303 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308304 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008305 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008306 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008307 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8308 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
8309 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008310 return -EPERM;
8311 }
8312 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008313 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05308314 wlan_hdd_tdls_set_link_status(pAdapter,
8315 mac,
8316 eTDLS_LINK_CONNECTING,
8317 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008318
Jeff Johnsond75fe012013-04-06 10:53:06 -07008319 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308320 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008321 {
8322 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8323 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008324 if(StaParams->htcap_present)
8325 {
8326 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8327 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
8328 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8329 "ht_capa->extended_capabilities: %0x",
8330 StaParams->HTCap.extendedHtCapInfo);
8331 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008332 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8333 "params->capability: %0x",StaParams->capability);
8334 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008335 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008336 if(StaParams->vhtcap_present)
8337 {
8338 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8339 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
8340 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
8341 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
8342 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008343 {
8344 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008346 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
8347 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8348 "[%d]: %x ", i, StaParams->supported_rates[i]);
8349 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07008350 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308351 else if ((1 == update) && (NULL == StaParams))
8352 {
8353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8354 "%s : update is true, but staParams is NULL. Error!", __func__);
8355 return -EPERM;
8356 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008357
8358 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
8359
8360 if (!update)
8361 {
8362 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
8363 pAdapter->sessionId, mac);
8364 }
8365 else
8366 {
8367 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
8368 pAdapter->sessionId, mac, StaParams);
8369 }
8370
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308371 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008372 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
8373
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308374 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008375 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308377 "%s: timeout waiting for tdls add station indication %ld",
8378 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008379 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008380 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308381
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008382 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
8383 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008385 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008386 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008387 }
8388
8389 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008390
8391error:
Atul Mittal115287b2014-07-08 13:26:33 +05308392 wlan_hdd_tdls_set_link_status(pAdapter,
8393 mac,
8394 eTDLS_LINK_IDLE,
8395 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008396 return -EPERM;
8397
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008398}
8399#endif
8400
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308401static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008402 struct net_device *dev,
8403 u8 *mac,
8404 struct station_parameters *params)
8405{
8406 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308407 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308408 hdd_context_t *pHddCtx;
8409 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008410 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308411 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008412#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008413 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008414 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308415 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008416#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008417
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308418 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308419
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308420 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308421 if ((NULL == pAdapter))
8422 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308424 "invalid adapter ");
8425 return -EINVAL;
8426 }
8427
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308428 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8429 TRACE_CODE_HDD_CHANGE_STATION,
8430 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05308431 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308432
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308433 ret = wlan_hdd_validate_context(pHddCtx);
8434 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05308435 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308436 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308437 }
8438
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308439 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8440
8441 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008442 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8444 "invalid HDD station context");
8445 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008446 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008447 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
8448
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008449 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8450 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07008451 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008452 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07008453 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308454 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07008455 WLANTL_STA_AUTHENTICATED);
8456
Gopichand Nakkala29149562013-05-10 21:43:41 +05308457 if (status != VOS_STATUS_SUCCESS)
8458 {
8459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8460 "%s: Not able to change TL state to AUTHENTICATED", __func__);
8461 return -EINVAL;
8462 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008463 }
8464 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07008465 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8466 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308467#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008468 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8469 StaParams.capability = params->capability;
8470 StaParams.uapsd_queues = params->uapsd_queues;
8471 StaParams.max_sp = params->max_sp;
8472
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308473 /* Convert (first channel , number of channels) tuple to
8474 * the total list of channels. This goes with the assumption
8475 * that if the first channel is < 14, then the next channels
8476 * are an incremental of 1 else an incremental of 4 till the number
8477 * of channels.
8478 */
8479 if (0 != params->supported_channels_len) {
8480 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
8481 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
8482 {
8483 int wifi_chan_index;
8484 StaParams.supported_channels[j] = params->supported_channels[i];
8485 wifi_chan_index =
8486 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
8487 no_of_channels = params->supported_channels[i+1];
8488 for(k=1; k <= no_of_channels; k++)
8489 {
8490 StaParams.supported_channels[j+1] =
8491 StaParams.supported_channels[j] + wifi_chan_index;
8492 j+=1;
8493 }
8494 }
8495 StaParams.supported_channels_len = j;
8496 }
8497 vos_mem_copy(StaParams.supported_oper_classes,
8498 params->supported_oper_classes,
8499 params->supported_oper_classes_len);
8500 StaParams.supported_oper_classes_len =
8501 params->supported_oper_classes_len;
8502
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008503 if (0 != params->ext_capab_len)
8504 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
8505 sizeof(StaParams.extn_capability));
8506
8507 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008508 {
8509 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008510 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008511 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008512
8513 StaParams.supported_rates_len = params->supported_rates_len;
8514
8515 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
8516 * The supported_rates array , for all the structures propogating till Add Sta
8517 * to the firmware has to be modified , if the supplicant (ieee80211) is
8518 * modified to send more rates.
8519 */
8520
8521 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
8522 */
8523 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
8524 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
8525
8526 if (0 != StaParams.supported_rates_len) {
8527 int i = 0;
8528 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
8529 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008531 "Supported Rates with Length %d", StaParams.supported_rates_len);
8532 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008534 "[%d]: %0x", i, StaParams.supported_rates[i]);
8535 }
8536
8537 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008538 {
8539 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008540 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008541 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008542
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008543 if (0 != params->ext_capab_len ) {
8544 /*Define A Macro : TODO Sunil*/
8545 if ((1<<4) & StaParams.extn_capability[3]) {
8546 isBufSta = 1;
8547 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308548 /* TDLS Channel Switching Support */
8549 if ((1<<6) & StaParams.extn_capability[3]) {
8550 isOffChannelSupported = 1;
8551 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008552 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308553 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
8554 &StaParams, isBufSta,
8555 isOffChannelSupported);
8556
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308557 if (VOS_STATUS_SUCCESS != status) {
8558 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8559 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
8560 return -EINVAL;
8561 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008562 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
8563
8564 if (VOS_STATUS_SUCCESS != status) {
8565 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8566 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
8567 return -EINVAL;
8568 }
8569 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008570#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05308571 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008572 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008573 return status;
8574}
8575
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308576static int wlan_hdd_change_station(struct wiphy *wiphy,
8577 struct net_device *dev,
8578 u8 *mac,
8579 struct station_parameters *params)
8580{
8581 int ret;
8582
8583 vos_ssr_protect(__func__);
8584 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
8585 vos_ssr_unprotect(__func__);
8586
8587 return ret;
8588}
8589
Jeff Johnson295189b2012-06-20 16:38:30 -07008590/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308591 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008592 * This function is used to initialize the key information
8593 */
8594#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308595static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008596 struct net_device *ndev,
8597 u8 key_index, bool pairwise,
8598 const u8 *mac_addr,
8599 struct key_params *params
8600 )
8601#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308602static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008603 struct net_device *ndev,
8604 u8 key_index, const u8 *mac_addr,
8605 struct key_params *params
8606 )
8607#endif
8608{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008609 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07008610 tCsrRoamSetKey setKey;
8611 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308612 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008613 v_U32_t roamId= 0xFF;
8614 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008615 hdd_hostapd_state_t *pHostapdState;
8616 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008617 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308618 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008619
8620 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308621
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308622 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8623 TRACE_CODE_HDD_CFG80211_ADD_KEY,
8624 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308625 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8626 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308627 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008628 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308629 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008630 }
8631
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308632 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8633 __func__, hdd_device_modetoString(pAdapter->device_mode),
8634 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008635
8636 if (CSR_MAX_NUM_KEY <= key_index)
8637 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008638 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008639 key_index);
8640
8641 return -EINVAL;
8642 }
8643
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008644 if (CSR_MAX_KEY_LEN < params->key_len)
8645 {
8646 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
8647 params->key_len);
8648
8649 return -EINVAL;
8650 }
8651
8652 hddLog(VOS_TRACE_LEVEL_INFO,
8653 "%s: called with key index = %d & key length %d",
8654 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008655
8656 /*extract key idx, key len and key*/
8657 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8658 setKey.keyId = key_index;
8659 setKey.keyLength = params->key_len;
8660 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
8661
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008662 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07008663 {
8664 case WLAN_CIPHER_SUITE_WEP40:
8665 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
8666 break;
8667
8668 case WLAN_CIPHER_SUITE_WEP104:
8669 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
8670 break;
8671
8672 case WLAN_CIPHER_SUITE_TKIP:
8673 {
8674 u8 *pKey = &setKey.Key[0];
8675 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
8676
8677 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
8678
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008679 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07008680
8681 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008682 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008683 |--------------|----------|----------|
8684 <---16bytes---><--8bytes--><--8bytes-->
8685
8686 */
8687 /*Sme expects the 32 bytes key to be in the below order
8688
8689 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008690 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008691 |--------------|----------|----------|
8692 <---16bytes---><--8bytes--><--8bytes-->
8693 */
8694 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008695 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07008696
8697 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008698 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008699
8700 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008701 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008702
8703
8704 break;
8705 }
8706
8707 case WLAN_CIPHER_SUITE_CCMP:
8708 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
8709 break;
8710
8711#ifdef FEATURE_WLAN_WAPI
8712 case WLAN_CIPHER_SUITE_SMS4:
8713 {
8714 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8715 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
8716 params->key, params->key_len);
8717 return 0;
8718 }
8719#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008720
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008721#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07008722 case WLAN_CIPHER_SUITE_KRK:
8723 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
8724 break;
8725#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008726
8727#ifdef WLAN_FEATURE_11W
8728 case WLAN_CIPHER_SUITE_AES_CMAC:
8729 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07008730 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07008731#endif
8732
Jeff Johnson295189b2012-06-20 16:38:30 -07008733 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008734 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07008735 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308736 status = -EOPNOTSUPP;
8737 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008738 }
8739
8740 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
8741 __func__, setKey.encType);
8742
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008743 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07008744#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8745 (!pairwise)
8746#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008747 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07008748#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008749 )
8750 {
8751 /* set group key*/
8752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8753 "%s- %d: setting Broadcast key",
8754 __func__, __LINE__);
8755 setKey.keyDirection = eSIR_RX_ONLY;
8756 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8757 }
8758 else
8759 {
8760 /* set pairwise key*/
8761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8762 "%s- %d: setting pairwise key",
8763 __func__, __LINE__);
8764 setKey.keyDirection = eSIR_TX_RX;
8765 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8766 }
8767 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
8768 {
8769 setKey.keyDirection = eSIR_TX_RX;
8770 /*Set the group key*/
8771 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8772 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07008773
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008774 if ( 0 != status )
8775 {
8776 hddLog(VOS_TRACE_LEVEL_ERROR,
8777 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308778 status = -EINVAL;
8779 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008780 }
8781 /*Save the keys here and call sme_RoamSetKey for setting
8782 the PTK after peer joins the IBSS network*/
8783 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
8784 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308785 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008786 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05308787 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
8788 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
8789 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008790 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008791 if( pHostapdState->bssState == BSS_START )
8792 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008793 status = WLANSAP_SetKeySta( pVosContext, &setKey);
8794
8795 if ( status != eHAL_STATUS_SUCCESS )
8796 {
8797 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8798 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8799 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308800 status = -EINVAL;
8801 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008802 }
8803 }
8804
8805 /* Saving WEP keys */
8806 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
8807 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
8808 {
8809 //Save the wep key in ap context. Issue setkey after the BSS is started.
8810 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8811 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
8812 }
8813 else
8814 {
8815 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008816 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008817 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
8818 }
8819 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008820 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
8821 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008822 {
8823 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8824 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8825
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308826#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8827 if (!pairwise)
8828#else
8829 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8830#endif
8831 {
8832 /* set group key*/
8833 if (pHddStaCtx->roam_info.deferKeyComplete)
8834 {
8835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8836 "%s- %d: Perform Set key Complete",
8837 __func__, __LINE__);
8838 hdd_PerformRoamSetKeyComplete(pAdapter);
8839 }
8840 }
8841
Jeff Johnson295189b2012-06-20 16:38:30 -07008842 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
8843
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08008844 pWextState->roamProfile.Keys.defaultIndex = key_index;
8845
8846
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008847 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008848 params->key, params->key_len);
8849
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308850
Jeff Johnson295189b2012-06-20 16:38:30 -07008851 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8852
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308853 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008854 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308855 __func__, setKey.peerMac[0], setKey.peerMac[1],
8856 setKey.peerMac[2], setKey.peerMac[3],
8857 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008858 setKey.keyDirection);
8859
Nirav Shah4f765af2015-01-21 19:51:30 +05308860 /* Wait for EAPOL M4 before setting key.
8861 * No need to consider Dynamic WEP as we will receive M8.
8862 */
8863 if ( (setKey.encType == eCSR_ENCRYPT_TYPE_AES ||
8864 setKey.encType == eCSR_ENCRYPT_TYPE_TKIP) &&
8865 ( 1
8866#if defined WLAN_FEATURE_VOWIFI_11R
8867 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_FT_RSN
8868 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_FT_RSN_PSK
8869#endif
8870#ifdef FEATURE_WLAN_ESE
8871 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_CCKM_WPA
8872 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_CCKM_RSN
8873#endif
8874 ))
Jeff Johnson295189b2012-06-20 16:38:30 -07008875 {
Nirav Shah4f765af2015-01-21 19:51:30 +05308876 vos_status = wlan_hdd_check_ula_done(pAdapter);
8877
8878 if ( vos_status != VOS_STATUS_SUCCESS )
8879 {
8880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008881 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8882 __LINE__, vos_status );
8883
Nirav Shah4f765af2015-01-21 19:51:30 +05308884 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008885
Nirav Shah4f765af2015-01-21 19:51:30 +05308886 status = -EINVAL;
8887 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008888
Nirav Shah4f765af2015-01-21 19:51:30 +05308889 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008890 }
8891
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008892#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308893 /* The supplicant may attempt to set the PTK once pre-authentication
8894 is done. Save the key in the UMAC and include it in the ADD BSS
8895 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008896 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308897 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008898 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308899 hddLog(VOS_TRACE_LEVEL_INFO_MED,
8900 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308901 status = 0;
8902 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308903 }
8904 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
8905 {
8906 hddLog(VOS_TRACE_LEVEL_ERROR,
8907 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308908 status = -EINVAL;
8909 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008910 }
8911#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07008912
8913 /* issue set key request to SME*/
8914 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8915 pAdapter->sessionId, &setKey, &roamId );
8916
8917 if ( 0 != status )
8918 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308919 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008920 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
8921 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308922 status = -EINVAL;
8923 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008924 }
8925
8926
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308927 /* in case of IBSS as there was no information available about WEP keys during
8928 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07008929 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308930 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
8931 !( ( IW_AUTH_KEY_MGMT_802_1X
8932 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07008933 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
8934 )
8935 &&
8936 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
8937 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
8938 )
8939 )
8940 {
8941 setKey.keyDirection = eSIR_RX_ONLY;
8942 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8943
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308944 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008945 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308946 __func__, setKey.peerMac[0], setKey.peerMac[1],
8947 setKey.peerMac[2], setKey.peerMac[3],
8948 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008949 setKey.keyDirection);
8950
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308951 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008952 pAdapter->sessionId, &setKey, &roamId );
8953
8954 if ( 0 != status )
8955 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308956 hddLog(VOS_TRACE_LEVEL_ERROR,
8957 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008958 __func__, status);
8959 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308960 status = -EINVAL;
8961 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008962 }
8963 }
8964 }
8965
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308966end:
8967 /* Need to clear any trace of key value in the memory.
8968 * Thus zero out the memory even though it is local
8969 * variable.
8970 */
8971 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308972 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308973 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008974}
8975
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308976#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8977static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8978 struct net_device *ndev,
8979 u8 key_index, bool pairwise,
8980 const u8 *mac_addr,
8981 struct key_params *params
8982 )
8983#else
8984static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8985 struct net_device *ndev,
8986 u8 key_index, const u8 *mac_addr,
8987 struct key_params *params
8988 )
8989#endif
8990{
8991 int ret;
8992 vos_ssr_protect(__func__);
8993#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8994 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
8995 mac_addr, params);
8996#else
8997 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
8998 params);
8999#endif
9000 vos_ssr_unprotect(__func__);
9001
9002 return ret;
9003}
9004
Jeff Johnson295189b2012-06-20 16:38:30 -07009005/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309006 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009007 * This function is used to get the key information
9008 */
9009#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309010static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309011 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009012 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309013 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009014 const u8 *mac_addr, void *cookie,
9015 void (*callback)(void *cookie, struct key_params*)
9016 )
9017#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309018static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309019 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009020 struct net_device *ndev,
9021 u8 key_index, const u8 *mac_addr, void *cookie,
9022 void (*callback)(void *cookie, struct key_params*)
9023 )
9024#endif
9025{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309026 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309027 hdd_wext_state_t *pWextState = NULL;
9028 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009029 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309030 hdd_context_t *pHddCtx;
9031 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009032
9033 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309034
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309035 if (NULL == pAdapter)
9036 {
9037 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9038 "%s: HDD adapter is Null", __func__);
9039 return -ENODEV;
9040 }
9041
9042 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9043 ret = wlan_hdd_validate_context(pHddCtx);
9044 if (0 != ret)
9045 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309046 return ret;
9047 }
9048
9049 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9050 pRoamProfile = &(pWextState->roamProfile);
9051
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309052 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9053 __func__, hdd_device_modetoString(pAdapter->device_mode),
9054 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309055
Jeff Johnson295189b2012-06-20 16:38:30 -07009056 memset(&params, 0, sizeof(params));
9057
9058 if (CSR_MAX_NUM_KEY <= key_index)
9059 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309060 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07009061 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309062 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009063
9064 switch(pRoamProfile->EncryptionType.encryptionType[0])
9065 {
9066 case eCSR_ENCRYPT_TYPE_NONE:
9067 params.cipher = IW_AUTH_CIPHER_NONE;
9068 break;
9069
9070 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
9071 case eCSR_ENCRYPT_TYPE_WEP40:
9072 params.cipher = WLAN_CIPHER_SUITE_WEP40;
9073 break;
9074
9075 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
9076 case eCSR_ENCRYPT_TYPE_WEP104:
9077 params.cipher = WLAN_CIPHER_SUITE_WEP104;
9078 break;
9079
9080 case eCSR_ENCRYPT_TYPE_TKIP:
9081 params.cipher = WLAN_CIPHER_SUITE_TKIP;
9082 break;
9083
9084 case eCSR_ENCRYPT_TYPE_AES:
9085 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
9086 break;
9087
9088 default:
9089 params.cipher = IW_AUTH_CIPHER_NONE;
9090 break;
9091 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309092
c_hpothuaaf19692014-05-17 17:01:48 +05309093 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9094 TRACE_CODE_HDD_CFG80211_GET_KEY,
9095 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309096
Jeff Johnson295189b2012-06-20 16:38:30 -07009097 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
9098 params.seq_len = 0;
9099 params.seq = NULL;
9100 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
9101 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309102 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009103 return 0;
9104}
9105
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309106#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9107static int wlan_hdd_cfg80211_get_key(
9108 struct wiphy *wiphy,
9109 struct net_device *ndev,
9110 u8 key_index, bool pairwise,
9111 const u8 *mac_addr, void *cookie,
9112 void (*callback)(void *cookie, struct key_params*)
9113 )
9114#else
9115static int wlan_hdd_cfg80211_get_key(
9116 struct wiphy *wiphy,
9117 struct net_device *ndev,
9118 u8 key_index, const u8 *mac_addr, void *cookie,
9119 void (*callback)(void *cookie, struct key_params*)
9120 )
9121#endif
9122{
9123 int ret;
9124
9125 vos_ssr_protect(__func__);
9126#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9127 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
9128 mac_addr, cookie, callback);
9129#else
9130 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
9131 callback);
9132#endif
9133 vos_ssr_unprotect(__func__);
9134
9135 return ret;
9136}
9137
Jeff Johnson295189b2012-06-20 16:38:30 -07009138/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309139 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009140 * This function is used to delete the key information
9141 */
9142#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309143static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009144 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309145 u8 key_index,
9146 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009147 const u8 *mac_addr
9148 )
9149#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309150static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009151 struct net_device *ndev,
9152 u8 key_index,
9153 const u8 *mac_addr
9154 )
9155#endif
9156{
9157 int status = 0;
9158
9159 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309160 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009161 //it is observed that this is invalidating peer
9162 //key index whenever re-key is done. This is affecting data link.
9163 //It should be ok to ignore del_key.
9164#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309165 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
9166 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009167 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
9168 tCsrRoamSetKey setKey;
9169 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309170
Jeff Johnson295189b2012-06-20 16:38:30 -07009171 ENTER();
9172
9173 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
9174 __func__,pAdapter->device_mode);
9175
9176 if (CSR_MAX_NUM_KEY <= key_index)
9177 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309178 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009179 key_index);
9180
9181 return -EINVAL;
9182 }
9183
9184 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9185 setKey.keyId = key_index;
9186
9187 if (mac_addr)
9188 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9189 else
9190 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
9191
9192 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
9193
9194 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009195 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309196 )
9197 {
9198
9199 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07009200 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9201 if( pHostapdState->bssState == BSS_START)
9202 {
9203 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309204
Jeff Johnson295189b2012-06-20 16:38:30 -07009205 if ( status != eHAL_STATUS_SUCCESS )
9206 {
9207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9208 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9209 __LINE__, status );
9210 }
9211 }
9212 }
9213 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309214 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07009215 )
9216 {
9217 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9218
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309219 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9220
9221 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009222 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309223 __func__, setKey.peerMac[0], setKey.peerMac[1],
9224 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07009225 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309226 if(pAdapter->sessionCtx.station.conn_info.connState ==
9227 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07009228 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309229 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009230 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309231
Jeff Johnson295189b2012-06-20 16:38:30 -07009232 if ( 0 != status )
9233 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309234 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009235 "%s: sme_RoamSetKey failure, returned %d",
9236 __func__, status);
9237 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9238 return -EINVAL;
9239 }
9240 }
9241 }
9242#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009243 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009244 return status;
9245}
9246
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309247#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9248static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9249 struct net_device *ndev,
9250 u8 key_index,
9251 bool pairwise,
9252 const u8 *mac_addr
9253 )
9254#else
9255static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9256 struct net_device *ndev,
9257 u8 key_index,
9258 const u8 *mac_addr
9259 )
9260#endif
9261{
9262 int ret;
9263
9264 vos_ssr_protect(__func__);
9265#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9266 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
9267 mac_addr);
9268#else
9269 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
9270#endif
9271 vos_ssr_unprotect(__func__);
9272
9273 return ret;
9274}
9275
Jeff Johnson295189b2012-06-20 16:38:30 -07009276/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309277 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009278 * This function is used to set the default tx key index
9279 */
9280#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309281static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009282 struct net_device *ndev,
9283 u8 key_index,
9284 bool unicast, bool multicast)
9285#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309286static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009287 struct net_device *ndev,
9288 u8 key_index)
9289#endif
9290{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309291 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309292 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309293 hdd_wext_state_t *pWextState;
9294 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309295 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009296
9297 ENTER();
9298
Gopichand Nakkala29149562013-05-10 21:43:41 +05309299 if ((NULL == pAdapter))
9300 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309302 "invalid adapter");
9303 return -EINVAL;
9304 }
9305
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309306 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9307 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
9308 pAdapter->sessionId, key_index));
9309
Gopichand Nakkala29149562013-05-10 21:43:41 +05309310 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9311 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9312
9313 if ((NULL == pWextState) || (NULL == pHddStaCtx))
9314 {
9315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9316 "invalid Wext state or HDD context");
9317 return -EINVAL;
9318 }
9319
Arif Hussain6d2a3322013-11-17 19:50:10 -08009320 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009321 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309322
Jeff Johnson295189b2012-06-20 16:38:30 -07009323 if (CSR_MAX_NUM_KEY <= key_index)
9324 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309325 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009326 key_index);
9327
9328 return -EINVAL;
9329 }
9330
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309331 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9332 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309333 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009334 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309335 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009336 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309337
Jeff Johnson295189b2012-06-20 16:38:30 -07009338 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07009339 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309340 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009341 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309342 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08009343 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309344 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08009345 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07009346 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309347 {
9348 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07009349 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309350
Jeff Johnson295189b2012-06-20 16:38:30 -07009351 tCsrRoamSetKey setKey;
9352 v_U32_t roamId= 0xFF;
9353 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309354
9355 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009356 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309357
Jeff Johnson295189b2012-06-20 16:38:30 -07009358 Keys->defaultIndex = (u8)key_index;
9359 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9360 setKey.keyId = key_index;
9361 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309362
9363 vos_mem_copy(&setKey.Key[0],
9364 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009365 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309366
Gopichand Nakkala29149562013-05-10 21:43:41 +05309367 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309368
9369 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07009370 &pHddStaCtx->conn_info.bssId[0],
9371 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309372
Gopichand Nakkala29149562013-05-10 21:43:41 +05309373 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
9374 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
9375 eCSR_ENCRYPT_TYPE_WEP104)
9376 {
9377 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
9378 even though ap is configured for WEP-40 encryption. In this canse the key length
9379 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
9380 type(104) and switching encryption type to 40*/
9381 pWextState->roamProfile.EncryptionType.encryptionType[0] =
9382 eCSR_ENCRYPT_TYPE_WEP40;
9383 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
9384 eCSR_ENCRYPT_TYPE_WEP40;
9385 }
9386
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309387 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07009388 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309389
Jeff Johnson295189b2012-06-20 16:38:30 -07009390 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309391 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009392 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309393
Jeff Johnson295189b2012-06-20 16:38:30 -07009394 if ( 0 != status )
9395 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309396 hddLog(VOS_TRACE_LEVEL_ERROR,
9397 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009398 status);
9399 return -EINVAL;
9400 }
9401 }
9402 }
9403
9404 /* In SoftAp mode setting key direction for default mode */
9405 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
9406 {
9407 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
9408 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
9409 (eCSR_ENCRYPT_TYPE_AES !=
9410 pWextState->roamProfile.EncryptionType.encryptionType[0])
9411 )
9412 {
9413 /* Saving key direction for default key index to TX default */
9414 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9415 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
9416 }
9417 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309418 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009419 return status;
9420}
9421
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309422#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9423static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9424 struct net_device *ndev,
9425 u8 key_index,
9426 bool unicast, bool multicast)
9427#else
9428static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9429 struct net_device *ndev,
9430 u8 key_index)
9431#endif
9432{
9433 int ret;
9434 vos_ssr_protect(__func__);
9435#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9436 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
9437 multicast);
9438#else
9439 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
9440#endif
9441 vos_ssr_unprotect(__func__);
9442
9443 return ret;
9444}
9445
Jeff Johnson295189b2012-06-20 16:38:30 -07009446/*
9447 * FUNCTION: wlan_hdd_cfg80211_inform_bss
9448 * This function is used to inform the BSS details to nl80211 interface.
9449 */
9450static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
9451 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
9452{
9453 struct net_device *dev = pAdapter->dev;
9454 struct wireless_dev *wdev = dev->ieee80211_ptr;
9455 struct wiphy *wiphy = wdev->wiphy;
9456 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
9457 int chan_no;
9458 int ie_length;
9459 const char *ie;
9460 unsigned int freq;
9461 struct ieee80211_channel *chan;
9462 int rssi = 0;
9463 struct cfg80211_bss *bss = NULL;
9464
9465 ENTER();
9466
9467 if( NULL == pBssDesc )
9468 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009469 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009470 return bss;
9471 }
9472
9473 chan_no = pBssDesc->channelId;
9474 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
9475 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
9476
9477 if( NULL == ie )
9478 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009479 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009480 return bss;
9481 }
9482
9483#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9484 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9485 {
9486 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9487 }
9488 else
9489 {
9490 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9491 }
9492#else
9493 freq = ieee80211_channel_to_frequency(chan_no);
9494#endif
9495
9496 chan = __ieee80211_get_channel(wiphy, freq);
9497
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05309498 if (!chan) {
9499 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
9500 return NULL;
9501 }
9502
Abhishek Singhaee43942014-06-16 18:55:47 +05309503 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07009504
Abhishek Singhaee43942014-06-16 18:55:47 +05309505 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309506 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07009507 pBssDesc->capabilityInfo,
9508 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05309509 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07009510}
9511
9512
9513
9514/*
9515 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
9516 * This function is used to inform the BSS details to nl80211 interface.
9517 */
9518struct cfg80211_bss*
9519wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
9520 tSirBssDescription *bss_desc
9521 )
9522{
9523 /*
9524 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
9525 already exists in bss data base of cfg80211 for that particular BSS ID.
9526 Using cfg80211_inform_bss_frame to update the bss entry instead of
9527 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
9528 now there is no possibility to get the mgmt(probe response) frame from PE,
9529 converting bss_desc to ieee80211_mgmt(probe response) and passing to
9530 cfg80211_inform_bss_frame.
9531 */
9532 struct net_device *dev = pAdapter->dev;
9533 struct wireless_dev *wdev = dev->ieee80211_ptr;
9534 struct wiphy *wiphy = wdev->wiphy;
9535 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009536#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9537 qcom_ie_age *qie_age = NULL;
9538 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
9539#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009540 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009541#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009542 const char *ie =
9543 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
9544 unsigned int freq;
9545 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309546 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009547 struct cfg80211_bss *bss_status = NULL;
9548 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
9549 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07009550 hdd_context_t *pHddCtx;
9551 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07009552#ifdef WLAN_OPEN_SOURCE
9553 struct timespec ts;
9554#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009555
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309556 ENTER();
9557
Wilson Yangf80a0542013-10-07 13:02:37 -07009558 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9559 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -07009560 if (0 != status)
9561 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009562 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009563 }
9564
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309565 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07009566 if (!mgmt)
9567 {
9568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9569 "%s: memory allocation failed ", __func__);
9570 return NULL;
9571 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009572
Jeff Johnson295189b2012-06-20 16:38:30 -07009573 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07009574
9575#ifdef WLAN_OPEN_SOURCE
9576 /* Android does not want the timestamp from the frame.
9577 Instead it wants a monotonic increasing value */
9578 get_monotonic_boottime(&ts);
9579 mgmt->u.probe_resp.timestamp =
9580 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
9581#else
9582 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009583 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
9584 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07009585
9586#endif
9587
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
9589 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009590
9591#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9592 /* GPS Requirement: need age ie per entry. Using vendor specific. */
9593 /* Assuming this is the last IE, copy at the end */
9594 ie_length -=sizeof(qcom_ie_age);
9595 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
9596 qie_age->element_id = QCOM_VENDOR_IE_ID;
9597 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
9598 qie_age->oui_1 = QCOM_OUI1;
9599 qie_age->oui_2 = QCOM_OUI2;
9600 qie_age->oui_3 = QCOM_OUI3;
9601 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
9602 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
9603#endif
9604
Jeff Johnson295189b2012-06-20 16:38:30 -07009605 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05309606 if (bss_desc->fProbeRsp)
9607 {
9608 mgmt->frame_control |=
9609 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
9610 }
9611 else
9612 {
9613 mgmt->frame_control |=
9614 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
9615 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009616
9617#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309618 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009619 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
9620 {
9621 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9622 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309623 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009624 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
9625
9626 {
9627 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9628 }
9629 else
9630 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309631 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
9632 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07009633 kfree(mgmt);
9634 return NULL;
9635 }
9636#else
9637 freq = ieee80211_channel_to_frequency(chan_no);
9638#endif
9639 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009640 /*when the band is changed on the fly using the GUI, three things are done
9641 * 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)
9642 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
9643 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
9644 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
9645 * and discards the channels correponding to previous band and calls back with zero bss results.
9646 * 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
9647 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
9648 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
9649 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
9650 * So drop the bss and continue to next bss.
9651 */
9652 if(chan == NULL)
9653 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309654 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07009655 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009656 return NULL;
9657 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009658 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309659 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07009660 * */
9661 if (( eConnectionState_Associated ==
9662 pAdapter->sessionCtx.station.conn_info.connState ) &&
9663 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
9664 pAdapter->sessionCtx.station.conn_info.bssId,
9665 WNI_CFG_BSSID_LEN)))
9666 {
9667 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
9668 rssi = (pAdapter->rssi * 100);
9669 }
9670 else
9671 {
9672 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
9673 }
9674
Nirav Shah20ac06f2013-12-12 18:14:06 +05309675 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
9676 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
9677 chan->center_freq, (int)(rssi/100));
9678
Jeff Johnson295189b2012-06-20 16:38:30 -07009679 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
9680 frame_len, rssi, GFP_KERNEL);
9681 kfree(mgmt);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309682 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009683 return bss_status;
9684}
9685
9686/*
9687 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
9688 * This function is used to update the BSS data base of CFG8011
9689 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309690struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009691 tCsrRoamInfo *pRoamInfo
9692 )
9693{
9694 tCsrRoamConnectedProfile roamProfile;
9695 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9696 struct cfg80211_bss *bss = NULL;
9697
9698 ENTER();
9699
9700 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
9701 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
9702
9703 if (NULL != roamProfile.pBssDesc)
9704 {
Girish Gowlif4b68022014-08-28 23:18:57 +05309705 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9706 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009707
9708 if (NULL == bss)
9709 {
9710 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
9711 __func__);
9712 }
9713
9714 sme_RoamFreeConnectProfile(hHal, &roamProfile);
9715 }
9716 else
9717 {
9718 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
9719 __func__);
9720 }
9721 return bss;
9722}
9723
9724/*
9725 * FUNCTION: wlan_hdd_cfg80211_update_bss
9726 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309727static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
9728 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07009729 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309730{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309731 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009732 tCsrScanResultInfo *pScanResult;
9733 eHalStatus status = 0;
9734 tScanResultHandle pResult;
9735 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009736 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009737
9738 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309739
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309740 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9741 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
9742 NO_SESSION, pAdapter->sessionId));
9743
Wilson Yangf80a0542013-10-07 13:02:37 -07009744 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9745
9746 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009747 {
Wilson Yangf80a0542013-10-07 13:02:37 -07009748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9749 "%s:LOGP in Progress. Ignore!!!",__func__);
9750 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009751 }
9752
Wilson Yangf80a0542013-10-07 13:02:37 -07009753
9754 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309755 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009756 {
9757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9758 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9759 return VOS_STATUS_E_PERM;
9760 }
9761
9762
Jeff Johnson295189b2012-06-20 16:38:30 -07009763 /*
9764 * start getting scan results and populate cgf80211 BSS database
9765 */
9766 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
9767
9768 /* no scan results */
9769 if (NULL == pResult)
9770 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309771 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
9772 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009773 return status;
9774 }
9775
9776 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
9777
9778 while (pScanResult)
9779 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309780 /*
9781 * cfg80211_inform_bss() is not updating ie field of bss entry, if
9782 * entry already exists in bss data base of cfg80211 for that
9783 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
9784 * bss entry instead of cfg80211_inform_bss, But this call expects
9785 * mgmt packet as input. As of now there is no possibility to get
9786 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07009787 * ieee80211_mgmt(probe response) and passing to c
9788 * fg80211_inform_bss_frame.
9789 * */
9790
9791 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9792 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309793
Jeff Johnson295189b2012-06-20 16:38:30 -07009794
9795 if (NULL == bss_status)
9796 {
9797 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009798 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009799 }
9800 else
9801 {
Yue Maf49ba872013-08-19 12:04:25 -07009802 cfg80211_put_bss(
9803#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
9804 wiphy,
9805#endif
9806 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009807 }
9808
9809 pScanResult = sme_ScanResultGetNext(hHal, pResult);
9810 }
9811
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309812 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07009813
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309814 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009815}
9816
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009817void
9818hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
9819{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309820 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08009821 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009822} /****** end hddPrintMacAddr() ******/
9823
9824void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009825hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009826{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309827 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009828 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009829 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
9830 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
9831 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009832} /****** end hddPrintPmkId() ******/
9833
9834//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
9835//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
9836
9837//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
9838//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
9839
9840#define dump_bssid(bssid) \
9841 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009842 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
9843 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009844 }
9845
9846#define dump_pmkid(pMac, pmkid) \
9847 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009848 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
9849 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009850 }
9851
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009852#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009853/*
9854 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
9855 * This function is used to notify the supplicant of a new PMKSA candidate.
9856 */
9857int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309858 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009859 int index, bool preauth )
9860{
Jeff Johnsone7245742012-09-05 17:12:55 -07009861#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009862 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009863 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009864
9865 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07009866 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009867
9868 if( NULL == pRoamInfo )
9869 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009870 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009871 return -EINVAL;
9872 }
9873
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009874 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
9875 {
9876 dump_bssid(pRoamInfo->bssid);
9877 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009878 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009879 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009880#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309881 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009882}
9883#endif //FEATURE_WLAN_LFR
9884
Yue Maef608272013-04-08 23:09:17 -07009885#ifdef FEATURE_WLAN_LFR_METRICS
9886/*
9887 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
9888 * 802.11r/LFR metrics reporting function to report preauth initiation
9889 *
9890 */
9891#define MAX_LFR_METRICS_EVENT_LENGTH 100
9892VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
9893 tCsrRoamInfo *pRoamInfo)
9894{
9895 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9896 union iwreq_data wrqu;
9897
9898 ENTER();
9899
9900 if (NULL == pAdapter)
9901 {
9902 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9903 return VOS_STATUS_E_FAILURE;
9904 }
9905
9906 /* create the event */
9907 memset(&wrqu, 0, sizeof(wrqu));
9908 memset(metrics_notification, 0, sizeof(metrics_notification));
9909
9910 wrqu.data.pointer = metrics_notification;
9911 wrqu.data.length = scnprintf(metrics_notification,
9912 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
9913 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9914
9915 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9916
9917 EXIT();
9918
9919 return VOS_STATUS_SUCCESS;
9920}
9921
9922/*
9923 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
9924 * 802.11r/LFR metrics reporting function to report preauth completion
9925 * or failure
9926 */
9927VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
9928 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
9929{
9930 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9931 union iwreq_data wrqu;
9932
9933 ENTER();
9934
9935 if (NULL == pAdapter)
9936 {
9937 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9938 return VOS_STATUS_E_FAILURE;
9939 }
9940
9941 /* create the event */
9942 memset(&wrqu, 0, sizeof(wrqu));
9943 memset(metrics_notification, 0, sizeof(metrics_notification));
9944
9945 scnprintf(metrics_notification, sizeof(metrics_notification),
9946 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
9947 MAC_ADDR_ARRAY(pRoamInfo->bssid));
9948
9949 if (1 == preauth_status)
9950 strncat(metrics_notification, " TRUE", 5);
9951 else
9952 strncat(metrics_notification, " FALSE", 6);
9953
9954 wrqu.data.pointer = metrics_notification;
9955 wrqu.data.length = strlen(metrics_notification);
9956
9957 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9958
9959 EXIT();
9960
9961 return VOS_STATUS_SUCCESS;
9962}
9963
9964/*
9965 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
9966 * 802.11r/LFR metrics reporting function to report handover initiation
9967 *
9968 */
9969VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
9970 tCsrRoamInfo *pRoamInfo)
9971{
9972 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9973 union iwreq_data wrqu;
9974
9975 ENTER();
9976
9977 if (NULL == pAdapter)
9978 {
9979 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9980 return VOS_STATUS_E_FAILURE;
9981 }
9982
9983 /* create the event */
9984 memset(&wrqu, 0, sizeof(wrqu));
9985 memset(metrics_notification, 0, sizeof(metrics_notification));
9986
9987 wrqu.data.pointer = metrics_notification;
9988 wrqu.data.length = scnprintf(metrics_notification,
9989 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
9990 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9991
9992 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9993
9994 EXIT();
9995
9996 return VOS_STATUS_SUCCESS;
9997}
9998#endif
9999
Jeff Johnson295189b2012-06-20 16:38:30 -070010000/*
10001 * FUNCTION: hdd_cfg80211_scan_done_callback
10002 * scanning callback function, called after finishing scan
10003 *
10004 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010005static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070010006 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
10007{
10008 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010009 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070010010 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010011 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10012 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -070010013 struct cfg80211_scan_request *req = NULL;
10014 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010015 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010016 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010017 tANI_U8 i;
Jeff Johnson295189b2012-06-20 16:38:30 -070010018
10019 ENTER();
10020
10021 hddLog(VOS_TRACE_LEVEL_INFO,
10022 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080010023 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010024 __func__, halHandle, pContext, (int) scanId, (int) status);
10025
Kiet Lamac06e2c2013-10-23 16:25:07 +053010026 pScanInfo->mScanPendingCounter = 0;
10027
Jeff Johnson295189b2012-06-20 16:38:30 -070010028 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010029 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070010030 &pScanInfo->scan_req_completion_event,
10031 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010032 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070010033 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010034 hddLog(VOS_TRACE_LEVEL_ERROR,
10035 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070010036 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010037 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010038 }
10039
Yue Maef608272013-04-08 23:09:17 -070010040 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010041 {
10042 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010043 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010044 }
10045
10046 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010047 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 {
10049 hddLog(VOS_TRACE_LEVEL_INFO,
10050 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010051 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070010052 (int) scanId);
10053 }
10054
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010055 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010056 pAdapter);
10057
10058 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010059 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010060
10061
10062 /* If any client wait scan result through WEXT
10063 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010064 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070010065 {
10066 /* The other scan request waiting for current scan finish
10067 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010068 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010069 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010070 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070010071 }
10072 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010073 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010074 {
10075 struct net_device *dev = pAdapter->dev;
10076 union iwreq_data wrqu;
10077 int we_event;
10078 char *msg;
10079
10080 memset(&wrqu, '\0', sizeof(wrqu));
10081 we_event = SIOCGIWSCAN;
10082 msg = NULL;
10083 wireless_send_event(dev, we_event, &wrqu, msg);
10084 }
10085 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010086 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010087
10088 /* Get the Scan Req */
10089 req = pAdapter->request;
10090
10091 if (!req)
10092 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010093 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010094 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010095 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010096 }
10097
Jeff Johnson295189b2012-06-20 16:38:30 -070010098 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070010099 /* Scan is no longer pending */
10100 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010101
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010102 /* last_scan_timestamp is used to decide if new scan
10103 * is needed or not on station interface. If last station
10104 * scan time and new station scan time is less then
10105 * last_scan_timestamp ; driver will return cached scan.
10106 */
10107 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
10108 {
10109 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
10110
10111 if ( req->n_channels )
10112 {
10113 for (i = 0; i < req->n_channels ; i++ )
10114 {
10115 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
10116 }
10117 /* store no of channel scanned */
10118 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
10119 }
10120
10121 }
10122
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070010123 /*
10124 * cfg80211_scan_done informing NL80211 about completion
10125 * of scanning
10126 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010127 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
10128 {
10129 aborted = true;
10130 }
10131 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080010132 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010133
Siddharth Bhal76972212014-10-15 16:22:51 +053010134 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
10135 /* Generate new random mac addr for next scan */
10136 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
10137 hdd_processSpoofMacAddrRequest(pHddCtx);
10138 }
10139
Jeff Johnsone7245742012-09-05 17:12:55 -070010140allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010141 /* release the wake lock at the end of the scan*/
10142 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -070010143
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010144 /* Acquire wakelock to handle the case where APP's tries to suspend
10145 * immediatly after the driver gets connect request(i.e after scan)
10146 * from supplicant, this result in app's is suspending and not able
10147 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010148 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010149
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010150#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010151 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010152#endif
10153
Jeff Johnson295189b2012-06-20 16:38:30 -070010154 EXIT();
10155 return 0;
10156}
10157
10158/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053010159 * FUNCTION: hdd_isConnectionInProgress
10160 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010161 *
10162 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010163v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010164{
10165 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10166 hdd_station_ctx_t *pHddStaCtx = NULL;
10167 hdd_adapter_t *pAdapter = NULL;
10168 VOS_STATUS status = 0;
10169 v_U8_t staId = 0;
10170 v_U8_t *staMac = NULL;
10171
c_hpothu9b781ba2013-12-30 20:57:45 +053010172 if (TRUE == pHddCtx->btCoexModeSet)
10173 {
10174 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053010175 FL("BTCoex Mode operation in progress"));
10176 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053010177 }
10178
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010179 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10180
10181 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10182 {
10183 pAdapter = pAdapterNode->pAdapter;
10184
10185 if( pAdapter )
10186 {
10187 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010188 "%s: Adapter with device mode %s (%d) exists",
10189 __func__, hdd_device_modetoString(pAdapter->device_mode),
10190 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010191 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053010192 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10193 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
10194 (eConnectionState_Connecting ==
10195 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
10196 {
10197 hddLog(VOS_TRACE_LEVEL_ERROR,
10198 "%s: %p(%d) Connection is in progress", __func__,
10199 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10200 return VOS_TRUE;
10201 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010202 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053010203 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010204 {
10205 hddLog(VOS_TRACE_LEVEL_ERROR,
10206 "%s: %p(%d) Reassociation is in progress", __func__,
10207 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10208 return VOS_TRUE;
10209 }
10210 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010211 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10212 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010213 {
10214 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10215 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010216 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010217 {
10218 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
10219 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010220 "%s: client " MAC_ADDRESS_STR
10221 " is in the middle of WPS/EAPOL exchange.", __func__,
10222 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010223 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010224 }
10225 }
10226 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
10227 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
10228 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010229 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10230 ptSapContext pSapCtx = NULL;
10231 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10232 if(pSapCtx == NULL){
10233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10234 FL("psapCtx is NULL"));
10235 return VOS_FALSE;
10236 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010237 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
10238 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010239 if ((pSapCtx->aStaInfo[staId].isUsed) &&
10240 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010241 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010242 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010243
10244 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010245 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
10246 "middle of WPS/EAPOL exchange.", __func__,
10247 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010248 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010249 }
10250 }
10251 }
10252 }
10253 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10254 pAdapterNode = pNext;
10255 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053010256 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010257}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010258
10259/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010260 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070010261 * this scan respond to scan trigger and update cfg80211 scan database
10262 * later, scan dump command can be used to recieve scan results
10263 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010264int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010265#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10266 struct net_device *dev,
10267#endif
10268 struct cfg80211_scan_request *request)
10269{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010270 hdd_adapter_t *pAdapter = NULL;
10271 hdd_context_t *pHddCtx = NULL;
10272 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010273 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010274 tCsrScanRequest scanRequest;
10275 tANI_U8 *channelList = NULL, i;
10276 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010277 int status;
10278 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010279 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010280 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010281
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010282#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
10283 struct net_device *dev = NULL;
10284 if (NULL == request)
10285 {
10286 hddLog(VOS_TRACE_LEVEL_ERROR,
10287 "%s: scan req param null", __func__);
10288 return -EINVAL;
10289 }
10290 dev = request->wdev->netdev;
10291#endif
10292
10293 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
10294 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
10295 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10296
Jeff Johnson295189b2012-06-20 16:38:30 -070010297 ENTER();
10298
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010299 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10300 __func__, hdd_device_modetoString(pAdapter->device_mode),
10301 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010302
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010303 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010304 if (0 != status)
10305 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010306 return status;
10307 }
10308
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010309 if (NULL == pwextBuf)
10310 {
10311 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
10312 __func__);
10313 return -EIO;
10314 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010315 cfg_param = pHddCtx->cfg_ini;
10316 pScanInfo = &pHddCtx->scan_info;
10317
Jeff Johnson295189b2012-06-20 16:38:30 -070010318#ifdef WLAN_BTAMP_FEATURE
10319 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010320 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070010321 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010322 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010323 "%s: No scanning when AMP is on", __func__);
10324 return -EOPNOTSUPP;
10325 }
10326#endif
10327 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010328 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010329 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010330 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010331 "%s: Not scanning on device_mode = %s (%d)",
10332 __func__, hdd_device_modetoString(pAdapter->device_mode),
10333 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010334 return -EOPNOTSUPP;
10335 }
10336
10337 if (TRUE == pScanInfo->mScanPending)
10338 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010339 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
10340 {
10341 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
10342 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010343 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010344 }
10345
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010346 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070010347 //Channel and action frame is pending
10348 //Otherwise Cancel Remain On Channel and allow Scan
10349 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010350 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070010351 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010352 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010353 return -EBUSY;
10354 }
10355
Jeff Johnson295189b2012-06-20 16:38:30 -070010356 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
10357 {
10358 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080010359 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010360 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010361 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010362 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
10363 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010364 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010365 "%s: MAX TM Level Scan not allowed", __func__);
10366 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010367 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010368 }
10369 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
10370
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010371 /* Check if scan is allowed at this point of time.
10372 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010373 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010374 {
10375 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
10376 return -EBUSY;
10377 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010378
Jeff Johnson295189b2012-06-20 16:38:30 -070010379 vos_mem_zero( &scanRequest, sizeof(scanRequest));
10380
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010381 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
10382 (int)request->n_ssids);
10383
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010384
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010385 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
10386 * Becasue of this, driver is assuming that this is not wildcard scan and so
10387 * is not aging out the scan results.
10388 */
10389 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010390 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010391 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010392 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010393
10394 if ((request->ssids) && (0 < request->n_ssids))
10395 {
10396 tCsrSSIDInfo *SsidInfo;
10397 int j;
10398 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
10399 /* Allocate num_ssid tCsrSSIDInfo structure */
10400 SsidInfo = scanRequest.SSIDs.SSIDList =
10401 ( tCsrSSIDInfo *)vos_mem_malloc(
10402 request->n_ssids*sizeof(tCsrSSIDInfo));
10403
10404 if(NULL == scanRequest.SSIDs.SSIDList)
10405 {
10406 hddLog(VOS_TRACE_LEVEL_ERROR,
10407 "%s: memory alloc failed SSIDInfo buffer", __func__);
10408 return -ENOMEM;
10409 }
10410
10411 /* copy all the ssid's and their length */
10412 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
10413 {
10414 /* get the ssid length */
10415 SsidInfo->SSID.length = request->ssids[j].ssid_len;
10416 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
10417 SsidInfo->SSID.length);
10418 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
10419 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
10420 j, SsidInfo->SSID.ssId);
10421 }
10422 /* set the scan type to active */
10423 scanRequest.scanType = eSIR_ACTIVE_SCAN;
10424 }
10425 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070010426 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010427 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10428 TRACE_CODE_HDD_CFG80211_SCAN,
10429 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070010430 /* set the scan type to active */
10431 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010432 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010433 else
10434 {
10435 /*Set the scan type to default type, in this case it is ACTIVE*/
10436 scanRequest.scanType = pScanInfo->scan_mode;
10437 }
10438 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
10439 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070010440
10441 /* set BSSType to default type */
10442 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
10443
10444 /*TODO: scan the requested channels only*/
10445
10446 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010447 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070010448 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010449 hddLog(VOS_TRACE_LEVEL_WARN,
10450 "No of Scan Channels exceeded limit: %d", request->n_channels);
10451 request->n_channels = MAX_CHANNEL;
10452 }
10453
10454 hddLog(VOS_TRACE_LEVEL_INFO,
10455 "No of Scan Channels: %d", request->n_channels);
10456
10457
10458 if( request->n_channels )
10459 {
10460 char chList [(request->n_channels*5)+1];
10461 int len;
10462 channelList = vos_mem_malloc( request->n_channels );
10463 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053010464 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010465 hddLog(VOS_TRACE_LEVEL_ERROR,
10466 "%s: memory alloc failed channelList", __func__);
10467 status = -ENOMEM;
10468 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053010469 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010470
10471 for( i = 0, len = 0; i < request->n_channels ; i++ )
10472 {
10473 channelList[i] = request->channels[i]->hw_value;
10474 len += snprintf(chList+len, 5, "%d ", channelList[i]);
10475 }
10476
Nirav Shah20ac06f2013-12-12 18:14:06 +053010477 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010478 "Channel-List: %s ", chList);
10479 }
c_hpothu53512302014-04-15 18:49:53 +053010480
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010481 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
10482 scanRequest.ChannelInfo.ChannelList = channelList;
10483
10484 /* set requestType to full scan */
10485 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10486
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010487 /* if there is back to back scan happening in driver with in
10488 * nDeferScanTimeInterval interval driver should defer new scan request
10489 * and should provide last cached scan results instead of new channel list.
10490 * This rule is not applicable if scan is p2p scan.
10491 * This condition will work only in case when last request no of channels
10492 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053010493 * This should be done only in connected state
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010494 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010495
Agarwal Ashish57e84372014-12-05 18:26:53 +053010496 if ((VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
10497 {
10498 if ( pScanInfo->last_scan_timestamp !=0 &&
10499 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
10500 {
10501 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
10502 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
10503 vos_mem_compare(pScanInfo->last_scan_channelList,
10504 channelList, pScanInfo->last_scan_numChannels))
10505 {
10506 hddLog(VOS_TRACE_LEVEL_WARN,
10507 " New and old station scan time differ is less then %u",
10508 pHddCtx->cfg_ini->nDeferScanTimeInterval);
10509
10510 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010511 pAdapter);
10512
Agarwal Ashish57e84372014-12-05 18:26:53 +053010513 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010514 "Return old cached scan as all channels and no of channels are same");
10515
Agarwal Ashish57e84372014-12-05 18:26:53 +053010516 if (0 > ret)
10517 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010518
Agarwal Ashish57e84372014-12-05 18:26:53 +053010519 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010520
10521 status = eHAL_STATUS_SUCCESS;
10522 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053010523 }
10524 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010525 }
10526
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010527 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10528 * search (Flush on both full scan and social scan but not on single
10529 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10530 */
10531
10532 /* Supplicant does single channel scan after 8-way handshake
10533 * and in that case driver shoudnt flush scan results. If
10534 * driver flushes the scan results here and unfortunately if
10535 * the AP doesnt respond to our probe req then association
10536 * fails which is not desired
10537 */
10538
10539 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
10540 {
10541 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
10542 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
10543 pAdapter->sessionId );
10544 }
10545
10546 if( request->ie_len )
10547 {
10548 /* save this for future association (join requires this) */
10549 /*TODO: Array needs to be converted to dynamic allocation,
10550 * as multiple ie.s can be sent in cfg80211_scan_request structure
10551 * CR 597966
10552 */
10553 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
10554 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
10555 pScanInfo->scanAddIE.length = request->ie_len;
10556
10557 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10558 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10559 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010560 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010561 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070010562 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010563 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
10564 memcpy( pwextBuf->roamProfile.addIEScan,
10565 request->ie, request->ie_len);
10566 }
10567 else
10568 {
10569 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
10570 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070010571 }
10572
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010573 }
10574 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
10575 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
10576
10577 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
10578 request->ie_len);
10579 if (pP2pIe != NULL)
10580 {
10581#ifdef WLAN_FEATURE_P2P_DEBUG
10582 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
10583 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
10584 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053010585 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010586 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
10587 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10588 "Go nego completed to Connection is started");
10589 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10590 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053010591 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010592 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
10593 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010594 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010595 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
10596 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10597 "Disconnected state to Connection is started");
10598 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10599 "for 4way Handshake");
10600 }
10601#endif
10602
10603 /* no_cck will be set during p2p find to disable 11b rates */
10604 if(TRUE == request->no_cck)
10605 {
10606 hddLog(VOS_TRACE_LEVEL_INFO,
10607 "%s: This is a P2P Search", __func__);
10608 scanRequest.p2pSearch = 1;
10609
10610 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053010611 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010612 /* set requestType to P2P Discovery */
10613 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
10614 }
10615
10616 /*
10617 Skip Dfs Channel in case of P2P Search
10618 if it is set in ini file
10619 */
10620 if(cfg_param->skipDfsChnlInP2pSearch)
10621 {
10622 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010623 }
10624 else
10625 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010626 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010627 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010628
Agarwal Ashish4f616132013-12-30 23:32:50 +053010629 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010630 }
10631 }
10632
10633 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
10634
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010635#ifdef FEATURE_WLAN_TDLS
10636 /* if tdls disagree scan right now, return immediately.
10637 tdls will schedule the scan when scan is allowed. (return SUCCESS)
10638 or will reject the scan if any TDLS is in progress. (return -EBUSY)
10639 */
10640 status = wlan_hdd_tdls_scan_callback (pAdapter,
10641 wiphy,
10642#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10643 dev,
10644#endif
10645 request);
10646 if(status <= 0)
10647 {
10648 if(!status)
10649 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
10650 "scan rejected %d", __func__, status);
10651 else
10652 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
10653 __func__, status);
10654
10655 return status;
10656 }
10657#endif
10658
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010659 /* acquire the wakelock to avoid the apps suspend during the scan. To
10660 * address the following issues.
10661 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
10662 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
10663 * for long time, this result in apps running at full power for long time.
10664 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
10665 * be stuck in full power because of resume BMPS
10666 */
10667 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -070010668
Nirav Shah20ac06f2013-12-12 18:14:06 +053010669 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10670 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010671 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
10672 scanRequest.requestType, scanRequest.scanType,
10673 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053010674 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
10675
Siddharth Bhal76972212014-10-15 16:22:51 +053010676 if (pHddCtx->spoofMacAddr.isEnabled)
10677 {
10678 hddLog(VOS_TRACE_LEVEL_INFO,
10679 "%s: MAC Spoofing enabled for current scan", __func__);
10680 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
10681 * to fill TxBds for probe request during current scan
10682 */
10683 WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
10684 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
10685 }
10686
Jeff Johnsone7245742012-09-05 17:12:55 -070010687 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010688 pAdapter->sessionId, &scanRequest, &scanId,
10689 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070010690
Jeff Johnson295189b2012-06-20 16:38:30 -070010691 if (eHAL_STATUS_SUCCESS != status)
10692 {
10693 hddLog(VOS_TRACE_LEVEL_ERROR,
10694 "%s: sme_ScanRequest returned error %d", __func__, status);
10695 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010696 if(eHAL_STATUS_RESOURCES == status)
10697 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010698 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
10699 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010700 status = -EBUSY;
10701 } else {
10702 status = -EIO;
10703 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010704 hdd_allow_suspend();
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010705
10706#ifdef FEATURE_WLAN_TDLS
10707 wlan_hdd_tdls_scan_done_callback(pAdapter);
10708#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010709 goto free_mem;
10710 }
10711
10712 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010713 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070010714 pAdapter->request = request;
10715 pScanInfo->scanId = scanId;
10716
10717 complete(&pScanInfo->scan_req_completion_event);
10718
10719free_mem:
10720 if( scanRequest.SSIDs.SSIDList )
10721 {
10722 vos_mem_free(scanRequest.SSIDs.SSIDList);
10723 }
10724
10725 if( channelList )
10726 vos_mem_free( channelList );
10727
10728 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010729 return status;
10730}
10731
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010732int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
10733#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10734 struct net_device *dev,
10735#endif
10736 struct cfg80211_scan_request *request)
10737{
10738 int ret;
10739
10740 vos_ssr_protect(__func__);
10741 ret = __wlan_hdd_cfg80211_scan(wiphy,
10742#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10743 dev,
10744#endif
10745 request);
10746 vos_ssr_unprotect(__func__);
10747
10748 return ret;
10749}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010750
10751void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
10752{
10753 v_U8_t iniDot11Mode =
10754 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
10755 eHddDot11Mode hddDot11Mode = iniDot11Mode;
10756
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010757 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
10758 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010759 switch ( iniDot11Mode )
10760 {
10761 case eHDD_DOT11_MODE_AUTO:
10762 case eHDD_DOT11_MODE_11ac:
10763 case eHDD_DOT11_MODE_11ac_ONLY:
10764#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053010765 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
10766 sme_IsFeatureSupportedByFW(DOT11AC) )
10767 hddDot11Mode = eHDD_DOT11_MODE_11ac;
10768 else
10769 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010770#else
10771 hddDot11Mode = eHDD_DOT11_MODE_11n;
10772#endif
10773 break;
10774 case eHDD_DOT11_MODE_11n:
10775 case eHDD_DOT11_MODE_11n_ONLY:
10776 hddDot11Mode = eHDD_DOT11_MODE_11n;
10777 break;
10778 default:
10779 hddDot11Mode = iniDot11Mode;
10780 break;
10781 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010782#ifdef WLAN_FEATURE_AP_HT40_24G
10783 if (operationChannel > SIR_11B_CHANNEL_END)
10784#endif
10785 {
10786 /* This call decides required channel bonding mode */
10787 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010788 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
10789 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010790 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010791}
10792
Jeff Johnson295189b2012-06-20 16:38:30 -070010793/*
10794 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010795 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010796 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010797int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010798 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010799{
10800 int status = 0;
10801 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080010802 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010803 v_U32_t roamId;
10804 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070010805 eCsrAuthType RSNAuthType;
10806
10807 ENTER();
10808
10809 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080010810 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10811
10812 status = wlan_hdd_validate_context(pHddCtx);
10813 if (status)
10814 {
Yue Mae36e3552014-03-05 17:06:20 -080010815 return status;
10816 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010817
Jeff Johnson295189b2012-06-20 16:38:30 -070010818 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
10819 {
10820 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
10821 return -EINVAL;
10822 }
10823
10824 pRoamProfile = &pWextState->roamProfile;
10825
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010826 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070010827 {
Jeff Johnsone7245742012-09-05 17:12:55 -070010828 hdd_station_ctx_t *pHddStaCtx;
10829 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010830
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010831 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070010832 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
10833 {
10834 /*QoS not enabled in cfg file*/
10835 pRoamProfile->uapsd_mask = 0;
10836 }
10837 else
10838 {
10839 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010840 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070010841 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
10842 }
10843
10844 pRoamProfile->SSIDs.numOfSSIDs = 1;
10845 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
10846 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010847 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070010848 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
10849 ssid, ssid_len);
10850
10851 if (bssid)
10852 {
10853 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
10854 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
10855 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010856 /* Save BSSID in seperate variable as well, as RoamProfile
10857 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070010858 case of join failure we should send valid BSSID to supplicant
10859 */
10860 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
10861 WNI_CFG_BSSID_LEN);
10862 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070010863 else
10864 {
10865 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
10866 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010867
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010868 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
10869 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010870 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
10871 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010872 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010873 /*set gen ie*/
10874 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
10875 /*set auth*/
10876 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
10877 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010878#ifdef FEATURE_WLAN_WAPI
10879 if (pAdapter->wapi_info.nWapiMode)
10880 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010881 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010882 switch (pAdapter->wapi_info.wapiAuthMode)
10883 {
10884 case WAPI_AUTH_MODE_PSK:
10885 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010886 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010887 pAdapter->wapi_info.wapiAuthMode);
10888 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
10889 break;
10890 }
10891 case WAPI_AUTH_MODE_CERT:
10892 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010893 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010894 pAdapter->wapi_info.wapiAuthMode);
10895 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
10896 break;
10897 }
10898 } // End of switch
10899 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
10900 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
10901 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010902 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010903 pRoamProfile->AuthType.numEntries = 1;
10904 pRoamProfile->EncryptionType.numEntries = 1;
10905 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10906 pRoamProfile->mcEncryptionType.numEntries = 1;
10907 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10908 }
10909 }
10910#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010911#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010912 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010913 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10914 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
10915 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010916 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
10917 sizeof (tSirGtkOffloadParams));
10918 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010919 }
10920#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010921 pRoamProfile->csrPersona = pAdapter->device_mode;
10922
Jeff Johnson32d95a32012-09-10 13:15:23 -070010923 if( operatingChannel )
10924 {
10925 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
10926 pRoamProfile->ChannelInfo.numOfChannels = 1;
10927 }
Chet Lanctot186b5732013-03-18 10:26:30 -070010928 else
10929 {
10930 pRoamProfile->ChannelInfo.ChannelList = NULL;
10931 pRoamProfile->ChannelInfo.numOfChannels = 0;
10932 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010933 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
10934 {
10935 hdd_select_cbmode(pAdapter,operatingChannel);
10936 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010937
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010938 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
10939 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010940 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010941 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010942 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
10943 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010944 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10945 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053010946 {
10947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10948 "%s: Set HDD connState to eConnectionState_Connecting",
10949 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010950 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
10951 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053010952 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010953 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010954 pAdapter->sessionId, pRoamProfile, &roamId);
10955
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010956 if ((eHAL_STATUS_SUCCESS != status) &&
10957 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10958 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010959
10960 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010961 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
10962 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
10963 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010964 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010965 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010966 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010967
10968 pRoamProfile->ChannelInfo.ChannelList = NULL;
10969 pRoamProfile->ChannelInfo.numOfChannels = 0;
10970
Jeff Johnson295189b2012-06-20 16:38:30 -070010971 }
10972 else
10973 {
10974 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
10975 return -EINVAL;
10976 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010977 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010978 return status;
10979}
10980
10981/*
10982 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
10983 * This function is used to set the authentication type (OPEN/SHARED).
10984 *
10985 */
10986static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
10987 enum nl80211_auth_type auth_type)
10988{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010989 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010990 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10991
10992 ENTER();
10993
10994 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010995 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070010996 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010997 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010998 hddLog(VOS_TRACE_LEVEL_INFO,
10999 "%s: set authentication type to AUTOSWITCH", __func__);
11000 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
11001 break;
11002
11003 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011004#ifdef WLAN_FEATURE_VOWIFI_11R
11005 case NL80211_AUTHTYPE_FT:
11006#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011007 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011008 "%s: set authentication type to OPEN", __func__);
11009 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11010 break;
11011
11012 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011013 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011014 "%s: set authentication type to SHARED", __func__);
11015 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
11016 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011017#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011018 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011019 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011020 "%s: set authentication type to CCKM WPA", __func__);
11021 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
11022 break;
11023#endif
11024
11025
11026 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011027 hddLog(VOS_TRACE_LEVEL_ERROR,
11028 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011029 auth_type);
11030 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
11031 return -EINVAL;
11032 }
11033
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011034 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011035 pHddStaCtx->conn_info.authType;
11036 return 0;
11037}
11038
11039/*
11040 * FUNCTION: wlan_hdd_set_akm_suite
11041 * This function is used to set the key mgmt type(PSK/8021x).
11042 *
11043 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011044static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011045 u32 key_mgmt
11046 )
11047{
11048 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11049 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053011050 /* Should be in ieee802_11_defs.h */
11051#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
11052#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070011053 /*set key mgmt type*/
11054 switch(key_mgmt)
11055 {
11056 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053011057 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011058#ifdef WLAN_FEATURE_VOWIFI_11R
11059 case WLAN_AKM_SUITE_FT_PSK:
11060#endif
11061 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070011062 __func__);
11063 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
11064 break;
11065
11066 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053011067 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011068#ifdef WLAN_FEATURE_VOWIFI_11R
11069 case WLAN_AKM_SUITE_FT_8021X:
11070#endif
11071 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070011072 __func__);
11073 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11074 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011075#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011076#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
11077#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
11078 case WLAN_AKM_SUITE_CCKM:
11079 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
11080 __func__);
11081 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
11082 break;
11083#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070011084#ifndef WLAN_AKM_SUITE_OSEN
11085#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
11086 case WLAN_AKM_SUITE_OSEN:
11087 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
11088 __func__);
11089 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11090 break;
11091#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011092
11093 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011094 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011095 __func__, key_mgmt);
11096 return -EINVAL;
11097
11098 }
11099 return 0;
11100}
11101
11102/*
11103 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011104 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070011105 * (NONE/WEP40/WEP104/TKIP/CCMP).
11106 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011107static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
11108 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070011109 bool ucast
11110 )
11111{
11112 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011113 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011114 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11115
11116 ENTER();
11117
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011118 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011119 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011120 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070011121 __func__, cipher);
11122 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11123 }
11124 else
11125 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011126
Jeff Johnson295189b2012-06-20 16:38:30 -070011127 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011128 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011129 {
11130 case IW_AUTH_CIPHER_NONE:
11131 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11132 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011133
Jeff Johnson295189b2012-06-20 16:38:30 -070011134 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011135 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070011136 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011137
Jeff Johnson295189b2012-06-20 16:38:30 -070011138 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011139 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070011140 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011141
Jeff Johnson295189b2012-06-20 16:38:30 -070011142 case WLAN_CIPHER_SUITE_TKIP:
11143 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
11144 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011145
Jeff Johnson295189b2012-06-20 16:38:30 -070011146 case WLAN_CIPHER_SUITE_CCMP:
11147 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11148 break;
11149#ifdef FEATURE_WLAN_WAPI
11150 case WLAN_CIPHER_SUITE_SMS4:
11151 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
11152 break;
11153#endif
11154
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011155#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011156 case WLAN_CIPHER_SUITE_KRK:
11157 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
11158 break;
11159#endif
11160 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011161 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011162 __func__, cipher);
11163 return -EOPNOTSUPP;
11164 }
11165 }
11166
11167 if (ucast)
11168 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011169 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011170 __func__, encryptionType);
11171 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11172 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011173 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011174 encryptionType;
11175 }
11176 else
11177 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011178 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011179 __func__, encryptionType);
11180 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
11181 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
11182 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
11183 }
11184
11185 return 0;
11186}
11187
11188
11189/*
11190 * FUNCTION: wlan_hdd_cfg80211_set_ie
11191 * This function is used to parse WPA/RSN IE's.
11192 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011193int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
11194 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070011195 size_t ie_len
11196 )
11197{
11198 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11199 u8 *genie = ie;
11200 v_U16_t remLen = ie_len;
11201#ifdef FEATURE_WLAN_WAPI
11202 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
11203 u16 *tmp;
11204 v_U16_t akmsuiteCount;
11205 int *akmlist;
11206#endif
11207 ENTER();
11208
11209 /* clear previous assocAddIE */
11210 pWextState->assocAddIE.length = 0;
11211 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011212 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011213
11214 while (remLen >= 2)
11215 {
11216 v_U16_t eLen = 0;
11217 v_U8_t elementId;
11218 elementId = *genie++;
11219 eLen = *genie++;
11220 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011221
Arif Hussain6d2a3322013-11-17 19:50:10 -080011222 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070011223 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011224
11225 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070011226 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011227 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011228 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 -070011229 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011230 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011231 "%s: Invalid WPA IE", __func__);
11232 return -EINVAL;
11233 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011234 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070011235 {
11236 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011237 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011238 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011239
Jeff Johnson295189b2012-06-20 16:38:30 -070011240 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11241 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011242 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
11243 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011244 VOS_ASSERT(0);
11245 return -ENOMEM;
11246 }
11247 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11248 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11249 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011250
Jeff Johnson295189b2012-06-20 16:38:30 -070011251 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
11252 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11253 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11254 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011255 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
11256 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011257 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
11258 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11259 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
11260 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
11261 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
11262 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011263 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053011264 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011265 {
11266 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011267 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011268 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011269
Jeff Johnson295189b2012-06-20 16:38:30 -070011270 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11271 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011272 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11273 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011274 VOS_ASSERT(0);
11275 return -ENOMEM;
11276 }
11277 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11278 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11279 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011280
Jeff Johnson295189b2012-06-20 16:38:30 -070011281 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11282 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11283 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011284#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011285 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
11286 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011287 /*Consider WFD IE, only for P2P Client */
11288 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11289 {
11290 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011291 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011292 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011293
Jeff Johnson295189b2012-06-20 16:38:30 -070011294 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11295 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011296 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11297 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011298 VOS_ASSERT(0);
11299 return -ENOMEM;
11300 }
11301 // WFD IE is saved to Additional IE ; it should be accumulated to handle
11302 // WPS IE + P2P IE + WFD IE
11303 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11304 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011305
Jeff Johnson295189b2012-06-20 16:38:30 -070011306 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11307 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11308 }
11309#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011310 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011311 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011312 HS20_OUI_TYPE_SIZE)) )
11313 {
11314 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011315 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011316 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011317
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011318 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11319 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011320 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11321 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011322 VOS_ASSERT(0);
11323 return -ENOMEM;
11324 }
11325 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11326 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011327
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011328 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11329 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11330 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011331 /* Appending OSEN Information Element in Assiciation Request */
11332 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
11333 OSEN_OUI_TYPE_SIZE)) )
11334 {
11335 v_U16_t curAddIELen = pWextState->assocAddIE.length;
11336 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
11337 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011338
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011339 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11340 {
11341 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11342 "Need bigger buffer space");
11343 VOS_ASSERT(0);
11344 return -ENOMEM;
11345 }
11346 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11347 pWextState->assocAddIE.length += eLen + 2;
11348
11349 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
11350 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11351 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11352 }
11353
11354 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070011355 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
11356
11357 /* populating as ADDIE in beacon frames */
11358 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11359 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
11360 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
11361 {
11362 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11363 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
11364 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11365 {
11366 hddLog(LOGE,
11367 "Coldn't pass "
11368 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
11369 }
11370 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
11371 else
11372 hddLog(LOGE,
11373 "Could not pass on "
11374 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
11375
11376 /* IBSS mode doesn't contain params->proberesp_ies still
11377 beaconIE's need to be populated in probe response frames */
11378 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
11379 {
11380 u16 rem_probe_resp_ie_len = eLen + 2;
11381 u8 probe_rsp_ie_len[3] = {0};
11382 u8 counter = 0;
11383
11384 /* Check Probe Resp Length if it is greater then 255 then
11385 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
11386 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
11387 not able Store More then 255 bytes into One Variable */
11388
11389 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
11390 {
11391 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
11392 {
11393 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
11394 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
11395 }
11396 else
11397 {
11398 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
11399 rem_probe_resp_ie_len = 0;
11400 }
11401 }
11402
11403 rem_probe_resp_ie_len = 0;
11404
11405 if (probe_rsp_ie_len[0] > 0)
11406 {
11407 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11408 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
11409 (tANI_U8*)(genie - 2),
11410 probe_rsp_ie_len[0], NULL,
11411 eANI_BOOLEAN_FALSE)
11412 == eHAL_STATUS_FAILURE)
11413 {
11414 hddLog(LOGE,
11415 "Could not pass"
11416 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
11417 }
11418 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
11419 }
11420
11421 if (probe_rsp_ie_len[1] > 0)
11422 {
11423 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11424 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
11425 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11426 probe_rsp_ie_len[1], NULL,
11427 eANI_BOOLEAN_FALSE)
11428 == eHAL_STATUS_FAILURE)
11429 {
11430 hddLog(LOGE,
11431 "Could not pass"
11432 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
11433 }
11434 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
11435 }
11436
11437 if (probe_rsp_ie_len[2] > 0)
11438 {
11439 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11440 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
11441 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11442 probe_rsp_ie_len[2], NULL,
11443 eANI_BOOLEAN_FALSE)
11444 == eHAL_STATUS_FAILURE)
11445 {
11446 hddLog(LOGE,
11447 "Could not pass"
11448 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
11449 }
11450 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
11451 }
11452
11453 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11454 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
11455 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11456 {
11457 hddLog(LOGE,
11458 "Could not pass"
11459 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
11460 }
11461 }
11462 else
11463 {
11464 // Reset WNI_CFG_PROBE_RSP Flags
11465 wlan_hdd_reset_prob_rspies(pAdapter);
11466
11467 hddLog(VOS_TRACE_LEVEL_INFO,
11468 "%s: No Probe Response IE received in set beacon",
11469 __func__);
11470 }
11471 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011472 break;
11473 case DOT11F_EID_RSN:
11474 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
11475 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11476 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
11477 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
11478 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
11479 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011480 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
11481 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011482 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011483 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011484 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011485 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011486
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011487 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11488 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011489 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11490 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011491 VOS_ASSERT(0);
11492 return -ENOMEM;
11493 }
11494 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11495 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011496
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011497 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11498 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11499 break;
11500 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011501#ifdef FEATURE_WLAN_WAPI
11502 case WLAN_EID_WAPI:
11503 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011504 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011505 pAdapter->wapi_info.nWapiMode);
11506 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011507 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070011508 akmsuiteCount = WPA_GET_LE16(tmp);
11509 tmp = tmp + 1;
11510 akmlist = (int *)(tmp);
11511 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
11512 {
11513 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
11514 }
11515 else
11516 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011517 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070011518 VOS_ASSERT(0);
11519 return -EINVAL;
11520 }
11521
11522 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
11523 {
11524 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011525 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011526 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011527 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011528 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011529 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011530 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011531 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011532 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
11533 }
11534 break;
11535#endif
11536 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011537 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011538 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011539 /* when Unknown IE is received we should break and continue
11540 * to the next IE in the buffer instead we were returning
11541 * so changing this to break */
11542 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011543 }
11544 genie += eLen;
11545 remLen -= eLen;
11546 }
11547 EXIT();
11548 return 0;
11549}
11550
11551/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053011552 * FUNCTION: hdd_isWPAIEPresent
11553 * Parse the received IE to find the WPA IE
11554 *
11555 */
11556static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
11557{
11558 v_U8_t eLen = 0;
11559 v_U16_t remLen = ie_len;
11560 v_U8_t elementId = 0;
11561
11562 while (remLen >= 2)
11563 {
11564 elementId = *ie++;
11565 eLen = *ie++;
11566 remLen -= 2;
11567 if (eLen > remLen)
11568 {
11569 hddLog(VOS_TRACE_LEVEL_ERROR,
11570 "%s: IE length is wrong %d", __func__, eLen);
11571 return FALSE;
11572 }
11573 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
11574 {
11575 /* OUI - 0x00 0X50 0XF2
11576 WPA Information Element - 0x01
11577 WPA version - 0x01*/
11578 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
11579 return TRUE;
11580 }
11581 ie += eLen;
11582 remLen -= eLen;
11583 }
11584 return FALSE;
11585}
11586
11587/*
Jeff Johnson295189b2012-06-20 16:38:30 -070011588 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011589 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011590 * parameters during connect operation.
11591 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011592int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011593 struct cfg80211_connect_params *req
11594 )
11595{
11596 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011597 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011598 ENTER();
11599
11600 /*set wpa version*/
11601 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
11602
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011603 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011604 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053011605 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011606 {
11607 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11608 }
11609 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
11610 {
11611 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11612 }
11613 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011614
11615 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011616 pWextState->wpaVersion);
11617
11618 /*set authentication type*/
11619 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
11620
11621 if (0 > status)
11622 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011623 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011624 "%s: failed to set authentication type ", __func__);
11625 return status;
11626 }
11627
11628 /*set key mgmt type*/
11629 if (req->crypto.n_akm_suites)
11630 {
11631 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
11632 if (0 > status)
11633 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011634 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070011635 __func__);
11636 return status;
11637 }
11638 }
11639
11640 /*set pairwise cipher type*/
11641 if (req->crypto.n_ciphers_pairwise)
11642 {
11643 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
11644 req->crypto.ciphers_pairwise[0], true);
11645 if (0 > status)
11646 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011647 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011648 "%s: failed to set unicast cipher type", __func__);
11649 return status;
11650 }
11651 }
11652 else
11653 {
11654 /*Reset previous cipher suite to none*/
11655 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
11656 if (0 > status)
11657 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011658 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011659 "%s: failed to set unicast cipher type", __func__);
11660 return status;
11661 }
11662 }
11663
11664 /*set group cipher type*/
11665 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
11666 false);
11667
11668 if (0 > status)
11669 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011670 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070011671 __func__);
11672 return status;
11673 }
11674
Chet Lanctot186b5732013-03-18 10:26:30 -070011675#ifdef WLAN_FEATURE_11W
11676 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
11677#endif
11678
Jeff Johnson295189b2012-06-20 16:38:30 -070011679 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
11680 if (req->ie_len)
11681 {
11682 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
11683 if ( 0 > status)
11684 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011685 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011686 __func__);
11687 return status;
11688 }
11689 }
11690
11691 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011692 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011693 {
11694 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
11695 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
11696 )
11697 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011698 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070011699 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
11700 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011701 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011702 __func__);
11703 return -EOPNOTSUPP;
11704 }
11705 else
11706 {
11707 u8 key_len = req->key_len;
11708 u8 key_idx = req->key_idx;
11709
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011710 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011711 && (CSR_MAX_NUM_KEY > key_idx)
11712 )
11713 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011714 hddLog(VOS_TRACE_LEVEL_INFO,
11715 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011716 __func__, key_idx, key_len);
11717 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011718 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011719 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011720 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011721 (u8)key_len;
11722 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
11723 }
11724 }
11725 }
11726 }
11727
11728 return status;
11729}
11730
11731/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011732 * FUNCTION: wlan_hdd_try_disconnect
11733 * This function is used to disconnect from previous
11734 * connection
11735 */
11736static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
11737{
11738 long ret = 0;
11739 hdd_station_ctx_t *pHddStaCtx;
11740 eMib_dot11DesiredBssType connectedBssType;
11741
11742 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11743
11744 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
11745
11746 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
11747 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
11748 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
11749 {
11750 /* Issue disconnect to CSR */
11751 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11752 if( eHAL_STATUS_SUCCESS ==
11753 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11754 pAdapter->sessionId,
11755 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11756 {
11757 ret = wait_for_completion_interruptible_timeout(
11758 &pAdapter->disconnect_comp_var,
11759 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11760 if (0 >= ret)
11761 {
11762 hddLog(LOGE, FL("Failed to receive disconnect event"));
11763 return -EALREADY;
11764 }
11765 }
11766 }
11767 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
11768 {
11769 ret = wait_for_completion_interruptible_timeout(
11770 &pAdapter->disconnect_comp_var,
11771 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11772 if (0 >= ret)
11773 {
11774 hddLog(LOGE, FL("Failed to receive disconnect event"));
11775 return -EALREADY;
11776 }
11777 }
11778
11779 return 0;
11780}
11781
11782/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053011783 * FUNCTION: __wlan_hdd_cfg80211_connect
11784 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011785 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011786static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011787 struct net_device *ndev,
11788 struct cfg80211_connect_params *req
11789 )
11790{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011791 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011792 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011793 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053011794 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011795
11796 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011797
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011798 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11799 TRACE_CODE_HDD_CFG80211_CONNECT,
11800 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011801 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011802 "%s: device_mode = %s (%d)", __func__,
11803 hdd_device_modetoString(pAdapter->device_mode),
11804 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011805
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011806 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011807 if (!pHddCtx)
11808 {
11809 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11810 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011811 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011812 }
11813
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011814 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011815 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011816 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011817 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011818 }
11819
Agarwal Ashish51325b52014-06-16 16:50:49 +053011820 if (vos_max_concurrent_connections_reached()) {
11821 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11822 return -ECONNREFUSED;
11823 }
11824
Jeff Johnson295189b2012-06-20 16:38:30 -070011825#ifdef WLAN_BTAMP_FEATURE
11826 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011827 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070011828 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011829 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011830 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011831 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070011832 }
11833#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011834
11835 //If Device Mode is Station Concurrent Sessions Exit BMps
11836 //P2P Mode will be taken care in Open/close adapter
11837 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011838 (vos_concurrent_open_sessions_running())) {
11839 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
11840 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011841 }
11842
11843 /*Try disconnecting if already in connected state*/
11844 status = wlan_hdd_try_disconnect(pAdapter);
11845 if ( 0 > status)
11846 {
11847 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11848 " connection"));
11849 return -EALREADY;
11850 }
11851
Jeff Johnson295189b2012-06-20 16:38:30 -070011852 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011853 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070011854
11855 if ( 0 > status)
11856 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011857 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070011858 __func__);
11859 return status;
11860 }
Mohit Khanna765234a2012-09-11 15:08:35 -070011861 if ( req->channel )
11862 {
11863 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
11864 req->ssid_len, req->bssid,
11865 req->channel->hw_value);
11866 }
11867 else
11868 {
11869 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011870 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070011871 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011872
11873 if (0 > status)
11874 {
11875 //ReEnable BMPS if disabled
11876 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
11877 (NULL != pHddCtx))
11878 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011879 if (pHddCtx->hdd_wlan_suspended)
11880 {
11881 hdd_set_pwrparams(pHddCtx);
11882 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011883 //ReEnable Bmps and Imps back
11884 hdd_enable_bmps_imps(pHddCtx);
11885 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011886 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011887 return status;
11888 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011889 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011890 EXIT();
11891 return status;
11892}
11893
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011894static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
11895 struct net_device *ndev,
11896 struct cfg80211_connect_params *req)
11897{
11898 int ret;
11899 vos_ssr_protect(__func__);
11900 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
11901 vos_ssr_unprotect(__func__);
11902
11903 return ret;
11904}
Jeff Johnson295189b2012-06-20 16:38:30 -070011905
11906/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011907 * FUNCTION: wlan_hdd_disconnect
11908 * This function is used to issue a disconnect request to SME
11909 */
11910int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
11911{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011912 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011913 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011914 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011915 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011916
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011917 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011918
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011919 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011920 if (0 != status)
11921 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011922 return status;
11923 }
11924
11925 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011926
Agarwal Ashish47d18112014-08-04 19:55:07 +053011927 /* Need to apply spin lock before decreasing active sessions
11928 * as there can be chance for double decrement if context switch
11929 * Calls hdd_DisConnectHandler.
11930 */
11931
11932 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011933 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11934 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011935 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11936 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053011937 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
11938 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011939
Abhishek Singhf4669da2014-05-26 15:07:49 +053011940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053011941 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
11942
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011943 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011944
Mihir Shete182a0b22014-08-18 16:08:48 +053011945 /*
11946 * stop tx queues before deleting STA/BSS context from the firmware.
11947 * tx has to be disabled because the firmware can get busy dropping
11948 * the tx frames after BSS/STA has been deleted and will not send
11949 * back a response resulting in WDI timeout
11950 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053011951 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053011952 netif_tx_disable(pAdapter->dev);
11953 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011954
Mihir Shete182a0b22014-08-18 16:08:48 +053011955 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011956 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11957 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011958 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
11959 {
11960 hddLog(VOS_TRACE_LEVEL_INFO,
11961 FL("status = %d, already disconnected"),
11962 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011963
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011964 }
11965 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011966 {
11967 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011968 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011969 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011970 result = -EINVAL;
11971 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011972 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011973 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011974 &pAdapter->disconnect_comp_var,
11975 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011976 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011977 {
11978 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011979 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011980 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011981 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011982 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011983 {
11984 hddLog(VOS_TRACE_LEVEL_ERROR,
11985 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011986 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011987 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011988disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11990 FL("Set HDD connState to eConnectionState_NotConnected"));
11991 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
11992
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011993 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011994 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011995}
11996
11997
11998/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011999 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070012000 * This function is used to issue a disconnect request to SME
12001 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012002static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012003 struct net_device *dev,
12004 u16 reason
12005 )
12006{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012007 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012008 tCsrRoamProfile *pRoamProfile =
12009 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012010 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012011 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12012 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012013#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012014 tANI_U8 staIdx;
12015#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012016
Jeff Johnson295189b2012-06-20 16:38:30 -070012017 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012018
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012019 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12020 TRACE_CODE_HDD_CFG80211_DISCONNECT,
12021 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012022 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
12023 __func__, hdd_device_modetoString(pAdapter->device_mode),
12024 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012025
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012026 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
12027 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070012028
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012029 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012030 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012031 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012032 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012033 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012034
Jeff Johnson295189b2012-06-20 16:38:30 -070012035 if (NULL != pRoamProfile)
12036 {
12037 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012038 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
12039 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070012040 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012041 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070012042 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012043 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012044 switch(reason)
12045 {
12046 case WLAN_REASON_MIC_FAILURE:
12047 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
12048 break;
12049
12050 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
12051 case WLAN_REASON_DISASSOC_AP_BUSY:
12052 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
12053 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
12054 break;
12055
12056 case WLAN_REASON_PREV_AUTH_NOT_VALID:
12057 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053012058 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070012059 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
12060 break;
12061
Jeff Johnson295189b2012-06-20 16:38:30 -070012062 default:
12063 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
12064 break;
12065 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012066 pScanInfo = &pHddCtx->scan_info;
12067 if (pScanInfo->mScanPending)
12068 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012069 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012070 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012071 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012072 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012073 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012074
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012075#ifdef FEATURE_WLAN_TDLS
12076 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012077 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012078 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012079 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
12080 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012081 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012082 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012083 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012084 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012085 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012086 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012087 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012088 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012089 pAdapter->sessionId,
12090 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012091 }
12092 }
12093#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012094 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012095 status = wlan_hdd_disconnect(pAdapter, reasonCode);
12096 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070012097 {
12098 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012099 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012100 __func__, (int)status );
12101 return -EINVAL;
12102 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012103 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012104 else
12105 {
12106 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
12107 "called while in %d state", __func__,
12108 pHddStaCtx->conn_info.connState);
12109 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012110 }
12111 else
12112 {
12113 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
12114 }
12115
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012116 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012117 return status;
12118}
12119
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012120static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
12121 struct net_device *dev,
12122 u16 reason
12123 )
12124{
12125 int ret;
12126 vos_ssr_protect(__func__);
12127 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
12128 vos_ssr_unprotect(__func__);
12129
12130 return ret;
12131}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012132
Jeff Johnson295189b2012-06-20 16:38:30 -070012133/*
12134 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012135 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012136 * settings in IBSS mode.
12137 */
12138static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012139 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012140 struct cfg80211_ibss_params *params
12141 )
12142{
12143 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012144 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012145 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12146 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012147
Jeff Johnson295189b2012-06-20 16:38:30 -070012148 ENTER();
12149
12150 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070012151 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070012152
12153 if (params->ie_len && ( NULL != params->ie) )
12154 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012155 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12156 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012157 {
12158 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12159 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12160 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012161 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012162 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012163 tDot11fIEWPA dot11WPAIE;
12164 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012165 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012166
Wilson Yang00256342013-10-10 23:13:38 -070012167 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012168 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12169 params->ie_len, DOT11F_EID_WPA);
12170 if ( NULL != ie )
12171 {
12172 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12173 // Unpack the WPA IE
12174 //Skip past the EID byte and length byte - and four byte WiFi OUI
12175 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
12176 &ie[2+4],
12177 ie[1] - 4,
12178 &dot11WPAIE);
12179 /*Extract the multicast cipher, the encType for unicast
12180 cipher for wpa-none is none*/
12181 encryptionType =
12182 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
12183 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012184 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012185
Jeff Johnson295189b2012-06-20 16:38:30 -070012186 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
12187
12188 if (0 > status)
12189 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012190 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012191 __func__);
12192 return status;
12193 }
12194 }
12195
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012196 pWextState->roamProfile.AuthType.authType[0] =
12197 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012198 eCSR_AUTH_TYPE_OPEN_SYSTEM;
12199
12200 if (params->privacy)
12201 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012202 /* Security enabled IBSS, At this time there is no information available
12203 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070012204 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012205 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070012206 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012207 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070012208 *enable privacy bit in beacons */
12209
12210 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12211 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012212 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
12213 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070012214 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12215 pWextState->roamProfile.EncryptionType.numEntries = 1;
12216 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070012217 return status;
12218}
12219
12220/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012221 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012222 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012223 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012224static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012225 struct net_device *dev,
12226 struct cfg80211_ibss_params *params
12227 )
12228{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012229 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012230 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12231 tCsrRoamProfile *pRoamProfile;
12232 int status;
krunal sonie9002db2013-11-25 14:24:17 -080012233 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012234 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12235 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012236
12237 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012238
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012239 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12240 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
12241 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012242 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012243 "%s: device_mode = %s (%d)", __func__,
12244 hdd_device_modetoString(pAdapter->device_mode),
12245 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012246
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012247 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012248 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012249 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012250 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012251 }
12252
12253 if (NULL == pWextState)
12254 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012255 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012256 __func__);
12257 return -EIO;
12258 }
12259
Agarwal Ashish51325b52014-06-16 16:50:49 +053012260 if (vos_max_concurrent_connections_reached()) {
12261 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12262 return -ECONNREFUSED;
12263 }
12264
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012265 /*Try disconnecting if already in connected state*/
12266 status = wlan_hdd_try_disconnect(pAdapter);
12267 if ( 0 > status)
12268 {
12269 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12270 " IBSS connection"));
12271 return -EALREADY;
12272 }
12273
Jeff Johnson295189b2012-06-20 16:38:30 -070012274 pRoamProfile = &pWextState->roamProfile;
12275
12276 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
12277 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012278 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012279 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012280 return -EINVAL;
12281 }
12282
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012283 /* BSSID is provided by upper layers hence no need to AUTO generate */
12284 if (NULL != params->bssid) {
12285 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12286 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
12287 hddLog (VOS_TRACE_LEVEL_ERROR,
12288 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12289 return -EIO;
12290 }
12291 }
krunal sonie9002db2013-11-25 14:24:17 -080012292 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
12293 {
12294 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12295 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
12296 {
12297 hddLog (VOS_TRACE_LEVEL_ERROR,
12298 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12299 return -EIO;
12300 }
12301 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
12302 if (!params->bssid)
12303 {
12304 hddLog (VOS_TRACE_LEVEL_ERROR,
12305 "%s:Failed memory allocation", __func__);
12306 return -EIO;
12307 }
12308 vos_mem_copy((v_U8_t *)params->bssid,
12309 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
12310 VOS_MAC_ADDR_SIZE);
12311 alloc_bssid = VOS_TRUE;
12312 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012313
Jeff Johnson295189b2012-06-20 16:38:30 -070012314 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070012315 if (NULL !=
12316#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12317 params->chandef.chan)
12318#else
12319 params->channel)
12320#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012321 {
12322 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012323 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12324 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
12325 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12326 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012327
12328 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012329 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070012330 ieee80211_frequency_to_channel(
12331#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12332 params->chandef.chan->center_freq);
12333#else
12334 params->channel->center_freq);
12335#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012336
12337 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12338 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070012339 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012340 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
12341 __func__);
12342 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012343 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012344
12345 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012346 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012347 if (channelNum == validChan[indx])
12348 {
12349 break;
12350 }
12351 }
12352 if (indx >= numChans)
12353 {
12354 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012355 __func__, channelNum);
12356 return -EINVAL;
12357 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012358 /* Set the Operational Channel */
12359 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
12360 channelNum);
12361 pRoamProfile->ChannelInfo.numOfChannels = 1;
12362 pHddStaCtx->conn_info.operationChannel = channelNum;
12363 pRoamProfile->ChannelInfo.ChannelList =
12364 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070012365 }
12366
12367 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012368 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070012369 if (status < 0)
12370 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012371 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070012372 __func__);
12373 return status;
12374 }
12375
12376 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012377 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012378 params->ssid_len, params->bssid,
12379 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012380
12381 if (0 > status)
12382 {
12383 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
12384 return status;
12385 }
12386
krunal sonie9002db2013-11-25 14:24:17 -080012387 if (NULL != params->bssid &&
12388 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
12389 alloc_bssid == VOS_TRUE)
12390 {
12391 vos_mem_free(params->bssid);
12392 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012393 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012394 return 0;
12395}
12396
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012397static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
12398 struct net_device *dev,
12399 struct cfg80211_ibss_params *params
12400 )
12401{
12402 int ret = 0;
12403
12404 vos_ssr_protect(__func__);
12405 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
12406 vos_ssr_unprotect(__func__);
12407
12408 return ret;
12409}
12410
Jeff Johnson295189b2012-06-20 16:38:30 -070012411/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012412 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012413 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012414 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012415static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012416 struct net_device *dev
12417 )
12418{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012419 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012420 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12421 tCsrRoamProfile *pRoamProfile;
12422 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012423 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012424
12425 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012426
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012427 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12428 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
12429 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012430 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012431 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012432 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012433 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012434 }
12435
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012436 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
12437 hdd_device_modetoString(pAdapter->device_mode),
12438 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012439 if (NULL == pWextState)
12440 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012441 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012442 __func__);
12443 return -EIO;
12444 }
12445
12446 pRoamProfile = &pWextState->roamProfile;
12447
12448 /* Issue disconnect only if interface type is set to IBSS */
12449 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
12450 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012451 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070012452 __func__);
12453 return -EINVAL;
12454 }
12455
12456 /* Issue Disconnect request */
12457 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12458 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12459 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
12460
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012461 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012462 return 0;
12463}
12464
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012465static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
12466 struct net_device *dev
12467 )
12468{
12469 int ret = 0;
12470
12471 vos_ssr_protect(__func__);
12472 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
12473 vos_ssr_unprotect(__func__);
12474
12475 return ret;
12476}
12477
Jeff Johnson295189b2012-06-20 16:38:30 -070012478/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012479 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070012480 * This function is used to set the phy parameters
12481 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
12482 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012483static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012484 u32 changed)
12485{
12486 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
12487 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012488 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012489
12490 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012491
12492 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012493 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
12494 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012495
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012496 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012497 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012498 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012499 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012500 }
12501
Jeff Johnson295189b2012-06-20 16:38:30 -070012502 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
12503 {
12504 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
12505 WNI_CFG_RTS_THRESHOLD_STAMAX :
12506 wiphy->rts_threshold;
12507
12508 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012509 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070012510 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012511 hddLog(VOS_TRACE_LEVEL_ERROR,
12512 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012513 __func__, rts_threshold);
12514 return -EINVAL;
12515 }
12516
12517 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
12518 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012519 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012520 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012521 hddLog(VOS_TRACE_LEVEL_ERROR,
12522 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012523 __func__, rts_threshold);
12524 return -EIO;
12525 }
12526
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012527 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012528 rts_threshold);
12529 }
12530
12531 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
12532 {
12533 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
12534 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
12535 wiphy->frag_threshold;
12536
12537 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012538 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012539 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012540 hddLog(VOS_TRACE_LEVEL_ERROR,
12541 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012542 frag_threshold);
12543 return -EINVAL;
12544 }
12545
12546 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
12547 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012548 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012549 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012550 hddLog(VOS_TRACE_LEVEL_ERROR,
12551 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012552 __func__, frag_threshold);
12553 return -EIO;
12554 }
12555
12556 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
12557 frag_threshold);
12558 }
12559
12560 if ((changed & WIPHY_PARAM_RETRY_SHORT)
12561 || (changed & WIPHY_PARAM_RETRY_LONG))
12562 {
12563 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
12564 wiphy->retry_short :
12565 wiphy->retry_long;
12566
12567 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
12568 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
12569 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012570 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012571 __func__, retry_value);
12572 return -EINVAL;
12573 }
12574
12575 if (changed & WIPHY_PARAM_RETRY_SHORT)
12576 {
12577 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
12578 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012579 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012580 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012581 hddLog(VOS_TRACE_LEVEL_ERROR,
12582 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012583 __func__, retry_value);
12584 return -EIO;
12585 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012586 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012587 __func__, retry_value);
12588 }
12589 else if (changed & WIPHY_PARAM_RETRY_SHORT)
12590 {
12591 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
12592 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012593 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012594 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012595 hddLog(VOS_TRACE_LEVEL_ERROR,
12596 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012597 __func__, retry_value);
12598 return -EIO;
12599 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012600 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012601 __func__, retry_value);
12602 }
12603 }
12604
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012605 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012606 return 0;
12607}
12608
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012609static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
12610 u32 changed)
12611{
12612 int ret;
12613
12614 vos_ssr_protect(__func__);
12615 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
12616 vos_ssr_unprotect(__func__);
12617
12618 return ret;
12619}
12620
Jeff Johnson295189b2012-06-20 16:38:30 -070012621/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012622 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012623 * This function is used to set the txpower
12624 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012625static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012626#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12627 struct wireless_dev *wdev,
12628#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012629#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012630 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012631#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012632 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012633#endif
12634 int dbm)
12635{
12636 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012637 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012638 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12639 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012640 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012641
12642 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012643
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012644 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12645 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
12646 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012647 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012648 if (0 != status)
12649 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012650 return status;
12651 }
12652
12653 hHal = pHddCtx->hHal;
12654
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012655 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
12656 dbm, ccmCfgSetCallback,
12657 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012658 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012659 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012660 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
12661 return -EIO;
12662 }
12663
12664 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
12665 dbm);
12666
12667 switch(type)
12668 {
12669 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
12670 /* Fall through */
12671 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
12672 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
12673 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012674 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
12675 __func__);
12676 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012677 }
12678 break;
12679 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012680 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012681 __func__);
12682 return -EOPNOTSUPP;
12683 break;
12684 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012685 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
12686 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070012687 return -EIO;
12688 }
12689
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012690 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012691 return 0;
12692}
12693
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012694static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
12695#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12696 struct wireless_dev *wdev,
12697#endif
12698#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12699 enum tx_power_setting type,
12700#else
12701 enum nl80211_tx_power_setting type,
12702#endif
12703 int dbm)
12704{
12705 int ret;
12706 vos_ssr_protect(__func__);
12707 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
12708#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12709 wdev,
12710#endif
12711#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12712 type,
12713#else
12714 type,
12715#endif
12716 dbm);
12717 vos_ssr_unprotect(__func__);
12718
12719 return ret;
12720}
12721
Jeff Johnson295189b2012-06-20 16:38:30 -070012722/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012723 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012724 * This function is used to read the txpower
12725 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012726static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012727#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12728 struct wireless_dev *wdev,
12729#endif
12730 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070012731{
12732
12733 hdd_adapter_t *pAdapter;
12734 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012735 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012736
Jeff Johnsone7245742012-09-05 17:12:55 -070012737 ENTER();
12738
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012739 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012740 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012741 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012742 *dbm = 0;
12743 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012744 }
12745
Jeff Johnson295189b2012-06-20 16:38:30 -070012746 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
12747 if (NULL == pAdapter)
12748 {
12749 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
12750 return -ENOENT;
12751 }
12752
12753 wlan_hdd_get_classAstats(pAdapter);
12754 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
12755
Jeff Johnsone7245742012-09-05 17:12:55 -070012756 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012757 return 0;
12758}
12759
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012760static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
12761#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12762 struct wireless_dev *wdev,
12763#endif
12764 int *dbm)
12765{
12766 int ret;
12767
12768 vos_ssr_protect(__func__);
12769 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
12770#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12771 wdev,
12772#endif
12773 dbm);
12774 vos_ssr_unprotect(__func__);
12775
12776 return ret;
12777}
12778
12779
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012780static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070012781 u8* mac, struct station_info *sinfo)
12782{
12783 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12784 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12785 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053012786 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070012787
12788 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
12789 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012790
12791 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
12792 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
12793 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
12794 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
12795 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
12796 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
12797 tANI_U16 maxRate = 0;
12798 tANI_U16 myRate;
12799 tANI_U16 currentRate = 0;
12800 tANI_U8 maxSpeedMCS = 0;
12801 tANI_U8 maxMCSIdx = 0;
12802 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053012803 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012804 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012805 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012806
Leo Chang6f8870f2013-03-26 18:11:36 -070012807#ifdef WLAN_FEATURE_11AC
12808 tANI_U32 vht_mcs_map;
12809 eDataRate11ACMaxMcs vhtMaxMcs;
12810#endif /* WLAN_FEATURE_11AC */
12811
Jeff Johnsone7245742012-09-05 17:12:55 -070012812 ENTER();
12813
Jeff Johnson295189b2012-06-20 16:38:30 -070012814 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
12815 (0 == ssidlen))
12816 {
12817 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
12818 " Invalid ssidlen, %d", __func__, ssidlen);
12819 /*To keep GUI happy*/
12820 return 0;
12821 }
12822
Mukul Sharma811205f2014-07-09 21:07:30 +053012823 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
12824 {
12825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12826 "%s: Roaming in progress, so unable to proceed this request", __func__);
12827 return 0;
12828 }
12829
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012830 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012831 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012832 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012833 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012834 }
12835
Jeff Johnson295189b2012-06-20 16:38:30 -070012836
Kiet Lam3b17fc82013-09-27 05:24:08 +053012837 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
12838 sinfo->filled |= STATION_INFO_SIGNAL;
12839
c_hpothu09f19542014-05-30 21:53:31 +053012840 wlan_hdd_get_station_stats(pAdapter);
12841 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
12842
12843 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053012844 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
12845 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053012846 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053012847 {
12848 rate_flags = pAdapter->maxRateFlags;
12849 }
c_hpothu44ff4e02014-05-08 00:13:57 +053012850
Jeff Johnson295189b2012-06-20 16:38:30 -070012851 //convert to the UI units of 100kbps
12852 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
12853
12854#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070012855 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 -070012856 sinfo->signal,
12857 pCfg->reportMaxLinkSpeed,
12858 myRate,
12859 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012860 (int) pCfg->linkSpeedRssiMid,
12861 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070012862 (int) rate_flags,
12863 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012864#endif //LINKSPEED_DEBUG_ENABLED
12865
12866 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
12867 {
12868 // we do not want to necessarily report the current speed
12869 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
12870 {
12871 // report the max possible speed
12872 rssidx = 0;
12873 }
12874 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
12875 {
12876 // report the max possible speed with RSSI scaling
12877 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
12878 {
12879 // report the max possible speed
12880 rssidx = 0;
12881 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012882 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070012883 {
12884 // report middle speed
12885 rssidx = 1;
12886 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012887 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
12888 {
12889 // report middle speed
12890 rssidx = 2;
12891 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012892 else
12893 {
12894 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012895 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070012896 }
12897 }
12898 else
12899 {
12900 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
12901 hddLog(VOS_TRACE_LEVEL_ERROR,
12902 "%s: Invalid value for reportMaxLinkSpeed: %u",
12903 __func__, pCfg->reportMaxLinkSpeed);
12904 rssidx = 0;
12905 }
12906
12907 maxRate = 0;
12908
12909 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012910 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
12911 OperationalRates, &ORLeng))
12912 {
12913 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12914 /*To keep GUI happy*/
12915 return 0;
12916 }
12917
Jeff Johnson295189b2012-06-20 16:38:30 -070012918 for (i = 0; i < ORLeng; i++)
12919 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012920 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012921 {
12922 /* Validate Rate Set */
12923 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
12924 {
12925 currentRate = supported_data_rate[j].supported_rate[rssidx];
12926 break;
12927 }
12928 }
12929 /* Update MAX rate */
12930 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12931 }
12932
12933 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012934 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
12935 ExtendedRates, &ERLeng))
12936 {
12937 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12938 /*To keep GUI happy*/
12939 return 0;
12940 }
12941
Jeff Johnson295189b2012-06-20 16:38:30 -070012942 for (i = 0; i < ERLeng; i++)
12943 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012944 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012945 {
12946 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
12947 {
12948 currentRate = supported_data_rate[j].supported_rate[rssidx];
12949 break;
12950 }
12951 }
12952 /* Update MAX rate */
12953 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12954 }
c_hpothu79aab322014-07-14 21:11:01 +053012955
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012956 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053012957 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012958 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053012959 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070012960 {
c_hpothu79aab322014-07-14 21:11:01 +053012961 if (rate_flags & eHAL_TX_RATE_VHT80)
12962 mode = 2;
12963 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
12964 mode = 1;
12965 else
12966 mode = 0;
12967
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012968 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
12969 MCSRates, &MCSLeng))
12970 {
12971 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12972 /*To keep GUI happy*/
12973 return 0;
12974 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012975 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070012976#ifdef WLAN_FEATURE_11AC
12977 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012978 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070012979 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012980 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012981 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070012982 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070012983 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012984 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070012985 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012986 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070012987 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012988 maxMCSIdx = 7;
12989 }
12990 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
12991 {
12992 maxMCSIdx = 8;
12993 }
12994 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
12995 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012996 //VHT20 is supporting 0~8
12997 if (rate_flags & eHAL_TX_RATE_VHT20)
12998 maxMCSIdx = 8;
12999 else
13000 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070013001 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013002
c_hpothu79aab322014-07-14 21:11:01 +053013003 if (0 != rssidx)/*check for scaled */
13004 {
13005 //get middle rate MCS index if rssi=1/2
13006 for (i=0; i <= maxMCSIdx; i++)
13007 {
13008 if (sinfo->signal <= rssiMcsTbl[mode][i])
13009 {
13010 maxMCSIdx = i;
13011 break;
13012 }
13013 }
13014 }
13015
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013016 if (rate_flags & eHAL_TX_RATE_VHT80)
13017 {
13018 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
13019 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
13020 }
13021 else if (rate_flags & eHAL_TX_RATE_VHT40)
13022 {
13023 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
13024 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
13025 }
13026 else if (rate_flags & eHAL_TX_RATE_VHT20)
13027 {
13028 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
13029 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
13030 }
13031
Leo Chang6f8870f2013-03-26 18:11:36 -070013032 maxSpeedMCS = 1;
13033 if (currentRate > maxRate)
13034 {
13035 maxRate = currentRate;
13036 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013037
Leo Chang6f8870f2013-03-26 18:11:36 -070013038 }
13039 else
13040#endif /* WLAN_FEATURE_11AC */
13041 {
13042 if (rate_flags & eHAL_TX_RATE_HT40)
13043 {
13044 rateFlag |= 1;
13045 }
13046 if (rate_flags & eHAL_TX_RATE_SGI)
13047 {
13048 rateFlag |= 2;
13049 }
13050
Girish Gowli01abcee2014-07-31 20:18:55 +053013051 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053013052 if (rssidx == 1 || rssidx == 2)
13053 {
13054 //get middle rate MCS index if rssi=1/2
13055 for (i=0; i <= 7; i++)
13056 {
13057 if (sinfo->signal <= rssiMcsTbl[mode][i])
13058 {
13059 temp = i+1;
13060 break;
13061 }
13062 }
13063 }
c_hpothu79aab322014-07-14 21:11:01 +053013064
13065 for (i = 0; i < MCSLeng; i++)
13066 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013067 for (j = 0; j < temp; j++)
13068 {
13069 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
13070 {
13071 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
13072 break;
13073 }
13074 }
13075 if ((j < temp) && (currentRate > maxRate))
13076 {
13077 maxRate = currentRate;
13078 maxSpeedMCS = 1;
13079 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
13080 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013081 }
13082 }
13083 }
13084
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013085 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
13086 {
13087 maxRate = myRate;
13088 maxSpeedMCS = 1;
13089 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13090 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013091 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053013092 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070013093 {
13094 maxRate = myRate;
13095 if (rate_flags & eHAL_TX_RATE_LEGACY)
13096 {
13097 maxSpeedMCS = 0;
13098 }
13099 else
13100 {
13101 maxSpeedMCS = 1;
13102 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13103 }
13104 }
13105
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013106 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070013107 {
13108 sinfo->txrate.legacy = maxRate;
13109#ifdef LINKSPEED_DEBUG_ENABLED
13110 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
13111#endif //LINKSPEED_DEBUG_ENABLED
13112 }
13113 else
13114 {
13115 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070013116#ifdef WLAN_FEATURE_11AC
13117 sinfo->txrate.nss = 1;
13118 if (rate_flags & eHAL_TX_RATE_VHT80)
13119 {
13120 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013121 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070013122 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013123 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070013124 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013125 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13126 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13127 }
13128 else if (rate_flags & eHAL_TX_RATE_VHT20)
13129 {
13130 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13131 }
13132#endif /* WLAN_FEATURE_11AC */
13133 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
13134 {
13135 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13136 if (rate_flags & eHAL_TX_RATE_HT40)
13137 {
13138 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13139 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013140 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013141 if (rate_flags & eHAL_TX_RATE_SGI)
13142 {
13143 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13144 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013145
Jeff Johnson295189b2012-06-20 16:38:30 -070013146#ifdef LINKSPEED_DEBUG_ENABLED
13147 pr_info("Reporting MCS rate %d flags %x\n",
13148 sinfo->txrate.mcs,
13149 sinfo->txrate.flags );
13150#endif //LINKSPEED_DEBUG_ENABLED
13151 }
13152 }
13153 else
13154 {
13155 // report current rate instead of max rate
13156
13157 if (rate_flags & eHAL_TX_RATE_LEGACY)
13158 {
13159 //provide to the UI in units of 100kbps
13160 sinfo->txrate.legacy = myRate;
13161#ifdef LINKSPEED_DEBUG_ENABLED
13162 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
13163#endif //LINKSPEED_DEBUG_ENABLED
13164 }
13165 else
13166 {
13167 //must be MCS
13168 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013169#ifdef WLAN_FEATURE_11AC
13170 sinfo->txrate.nss = 1;
13171 if (rate_flags & eHAL_TX_RATE_VHT80)
13172 {
13173 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13174 }
13175 else
13176#endif /* WLAN_FEATURE_11AC */
13177 {
13178 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13179 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013180 if (rate_flags & eHAL_TX_RATE_SGI)
13181 {
13182 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13183 }
13184 if (rate_flags & eHAL_TX_RATE_HT40)
13185 {
13186 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13187 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013188#ifdef WLAN_FEATURE_11AC
13189 else if (rate_flags & eHAL_TX_RATE_VHT80)
13190 {
13191 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
13192 }
13193#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070013194#ifdef LINKSPEED_DEBUG_ENABLED
13195 pr_info("Reporting actual MCS rate %d flags %x\n",
13196 sinfo->txrate.mcs,
13197 sinfo->txrate.flags );
13198#endif //LINKSPEED_DEBUG_ENABLED
13199 }
13200 }
13201 sinfo->filled |= STATION_INFO_TX_BITRATE;
13202
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013203 sinfo->tx_packets =
13204 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
13205 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
13206 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
13207 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
13208
13209 sinfo->tx_retries =
13210 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
13211 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
13212 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
13213 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
13214
13215 sinfo->tx_failed =
13216 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
13217 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
13218 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
13219 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
13220
13221 sinfo->filled |=
13222 STATION_INFO_TX_PACKETS |
13223 STATION_INFO_TX_RETRIES |
13224 STATION_INFO_TX_FAILED;
13225
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013226 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13227 TRACE_CODE_HDD_CFG80211_GET_STA,
13228 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013229 EXIT();
13230 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013231}
13232
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013233static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13234 u8* mac, struct station_info *sinfo)
13235{
13236 int ret;
13237
13238 vos_ssr_protect(__func__);
13239 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
13240 vos_ssr_unprotect(__func__);
13241
13242 return ret;
13243}
13244
13245static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070013246 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070013247{
13248 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013249 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013250 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013251 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013252
Jeff Johnsone7245742012-09-05 17:12:55 -070013253 ENTER();
13254
Jeff Johnson295189b2012-06-20 16:38:30 -070013255 if (NULL == pAdapter)
13256 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013257 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013258 return -ENODEV;
13259 }
13260
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013261 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13262 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
13263 pAdapter->sessionId, timeout));
13264
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013265 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013266 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013267 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013268 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013269 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013270 }
13271
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013272 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
13273 (TRUE == pHddCtx->hdd_wlan_suspended) &&
13274 (pHddCtx->cfg_ini->fhostArpOffload) &&
13275 (eConnectionState_Associated ==
13276 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13277 {
Amar Singhald53568e2013-09-26 11:03:45 -070013278
13279 hddLog(VOS_TRACE_LEVEL_INFO,
13280 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053013281 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013282 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13283 {
13284 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013285 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013286 __func__, vos_status);
13287 }
13288 }
13289
Jeff Johnson295189b2012-06-20 16:38:30 -070013290 /**The get power cmd from the supplicant gets updated by the nl only
13291 *on successful execution of the function call
13292 *we are oppositely mapped w.r.t mode in the driver
13293 **/
13294 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
13295
13296 if (VOS_STATUS_E_FAILURE == vos_status)
13297 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013298 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13299 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013300 return -EINVAL;
13301 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013302 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013303 return 0;
13304}
13305
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013306static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
13307 struct net_device *dev, bool mode, int timeout)
13308{
13309 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013310
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013311 vos_ssr_protect(__func__);
13312 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
13313 vos_ssr_unprotect(__func__);
13314
13315 return ret;
13316}
Jeff Johnson295189b2012-06-20 16:38:30 -070013317#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013318static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
13319 struct net_device *netdev,
13320 u8 key_index)
13321{
13322 ENTER();
13323 return 0;
13324}
13325
Jeff Johnson295189b2012-06-20 16:38:30 -070013326static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013327 struct net_device *netdev,
13328 u8 key_index)
13329{
13330 int ret;
13331 vos_ssr_protect(__func__);
13332 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
13333 vos_ssr_unprotect(__func__);
13334 return ret;
13335}
13336#endif //LINUX_VERSION_CODE
13337
13338#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13339static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13340 struct net_device *dev,
13341 struct ieee80211_txq_params *params)
13342{
13343 ENTER();
13344 return 0;
13345}
13346#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13347static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13348 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013349{
Jeff Johnsone7245742012-09-05 17:12:55 -070013350 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013351 return 0;
13352}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013353#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070013354
13355#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13356static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013357 struct net_device *dev,
13358 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013359{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013360 int ret;
13361
13362 vos_ssr_protect(__func__);
13363 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
13364 vos_ssr_unprotect(__func__);
13365 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013366}
13367#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13368static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
13369 struct ieee80211_txq_params *params)
13370{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013371 int ret;
13372
13373 vos_ssr_protect(__func__);
13374 ret = __wlan_hdd_set_txq_params(wiphy, params);
13375 vos_ssr_unprotect(__func__);
13376 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013377}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013378#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013379
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013380static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013381 struct net_device *dev,
13382 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070013383{
13384 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013385 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013386 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013387 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013388 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013389 v_CONTEXT_t pVosContext = NULL;
13390 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013391
Jeff Johnsone7245742012-09-05 17:12:55 -070013392 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013393
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013394 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070013395 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013396 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013397 return -EINVAL;
13398 }
13399
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013400 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13401 TRACE_CODE_HDD_CFG80211_DEL_STA,
13402 pAdapter->sessionId, pAdapter->device_mode));
13403
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013404 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13405 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013406 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013407 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013408 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013409 }
13410
Jeff Johnson295189b2012-06-20 16:38:30 -070013411 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013412 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013413 )
13414 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013415 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13416 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13417 if(pSapCtx == NULL){
13418 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13419 FL("psapCtx is NULL"));
13420 return -ENOENT;
13421 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013422 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013423 {
13424 v_U16_t i;
13425 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13426 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013427 if ((pSapCtx->aStaInfo[i].isUsed) &&
13428 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070013429 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013430 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013431 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013432 ETHER_ADDR_LEN);
13433
Jeff Johnson295189b2012-06-20 16:38:30 -070013434 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013435 "%s: Delete STA with MAC::"
13436 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013437 __func__,
13438 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
13439 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013440 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013441 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013442 }
13443 }
13444 }
13445 else
13446 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013447
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013448 vos_status = hdd_softap_GetStaId(pAdapter,
13449 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013450 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13451 {
13452 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013453 "%s: Skip this DEL STA as this is not used::"
13454 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013455 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013456 return -ENOENT;
13457 }
13458
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013459 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013460 {
13461 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013462 "%s: Skip this DEL STA as deauth is in progress::"
13463 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013464 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013465 return -ENOENT;
13466 }
13467
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013468 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013469
Jeff Johnson295189b2012-06-20 16:38:30 -070013470 hddLog(VOS_TRACE_LEVEL_INFO,
13471 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013472 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013473 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013474 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013475
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013476 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013477 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13478 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013479 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013480 hddLog(VOS_TRACE_LEVEL_INFO,
13481 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013482 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013483 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013484 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013485 return -ENOENT;
13486 }
13487
Jeff Johnson295189b2012-06-20 16:38:30 -070013488 }
13489 }
13490
13491 EXIT();
13492
13493 return 0;
13494}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013495
13496#ifdef CFG80211_DEL_STA_V2
13497static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13498 struct net_device *dev,
13499 struct station_del_parameters *param)
13500#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013501static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13502 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013503#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013504{
13505 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013506 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070013507
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013508 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013509
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013510#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013511 if (NULL == param) {
13512 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013513 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013514 return -EINVAL;
13515 }
13516
13517 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
13518 param->subtype, &delStaParams);
13519
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013520#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053013521 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013522 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013523#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013524 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
13525
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013526 vos_ssr_unprotect(__func__);
13527
13528 return ret;
13529}
13530
13531static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013532 struct net_device *dev, u8 *mac, struct station_parameters *params)
13533{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013534 hdd_adapter_t *pAdapter;
13535 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013536 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013537#ifdef FEATURE_WLAN_TDLS
13538 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013539
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013540 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013541
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013542 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13543 if (NULL == pAdapter)
13544 {
13545 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13546 "%s: Adapter is NULL",__func__);
13547 return -EINVAL;
13548 }
13549 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13550 status = wlan_hdd_validate_context(pHddCtx);
13551 if (0 != status)
13552 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013553 return status;
13554 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013555
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013556 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13557 TRACE_CODE_HDD_CFG80211_ADD_STA,
13558 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013559 mask = params->sta_flags_mask;
13560
13561 set = params->sta_flags_set;
13562
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013563#ifdef WLAN_FEATURE_TDLS_DEBUG
13564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13565 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
13566 __func__, mask, set, MAC_ADDR_ARRAY(mac));
13567#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013568
13569 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13570 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013571 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013572 }
13573 }
13574#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013575 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013576 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013577}
13578
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013579static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
13580 struct net_device *dev, u8 *mac, struct station_parameters *params)
13581{
13582 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013583
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013584 vos_ssr_protect(__func__);
13585 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
13586 vos_ssr_unprotect(__func__);
13587
13588 return ret;
13589}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013590#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070013591
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013592static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070013593 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013594{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013595 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13596 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013597 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013598 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013599 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013600 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070013601
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013602 ENTER();
13603
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013604 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013605 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013606 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013607 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013608 return -EINVAL;
13609 }
13610
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013611 if (!pmksa) {
13612 hddLog(LOGE, FL("pmksa is NULL"));
13613 return -EINVAL;
13614 }
13615
13616 if (!pmksa->bssid || !pmksa->pmkid) {
13617 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
13618 pmksa->bssid, pmksa->pmkid);
13619 return -EINVAL;
13620 }
13621
13622 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
13623 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13624
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013625 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13626 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013627 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013628 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013629 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013630 }
13631
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013632 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013633 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13634
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013635 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
13636 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013637
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013638 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013639 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013640 &pmk_id, 1, FALSE);
13641
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013642 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13643 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
13644 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013645
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013646 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013647 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013648}
13649
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013650static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
13651 struct cfg80211_pmksa *pmksa)
13652{
13653 int ret;
13654
13655 vos_ssr_protect(__func__);
13656 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
13657 vos_ssr_unprotect(__func__);
13658
13659 return ret;
13660}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013661
Wilson Yang6507c4e2013-10-01 20:11:19 -070013662
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013663static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070013664 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013665{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013666 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13667 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013668 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013669 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013670
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013671 ENTER();
13672
Wilson Yang6507c4e2013-10-01 20:11:19 -070013673 /* Validate pAdapter */
13674 if (NULL == pAdapter)
13675 {
13676 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
13677 return -EINVAL;
13678 }
13679
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013680 if (!pmksa) {
13681 hddLog(LOGE, FL("pmksa is NULL"));
13682 return -EINVAL;
13683 }
13684
13685 if (!pmksa->bssid) {
13686 hddLog(LOGE, FL("pmksa->bssid is NULL"));
13687 return -EINVAL;
13688 }
13689
Kiet Lam98c46a12014-10-31 15:34:57 -070013690 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
13691 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13692
Wilson Yang6507c4e2013-10-01 20:11:19 -070013693 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13694 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070013695 if (0 != status)
13696 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070013697 return status;
13698 }
13699
13700 /*Retrieve halHandle*/
13701 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13702
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013703 /* Delete the PMKID CSR cache */
13704 if (eHAL_STATUS_SUCCESS !=
13705 sme_RoamDelPMKIDfromCache(halHandle,
13706 pAdapter->sessionId, pmksa->bssid, FALSE)) {
13707 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
13708 MAC_ADDR_ARRAY(pmksa->bssid));
13709 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013710 }
13711
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013712 EXIT();
13713 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013714}
13715
Wilson Yang6507c4e2013-10-01 20:11:19 -070013716
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013717static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
13718 struct cfg80211_pmksa *pmksa)
13719{
13720 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013721
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013722 vos_ssr_protect(__func__);
13723 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
13724 vos_ssr_unprotect(__func__);
13725
13726 return ret;
13727
13728}
13729
13730static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013731{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013732 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13733 tHalHandle halHandle;
13734 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013735 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013736
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013737 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070013738
13739 /* Validate pAdapter */
13740 if (NULL == pAdapter)
13741 {
13742 hddLog(VOS_TRACE_LEVEL_ERROR,
13743 "%s: Invalid Adapter" ,__func__);
13744 return -EINVAL;
13745 }
13746
13747 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13748 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070013749 if (0 != status)
13750 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070013751 return status;
13752 }
13753
13754 /*Retrieve halHandle*/
13755 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13756
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013757 /* Flush the PMKID cache in CSR */
13758 if (eHAL_STATUS_SUCCESS !=
13759 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
13760 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
13761 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013762 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013763 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080013764 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013765}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013766
13767static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
13768{
13769 int ret;
13770
13771 vos_ssr_protect(__func__);
13772 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
13773 vos_ssr_unprotect(__func__);
13774
13775 return ret;
13776}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013777#endif
13778
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013779#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013780static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13781 struct net_device *dev,
13782 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013783{
13784 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13785 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013786 hdd_context_t *pHddCtx;
13787 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013788
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013789 ENTER();
13790
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013791 if (NULL == pAdapter)
13792 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013793 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013794 return -ENODEV;
13795 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013796 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13797 ret = wlan_hdd_validate_context(pHddCtx);
13798 if (0 != ret)
13799 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013800 return ret;
13801 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013802 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013803 if (NULL == pHddStaCtx)
13804 {
13805 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
13806 return -EINVAL;
13807 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013808
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013809 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13810 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
13811 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013812 // Added for debug on reception of Re-assoc Req.
13813 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
13814 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013815 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013816 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080013817 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013818 }
13819
13820#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080013821 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013822 ftie->ie_len);
13823#endif
13824
13825 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013826 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13827 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013828 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013829
13830 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013831 return 0;
13832}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013833
13834static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13835 struct net_device *dev,
13836 struct cfg80211_update_ft_ies_params *ftie)
13837{
13838 int ret;
13839
13840 vos_ssr_protect(__func__);
13841 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
13842 vos_ssr_unprotect(__func__);
13843
13844 return ret;
13845}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013846#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013847
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013848#ifdef FEATURE_WLAN_SCAN_PNO
13849
13850void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
13851 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
13852{
13853 int ret;
13854 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
13855 hdd_context_t *pHddCtx;
13856
Nirav Shah80830bf2013-12-31 16:35:12 +053013857 ENTER();
13858
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013859 if (NULL == pAdapter)
13860 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013861 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013862 "%s: HDD adapter is Null", __func__);
13863 return ;
13864 }
13865
13866 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13867 if (NULL == pHddCtx)
13868 {
13869 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13870 "%s: HDD context is Null!!!", __func__);
13871 return ;
13872 }
13873
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013874 spin_lock(&pHddCtx->schedScan_lock);
13875 if (TRUE == pHddCtx->isWiphySuspended)
13876 {
13877 pHddCtx->isSchedScanUpdatePending = TRUE;
13878 spin_unlock(&pHddCtx->schedScan_lock);
13879 hddLog(VOS_TRACE_LEVEL_INFO,
13880 "%s: Update cfg80211 scan database after it resume", __func__);
13881 return ;
13882 }
13883 spin_unlock(&pHddCtx->schedScan_lock);
13884
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013885 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
13886
13887 if (0 > ret)
13888 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
13889
13890 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013891 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13892 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013893}
13894
13895/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013896 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013897 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013898 */
13899static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
13900{
13901 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13902 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013903 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013904 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13905 int status = 0;
13906 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13907
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013908 /* The current firmware design does not allow PNO during any
13909 * active sessions. Hence, determine the active sessions
13910 * and return a failure.
13911 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013912 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
13913 {
13914 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013915 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013916
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013917 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
13918 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
13919 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
13920 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
13921 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053013922 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013923 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013924 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013925 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013926 }
13927 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13928 pAdapterNode = pNext;
13929 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013930 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013931}
13932
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013933void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
13934{
13935 hdd_adapter_t *pAdapter = callbackContext;
13936 hdd_context_t *pHddCtx;
13937
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013938 ENTER();
13939
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013940 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
13941 {
13942 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13943 FL("Invalid adapter or adapter has invalid magic"));
13944 return;
13945 }
13946
13947 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13948 if (0 != wlan_hdd_validate_context(pHddCtx))
13949 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013950 return;
13951 }
13952
c_hpothub53c45d2014-08-18 16:53:14 +053013953 if (VOS_STATUS_SUCCESS != status)
13954 {
13955 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013956 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053013957 pHddCtx->isPnoEnable = FALSE;
13958 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013959
13960 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
13961 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013962 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013963}
13964
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013965/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013966 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
13967 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013968 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013969static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013970 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13971{
13972 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053013973 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013974 hdd_context_t *pHddCtx;
13975 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013976 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053013977 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
13978 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013979 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13980 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013981 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013982 hdd_config_t *pConfig = NULL;
13983 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013984
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013985 ENTER();
13986
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013987 if (NULL == pAdapter)
13988 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013990 "%s: HDD adapter is Null", __func__);
13991 return -ENODEV;
13992 }
13993
13994 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013995 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013996
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013997 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013998 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013999 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014000 }
14001
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014002 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014003 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14004 if (NULL == hHal)
14005 {
14006 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14007 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014008 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014009 }
Sushant Kaushik2fe89932014-09-03 10:58:09 +053014010 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014011 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053014012 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014013 {
14014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14015 "%s: aborting the existing scan is unsuccessfull", __func__);
14016 return -EBUSY;
14017 }
14018
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014019 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014020 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014021 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014022 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014023 return -EBUSY;
14024 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014025
c_hpothu37f21312014-04-09 21:49:54 +053014026 if (TRUE == pHddCtx->isPnoEnable)
14027 {
14028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14029 FL("already PNO is enabled"));
14030 return -EBUSY;
14031 }
c_hpothu225aa7c2014-10-22 17:45:13 +053014032
14033 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
14034 {
14035 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14036 "%s: abort ROC failed ", __func__);
14037 return -EBUSY;
14038 }
14039
c_hpothu37f21312014-04-09 21:49:54 +053014040 pHddCtx->isPnoEnable = TRUE;
14041
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014042 pnoRequest.enable = 1; /*Enable PNO */
14043 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014044
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014045 if (( !pnoRequest.ucNetworksCount ) ||
14046 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014047 {
14048 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014049 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014050 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014051 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014052 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014053 goto error;
14054 }
14055
14056 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
14057 {
14058 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014059 "%s: Incorrect number of channels %d",
14060 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014061 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014062 goto error;
14063 }
14064
14065 /* Framework provides one set of channels(all)
14066 * common for all saved profile */
14067 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14068 channels_allowed, &num_channels_allowed))
14069 {
14070 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14071 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014072 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014073 goto error;
14074 }
14075 /* Checking each channel against allowed channel list */
14076 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053014077 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014078 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014079 char chList [(request->n_channels*5)+1];
14080 int len;
14081 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014082 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014083 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014084 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014085 if (request->channels[i]->hw_value == channels_allowed[indx])
14086 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014087 if ((!pConfig->enableDFSPnoChnlScan) &&
14088 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
14089 {
14090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14091 "%s : Dropping DFS channel : %d",
14092 __func__,channels_allowed[indx]);
14093 num_ignore_dfs_ch++;
14094 break;
14095 }
14096
Nirav Shah80830bf2013-12-31 16:35:12 +053014097 valid_ch[num_ch++] = request->channels[i]->hw_value;
14098 len += snprintf(chList+len, 5, "%d ",
14099 request->channels[i]->hw_value);
14100 break ;
14101 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014102 }
14103 }
Nirav Shah80830bf2013-12-31 16:35:12 +053014104 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014105
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014106 /*If all channels are DFS and dropped, then ignore the PNO request*/
14107 if (num_ignore_dfs_ch == request->n_channels)
14108 {
14109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14110 "%s : All requested channels are DFS channels", __func__);
14111 ret = -EINVAL;
14112 goto error;
14113 }
14114 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014115
14116 pnoRequest.aNetworks =
14117 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14118 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014119 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014120 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14121 FL("failed to allocate memory aNetworks %u"),
14122 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14123 goto error;
14124 }
14125 vos_mem_zero(pnoRequest.aNetworks,
14126 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14127
14128 /* Filling per profile params */
14129 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
14130 {
14131 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014132 request->match_sets[i].ssid.ssid_len;
14133
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014134 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
14135 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014136 {
14137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014138 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014139 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014140 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014141 goto error;
14142 }
14143
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014144 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014145 request->match_sets[i].ssid.ssid,
14146 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14148 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014149 i, pnoRequest.aNetworks[i].ssId.ssId);
14150 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
14151 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
14152 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014153
14154 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014155 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
14156 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014157
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014158 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014159 }
14160
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014161 for (i = 0; i < request->n_ssids; i++)
14162 {
14163 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014164 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014165 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014166 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014167 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014168 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014169 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014170 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014171 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014172 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014173 break;
14174 }
14175 j++;
14176 }
14177 }
14178 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14179 "Number of hidden networks being Configured = %d",
14180 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014181 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080014182 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014183
14184 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14185 if (pnoRequest.p24GProbeTemplate == NULL)
14186 {
14187 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14188 FL("failed to allocate memory p24GProbeTemplate %u"),
14189 SIR_PNO_MAX_PB_REQ_SIZE);
14190 goto error;
14191 }
14192
14193 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14194 if (pnoRequest.p5GProbeTemplate == NULL)
14195 {
14196 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14197 FL("failed to allocate memory p5GProbeTemplate %u"),
14198 SIR_PNO_MAX_PB_REQ_SIZE);
14199 goto error;
14200 }
14201
14202 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14203 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14204
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053014205 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
14206 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014207 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014208 pnoRequest.us24GProbeTemplateLen = request->ie_len;
14209 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
14210 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014211
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014212 pnoRequest.us5GProbeTemplateLen = request->ie_len;
14213 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
14214 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014215 }
14216
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014217 /* Driver gets only one time interval which is hardcoded in
14218 * supplicant for 10000ms. Taking power consumption into account 6 timers
14219 * will be used, Timervalue is increased exponentially i.e 10,20,40,
14220 * 80,160,320 secs. And number of scan cycle for each timer
14221 * is configurable through INI param gPNOScanTimerRepeatValue.
14222 * If it is set to 0 only one timer will be used and PNO scan cycle
14223 * will be repeated after each interval specified by supplicant
14224 * till PNO is disabled.
14225 */
14226 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014227 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014228 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014229 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014230 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
14231
14232 tempInterval = (request->interval)/1000;
14233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14234 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
14235 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014236 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014237 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014238 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014239 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014240 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014241 tempInterval *= 2;
14242 }
14243 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014244 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014245
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014246 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014247
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014248 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014249 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
14250 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014251 pAdapter->pno_req_status = 0;
14252
Nirav Shah80830bf2013-12-31 16:35:12 +053014253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14254 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014255 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
14256 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053014257
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014258 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014259 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014260 hdd_cfg80211_sched_scan_done_callback, pAdapter);
14261 if (eHAL_STATUS_SUCCESS != status)
14262 {
14263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014264 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014265 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014266 goto error;
14267 }
14268
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014269 ret = wait_for_completion_timeout(
14270 &pAdapter->pno_comp_var,
14271 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
14272 if (0 >= ret)
14273 {
14274 // Did not receive the response for PNO enable in time.
14275 // Assuming the PNO enable was success.
14276 // Returning error from here, because we timeout, results
14277 // in side effect of Wifi (Wifi Setting) not to work.
14278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14279 FL("Timed out waiting for PNO to be Enabled"));
14280 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014281 }
14282
14283 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053014284 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014285
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014286error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014287 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14288 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053014289 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014290 if (pnoRequest.aNetworks)
14291 vos_mem_free(pnoRequest.aNetworks);
14292 if (pnoRequest.p24GProbeTemplate)
14293 vos_mem_free(pnoRequest.p24GProbeTemplate);
14294 if (pnoRequest.p5GProbeTemplate)
14295 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014296
14297 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014298 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014299}
14300
14301/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014302 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
14303 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014304 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014305static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
14306 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14307{
14308 int ret;
14309
14310 vos_ssr_protect(__func__);
14311 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
14312 vos_ssr_unprotect(__func__);
14313
14314 return ret;
14315}
14316
14317/*
14318 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
14319 * Function to disable PNO
14320 */
14321static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014322 struct net_device *dev)
14323{
14324 eHalStatus status = eHAL_STATUS_FAILURE;
14325 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14326 hdd_context_t *pHddCtx;
14327 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014328 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014329 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014330
14331 ENTER();
14332
14333 if (NULL == pAdapter)
14334 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014336 "%s: HDD adapter is Null", __func__);
14337 return -ENODEV;
14338 }
14339
14340 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014341
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014342 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014343 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014345 "%s: HDD context is Null", __func__);
14346 return -ENODEV;
14347 }
14348
14349 /* The return 0 is intentional when isLogpInProgress and
14350 * isLoadUnloadInProgress. We did observe a crash due to a return of
14351 * failure in sched_scan_stop , especially for a case where the unload
14352 * of the happens at the same time. The function __cfg80211_stop_sched_scan
14353 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
14354 * success. If it returns a failure , then its next invocation due to the
14355 * clean up of the second interface will have the dev pointer corresponding
14356 * to the first one leading to a crash.
14357 */
14358 if (pHddCtx->isLogpInProgress)
14359 {
14360 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14361 "%s: LOGP in Progress. Ignore!!!", __func__);
14362 return ret;
14363 }
14364
Mihir Shete18156292014-03-11 15:38:30 +053014365 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014366 {
14367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14368 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14369 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014370 }
14371
14372 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14373 if (NULL == hHal)
14374 {
14375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14376 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014377 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014378 }
14379
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014380 pnoRequest.enable = 0; /* Disable PNO */
14381 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014382
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014383 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014384 pAdapter->sessionId,
14385 NULL, pAdapter);
14386 if (eHAL_STATUS_SUCCESS != status)
14387 {
14388 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14389 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014390 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014391 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014392 }
c_hpothu37f21312014-04-09 21:49:54 +053014393 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014394
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014395error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014396 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014397 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014398
14399 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014400 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014401}
14402
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014403/*
14404 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
14405 * NL interface to disable PNO
14406 */
14407static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
14408 struct net_device *dev)
14409{
14410 int ret;
14411
14412 vos_ssr_protect(__func__);
14413 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
14414 vos_ssr_unprotect(__func__);
14415
14416 return ret;
14417}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014418#endif /*FEATURE_WLAN_SCAN_PNO*/
14419
14420
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014421#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014422#if TDLS_MGMT_VERSION2
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014423static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014424 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014425 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
14426#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014427static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014428 u8 *peer, u8 action_code, u8 dialog_token,
14429 u16 status_code, const u8 *buf, size_t len)
14430#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014431{
14432
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014433 hdd_adapter_t *pAdapter;
14434 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014435 u8 peerMac[6];
14436 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070014437 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080014438 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070014439 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014440 int ret;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014441#if !(TDLS_MGMT_VERSION2)
14442 u32 peer_capability = 0;
14443#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014444 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014445
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014446 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14447 if (NULL == pAdapter)
14448 {
14449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14450 "%s: Adapter is NULL",__func__);
14451 return -EINVAL;
14452 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014453 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14454 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
14455 pAdapter->sessionId, action_code));
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014456 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014457 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014458 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014460 "Invalid arguments");
14461 return -EINVAL;
14462 }
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014463 if (pHddCtx->isLogpInProgress)
14464 {
14465 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14466 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053014467 wlan_hdd_tdls_set_link_status(pAdapter,
14468 peer,
14469 eTDLS_LINK_IDLE,
14470 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014471 return -EBUSY;
14472 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014473 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
14474 {
14475 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14476 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14477 return -EAGAIN;
14478 }
Hoonki Lee27511902013-03-14 18:19:06 -070014479 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014480 {
Hoonki Lee27511902013-03-14 18:19:06 -070014481 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
14482 "%s: TDLS mode is disabled OR not enabled in FW."
14483 MAC_ADDRESS_STR " action %d declined.",
14484 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014485 return -ENOTSUPP;
14486 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014487
Hoonki Lee27511902013-03-14 18:19:06 -070014488 /* other than teardown frame, other mgmt frames are not sent if disabled */
14489 if (SIR_MAC_TDLS_TEARDOWN != action_code)
14490 {
14491 /* if tdls_mode is disabled to respond to peer's request */
14492 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
14493 {
14494 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
14495 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014496 " TDLS mode is disabled. action %d declined.",
14497 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070014498
14499 return -ENOTSUPP;
14500 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014501
14502 if (vos_max_concurrent_connections_reached())
14503 {
14504 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14505 return -EINVAL;
14506 }
Hoonki Lee27511902013-03-14 18:19:06 -070014507 }
14508
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014509 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
14510 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014511 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014512 {
14513 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014514 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014515 " TDLS setup is ongoing. action %d declined.",
14516 __func__, MAC_ADDR_ARRAY(peer), action_code);
14517 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014518 }
14519 }
14520
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014521 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
14522 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080014523 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014524 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14525 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014526 {
14527 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
14528 we return error code at 'add_station()'. Hence we have this
14529 check again in addtion to add_station().
14530 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014531 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014532 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14534 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014535 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
14536 __func__, MAC_ADDR_ARRAY(peer), action_code,
14537 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053014538 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080014539 }
14540 else
14541 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014542 /* maximum reached. tweak to send error code to peer and return
14543 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014544 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14546 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014547 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
14548 __func__, MAC_ADDR_ARRAY(peer), status_code,
14549 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070014550 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014551 /* fall through to send setup resp with failure status
14552 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014553 }
14554 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014555 else
14556 {
14557 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014558 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014559 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014560 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014562 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
14563 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014564 return -EPERM;
14565 }
14566 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014567 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014568 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014569
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014570#ifdef WLAN_FEATURE_TDLS_DEBUG
14571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014572 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014573 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
14574 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014575#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014576
Hoonki Leea34dd892013-02-05 22:56:02 -080014577 /*Except teardown responder will not be used so just make 0*/
14578 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014579 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080014580 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014581
14582 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014583 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014584
14585 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
14586 responder = pTdlsPeer->is_responder;
14587 else
Hoonki Leea34dd892013-02-05 22:56:02 -080014588 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014589 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014590 "%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 -070014591 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
14592 dialog_token, status_code, len);
14593 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080014594 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014595 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014596
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014597 /* For explicit trigger of DIS_REQ come out of BMPS for
14598 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070014599 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014600 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
14601 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070014602 {
14603 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
14604 {
14605 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014606 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070014607 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
14608 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014609 if (SIR_MAC_TDLS_DIS_REQ != action_code)
14610 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070014611 }
14612
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014613 /* make sure doesn't call send_mgmt() while it is pending */
14614 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
14615 {
14616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014617 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014618 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014619 ret = -EBUSY;
14620 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014621 }
14622
14623 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014624 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
14625
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014626 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053014627 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014628
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014629 if (VOS_STATUS_SUCCESS != status)
14630 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14632 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014633 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014634 ret = -EINVAL;
14635 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014636 }
14637
Hoonki Leed37cbb32013-04-20 00:31:14 -070014638 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
14639 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
14640
14641 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014642 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070014643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014644 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070014645 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014646 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080014647
14648 if (pHddCtx->isLogpInProgress)
14649 {
14650 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14651 "%s: LOGP in Progress. Ignore!!!", __func__);
14652 return -EAGAIN;
14653 }
14654
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014655 ret = -EINVAL;
14656 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014657 }
14658
Gopichand Nakkala05922802013-03-14 12:23:19 -070014659 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070014660 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014661 ret = max_sta_failed;
14662 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070014663 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014664
Hoonki Leea34dd892013-02-05 22:56:02 -080014665 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
14666 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014667 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080014668 }
14669 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
14670 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014671 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080014672 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014673
14674 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014675
14676tx_failed:
14677 /* add_station will be called before sending TDLS_SETUP_REQ and
14678 * TDLS_SETUP_RSP and as part of add_station driver will enable
14679 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
14680 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
14681 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
14682 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
14683 */
14684
14685 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
14686 (SIR_MAC_TDLS_SETUP_RSP == action_code))
14687 wlan_hdd_tdls_check_bmps(pAdapter);
14688 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014689}
14690
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014691#if TDLS_MGMT_VERSION2
14692static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14693 u8 *peer, u8 action_code, u8 dialog_token,
14694 u16 status_code, u32 peer_capability,
14695 const u8 *buf, size_t len)
14696#else
14697static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14698 u8 *peer, u8 action_code, u8 dialog_token,
14699 u16 status_code, const u8 *buf, size_t len)
14700#endif
14701{
14702 int ret;
14703
14704 vos_ssr_protect(__func__);
14705#if TDLS_MGMT_VERSION2
14706 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14707 status_code, peer_capability, buf, len);
14708#else
14709 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14710 status_code, buf, len);
14711#endif
14712 vos_ssr_unprotect(__func__);
14713
14714 return ret;
14715}
Atul Mittal115287b2014-07-08 13:26:33 +053014716
14717int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
14718 u8 *peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014719 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053014720 cfg80211_exttdls_callback callback)
14721{
14722
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014723 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053014724 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014725 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053014726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14727 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
14728 __func__, MAC_ADDR_ARRAY(peer));
14729
14730 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14731 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14732
14733 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14734 " %s TDLS External control and Implicit Trigger not enabled ",
14735 __func__);
14736 return -ENOTSUPP;
14737 }
14738
14739 /* To cater the requirement of establishing the TDLS link
14740 * irrespective of the data traffic , get an entry of TDLS peer.
14741 */
14742 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
14743 if (pTdlsPeer == NULL) {
14744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14745 "%s: peer " MAC_ADDRESS_STR " not existing",
14746 __func__, MAC_ADDR_ARRAY(peer));
14747 return -EINVAL;
14748 }
14749
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053014750 /* check FW TDLS Off Channel capability */
14751 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
14752 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014753 {
14754 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
14755 pTdlsPeer->peerParams.global_operating_class =
14756 tdls_peer_params->global_operating_class;
14757 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
14758 pTdlsPeer->peerParams.min_bandwidth_kbps =
14759 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014760 /* check configured channel is valid, non dfs and
14761 * not current operating channel */
14762 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
14763 tdls_peer_params->channel)) &&
14764 (pHddStaCtx) &&
14765 (tdls_peer_params->channel !=
14766 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014767 {
14768 pTdlsPeer->isOffChannelConfigured = TRUE;
14769 }
14770 else
14771 {
14772 pTdlsPeer->isOffChannelConfigured = FALSE;
14773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14774 "%s: Configured Tdls Off Channel is not valid", __func__);
14775
14776 }
14777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014778 "%s: tdls_off_channel %d isOffChannelConfigured %d "
14779 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014780 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014781 pTdlsPeer->isOffChannelConfigured,
14782 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014783 }
14784 else
14785 {
14786 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053014787 "%s: TDLS off channel FW capability %d or "
14788 "Invalid TDLS Peer Params", __func__,
14789 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014790 }
14791
Atul Mittal115287b2014-07-08 13:26:33 +053014792 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
14793
14794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14795 " %s TDLS Add Force Peer Failed",
14796 __func__);
14797 return -EINVAL;
14798 }
14799 /*EXT TDLS*/
14800
14801 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
14802 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14803 " %s TDLS set callback Failed",
14804 __func__);
14805 return -EINVAL;
14806 }
14807
14808 return(0);
14809
14810}
14811
14812int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
14813{
14814
14815 hddTdlsPeer_t *pTdlsPeer;
14816 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14817 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14818 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
14819 __func__, MAC_ADDR_ARRAY(peer));
14820
14821 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14822 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14823
14824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14825 " %s TDLS External control and Implicit Trigger not enabled ",
14826 __func__);
14827 return -ENOTSUPP;
14828 }
14829
14830
14831 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
14832
14833 if ( NULL == pTdlsPeer ) {
14834 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
14835 " peer not exsting",
14836 __func__, MAC_ADDR_ARRAY(peer));
14837 return -EINVAL;
14838 }
14839 else {
14840 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
14841 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014842 /* if channel switch is configured, reset
14843 the channel for this peer */
14844 if (TRUE == pTdlsPeer->isOffChannelConfigured)
14845 {
14846 pTdlsPeer->peerParams.channel = 0;
14847 pTdlsPeer->isOffChannelConfigured = FALSE;
14848 }
Atul Mittal115287b2014-07-08 13:26:33 +053014849 }
14850
14851 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
14852 return -EINVAL;
14853
14854 /*EXT TDLS*/
14855
14856 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
14857
14858 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14859 " %s TDLS set callback Failed",
14860 __func__);
14861 return -EINVAL;
14862 }
14863 return(0);
14864
14865}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014866static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014867 u8 *peer, enum nl80211_tdls_operation oper)
14868{
14869 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14870 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014871 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014872 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014873
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014874 ENTER();
14875
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014876 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14877 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
14878 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014879 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014880 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014881 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014882 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014883 return -EINVAL;
14884 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014885
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014886 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014887 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014888 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014889 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014890 }
14891
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014892
14893 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014894 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014895 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014897 "TDLS Disabled in INI OR not enabled in FW. "
14898 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014899 return -ENOTSUPP;
14900 }
14901
14902 switch (oper) {
14903 case NL80211_TDLS_ENABLE_LINK:
14904 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014905 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014906 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014907 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053014908 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014909 tANI_U16 numCurrTdlsPeers = 0;
14910 hddTdlsPeer_t *connPeer = NULL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014911
Sunil Dutt41de4e22013-11-14 18:09:02 +053014912 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053014913 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053014914 if ( NULL == pTdlsPeer ) {
14915 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
14916 " (oper %d) not exsting. ignored",
14917 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
14918 return -EINVAL;
14919 }
14920
14921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14922 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
14923 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
14924 "NL80211_TDLS_ENABLE_LINK");
14925
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070014926 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
14927 {
14928 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
14929 MAC_ADDRESS_STR " failed",
14930 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
14931 return -EINVAL;
14932 }
14933
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014934 /* TDLS Off Channel, Disable tdls channel switch,
14935 when there are more than one tdls link */
14936 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14937 if (numCurrTdlsPeers == 1)
14938 {
14939 /* get connected peer and send disable tdls off chan */
14940 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
14941 if (connPeer && (connPeer->isOffChannelConfigured == TRUE))
14942 {
14943 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14944 "%s: More then one peer connected, Disable "
14945 "TDLS channel switch", __func__);
14946
14947 sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
14948 pAdapter->sessionId,
14949 connPeer->peerMac,
14950 connPeer->peerParams.channel,
14951 TDLS_OFF_CHANNEL_BW_OFFSET,
14952 TDLS_CHANNEL_SWITCH_DISABLE);
14953 }
14954 else
14955 {
14956 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14957 "%s: No TDLS Connected Peer or "
14958 "isOffChannelConfigured %d",
14959 __func__,
14960 (connPeer ? connPeer->isOffChannelConfigured : -1));
14961 }
14962 }
14963
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014964 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014965 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014966 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053014967
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014968 if (0 != wlan_hdd_tdls_get_link_establish_params(
14969 pAdapter, peer,&tdlsLinkEstablishParams)) {
14970 return -EINVAL;
14971 }
14972 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014973
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014974 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
14975 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
14976 /* Send TDLS peer UAPSD capabilities to the firmware and
14977 * register with the TL on after the response for this operation
14978 * is received .
14979 */
14980 ret = wait_for_completion_interruptible_timeout(
14981 &pAdapter->tdls_link_establish_req_comp,
14982 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
14983 if (ret <= 0)
14984 {
14985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14986 "%s: Link Establish Request Faled Status %ld",
14987 __func__, ret);
14988 return -EINVAL;
14989 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014990 }
Atul Mittal115287b2014-07-08 13:26:33 +053014991 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
14992 eTDLS_LINK_CONNECTED,
14993 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053014994 staDesc.ucSTAId = pTdlsPeer->staId;
14995 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
14996 WLANTL_UpdateTdlsSTAClient(pHddCtx->pvosContext,
14997 &staDesc);
14998
14999
Gopichand Nakkala471708b2013-06-04 20:03:01 +053015000 /* Mark TDLS client Authenticated .*/
15001 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
15002 pTdlsPeer->staId,
15003 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015004 if (VOS_STATUS_SUCCESS == status)
15005 {
Hoonki Lee14621352013-04-16 17:51:19 -070015006 if (pTdlsPeer->is_responder == 0)
15007 {
15008 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
15009
15010 wlan_hdd_tdls_timer_restart(pAdapter,
15011 &pTdlsPeer->initiatorWaitTimeoutTimer,
15012 WAIT_TIME_TDLS_INITIATOR);
15013 /* suspend initiator TX until it receives direct packet from the
15014 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
15015 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15016 &staId, NULL);
15017 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015018 wlan_hdd_tdls_increment_peer_count(pAdapter);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015019
15020 /* TDLS Off Channel, Enable tdls channel switch,
15021 when their is only one tdls link and it supports */
15022 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15023 if ((numCurrTdlsPeers == 1) &&
15024 (TRUE == pTdlsPeer->isOffChannelSupported) &&
15025 (TRUE == pTdlsPeer->isOffChannelConfigured))
15026 {
15027 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15028 "%s: Send TDLS channel switch request for channel %d",
15029 __func__, pTdlsPeer->peerParams.channel);
15030 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
15031 pAdapter->sessionId,
15032 pTdlsPeer->peerMac,
15033 pTdlsPeer->peerParams.channel,
15034 TDLS_OFF_CHANNEL_BW_OFFSET,
15035 TDLS_CHANNEL_SWITCH_ENABLE);
15036 }
15037 else
15038 {
15039 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15040 "%s: TDLS channel switch request not sent"
15041 " numCurrTdlsPeers %d "
15042 "isOffChannelSupported %d "
15043 "isOffChannelConfigured %d",
15044 __func__, numCurrTdlsPeers,
15045 pTdlsPeer->isOffChannelSupported,
15046 pTdlsPeer->isOffChannelConfigured);
15047 }
15048
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015049 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015050 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015051
15052 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015053 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
15054 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015055 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015056 int ac;
15057 uint8 ucAc[4] = { WLANTL_AC_VO,
15058 WLANTL_AC_VI,
15059 WLANTL_AC_BK,
15060 WLANTL_AC_BE };
15061 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
15062 for(ac=0; ac < 4; ac++)
15063 {
15064 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15065 pTdlsPeer->staId, ucAc[ac],
15066 tlTid[ac], tlTid[ac], 0, 0,
15067 WLANTL_BI_DIR );
15068 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015069 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015070 }
15071
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015072 }
15073 break;
15074 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080015075 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015076 tANI_U16 numCurrTdlsPeers = 0;
15077 hddTdlsPeer_t *connPeer = NULL;
15078
Sunil Dutt41de4e22013-11-14 18:09:02 +053015079 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15080
15081 if ( NULL == pTdlsPeer ) {
15082 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15083 " (oper %d) not exsting. ignored",
15084 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15085 return -EINVAL;
15086 }
15087
15088 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15089 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15090 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15091 "NL80211_TDLS_DISABLE_LINK");
15092
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015093 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080015094 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015095 long status;
15096
Atul Mittal271a7652014-09-12 13:18:22 +053015097
15098 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15099 eTDLS_LINK_TEARING,
15100 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
15101 eTDLS_LINK_UNSPECIFIED:
15102 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015103 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
15104
Lee Hoonkic1262f22013-01-24 21:59:00 -080015105 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
15106 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015107
15108 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
15109 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053015110 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053015111 eTDLS_LINK_IDLE,
15112 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015113 if (status <= 0)
15114 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015115 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15116 "%s: Del station failed status %ld",
15117 __func__, status);
15118 return -EPERM;
15119 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015120
15121 /* TDLS Off Channel, Enable tdls channel switch,
15122 when their is only one tdls link and it supports */
15123 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15124 if (numCurrTdlsPeers == 1)
15125 {
15126 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
15127 if ((connPeer) &&
15128 (connPeer->isOffChannelSupported == TRUE) &&
15129 (connPeer->isOffChannelConfigured == TRUE))
15130 {
15131 sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
15132 pAdapter->sessionId,
15133 connPeer->peerMac,
15134 connPeer->peerParams.channel,
15135 TDLS_OFF_CHANNEL_BW_OFFSET,
15136 TDLS_CHANNEL_SWITCH_ENABLE);
15137 }
15138 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15139 "%s: TDLS channel switch "
15140 "isOffChannelSupported %d "
15141 "isOffChannelConfigured %d",
15142 __func__,
15143 (connPeer ? connPeer->isOffChannelSupported : -1),
15144 (connPeer ? connPeer->isOffChannelConfigured : -1));
15145 }
15146 else
15147 {
15148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15149 "%s: TDLS channel switch request not sent "
15150 "numCurrTdlsPeers %d ",
15151 __func__, numCurrTdlsPeers);
15152 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015153 }
15154 else
15155 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15157 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080015158 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015159 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015160 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015161 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015162 {
Atul Mittal115287b2014-07-08 13:26:33 +053015163 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015164
Atul Mittal115287b2014-07-08 13:26:33 +053015165 if (0 != status)
15166 {
15167 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15168 "%s: Error in TDLS Teardown", __func__);
15169 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015170 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053015171 break;
15172 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015173 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015174 {
Atul Mittal115287b2014-07-08 13:26:33 +053015175 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
15176 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015177 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053015178 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015179
Atul Mittal115287b2014-07-08 13:26:33 +053015180 if (0 != status)
15181 {
15182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15183 "%s: Error in TDLS Setup", __func__);
15184 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053015185 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053015186 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015187 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015188 case NL80211_TDLS_DISCOVERY_REQ:
15189 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15191 "%s: We don't support in-driver setup/teardown/discovery "
15192 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015193 return -ENOTSUPP;
15194 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15196 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015197 return -ENOTSUPP;
15198 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015199
15200 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015201 return 0;
15202}
Chilam NG571c65a2013-01-19 12:27:36 +053015203
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015204static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
15205 u8 *peer, enum nl80211_tdls_operation oper)
15206{
15207 int ret;
15208
15209 vos_ssr_protect(__func__);
15210 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
15211 vos_ssr_unprotect(__func__);
15212
15213 return ret;
15214}
15215
Chilam NG571c65a2013-01-19 12:27:36 +053015216int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
15217 struct net_device *dev, u8 *peer)
15218{
Arif Hussaina7c8e412013-11-20 11:06:42 -080015219 hddLog(VOS_TRACE_LEVEL_INFO,
15220 "tdls send discover req: "MAC_ADDRESS_STR,
15221 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053015222
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015223#if TDLS_MGMT_VERSION2
15224 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15225 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15226#else
Chilam NG571c65a2013-01-19 12:27:36 +053015227 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15228 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015229#endif
Chilam NG571c65a2013-01-19 12:27:36 +053015230}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015231#endif
15232
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015233#ifdef WLAN_FEATURE_GTK_OFFLOAD
15234/*
15235 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
15236 * Callback rountine called upon receiving response for
15237 * get offload info
15238 */
15239void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
15240 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
15241{
15242
15243 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015244 tANI_U8 tempReplayCounter[8];
15245 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015246
15247 ENTER();
15248
15249 if (NULL == pAdapter)
15250 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053015251 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015252 "%s: HDD adapter is Null", __func__);
15253 return ;
15254 }
15255
15256 if (NULL == pGtkOffloadGetInfoRsp)
15257 {
15258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15259 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
15260 return ;
15261 }
15262
15263 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
15264 {
15265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15266 "%s: wlan Failed to get replay counter value",
15267 __func__);
15268 return ;
15269 }
15270
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015271 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15272 /* Update replay counter */
15273 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
15274 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15275
15276 {
15277 /* changing from little to big endian since supplicant
15278 * works on big endian format
15279 */
15280 int i;
15281 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15282
15283 for (i = 0; i < 8; i++)
15284 {
15285 tempReplayCounter[7-i] = (tANI_U8)p[i];
15286 }
15287 }
15288
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015289 /* Update replay counter to NL */
15290 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015291 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015292}
15293
15294/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015295 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015296 * This function is used to offload GTK rekeying job to the firmware.
15297 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015298int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015299 struct cfg80211_gtk_rekey_data *data)
15300{
15301 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15302 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15303 hdd_station_ctx_t *pHddStaCtx;
15304 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015305 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015306 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015307 eHalStatus status = eHAL_STATUS_FAILURE;
15308
15309 ENTER();
15310
15311 if (NULL == pAdapter)
15312 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015314 "%s: HDD adapter is Null", __func__);
15315 return -ENODEV;
15316 }
15317
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015318 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15319 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
15320 pAdapter->sessionId, pAdapter->device_mode));
15321
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015322 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015323 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015324 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015325 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015326 }
15327
15328 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15329 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15330 if (NULL == hHal)
15331 {
15332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15333 "%s: HAL context is Null!!!", __func__);
15334 return -EAGAIN;
15335 }
15336
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015337 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
15338 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
15339 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
15340 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015341 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015342 {
15343 /* changing from big to little endian since driver
15344 * works on little endian format
15345 */
15346 tANI_U8 *p =
15347 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
15348 int i;
15349
15350 for (i = 0; i < 8; i++)
15351 {
15352 p[7-i] = data->replay_ctr[i];
15353 }
15354 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015355
15356 if (TRUE == pHddCtx->hdd_wlan_suspended)
15357 {
15358 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015359 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
15360 sizeof (tSirGtkOffloadParams));
15361 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015362 pAdapter->sessionId);
15363
15364 if (eHAL_STATUS_SUCCESS != status)
15365 {
15366 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15367 "%s: sme_SetGTKOffload failed, returned %d",
15368 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053015369
15370 /* Need to clear any trace of key value in the memory.
15371 * Thus zero out the memory even though it is local
15372 * variable.
15373 */
15374 vos_mem_zero(&hddGtkOffloadReqParams,
15375 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015376 return status;
15377 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15379 "%s: sme_SetGTKOffload successfull", __func__);
15380 }
15381 else
15382 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15384 "%s: wlan not suspended GTKOffload request is stored",
15385 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015386 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015387
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053015388 /* Need to clear any trace of key value in the memory.
15389 * Thus zero out the memory even though it is local
15390 * variable.
15391 */
15392 vos_mem_zero(&hddGtkOffloadReqParams,
15393 sizeof(hddGtkOffloadReqParams));
15394
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015395 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015396 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015397}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015398
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015399int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
15400 struct cfg80211_gtk_rekey_data *data)
15401{
15402 int ret;
15403
15404 vos_ssr_protect(__func__);
15405 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
15406 vos_ssr_unprotect(__func__);
15407
15408 return ret;
15409}
15410#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015411/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015412 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015413 * This function is used to set access control policy
15414 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015415static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
15416 struct net_device *dev,
15417 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015418{
15419 int i;
15420 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15421 hdd_hostapd_state_t *pHostapdState;
15422 tsap_Config_t *pConfig;
15423 v_CONTEXT_t pVosContext = NULL;
15424 hdd_context_t *pHddCtx;
15425 int status;
15426
15427 ENTER();
15428
15429 if (NULL == pAdapter)
15430 {
15431 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15432 "%s: HDD adapter is Null", __func__);
15433 return -ENODEV;
15434 }
15435
15436 if (NULL == params)
15437 {
15438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15439 "%s: params is Null", __func__);
15440 return -EINVAL;
15441 }
15442
15443 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15444 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015445 if (0 != status)
15446 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015447 return status;
15448 }
15449
15450 pVosContext = pHddCtx->pvosContext;
15451 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
15452
15453 if (NULL == pHostapdState)
15454 {
15455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15456 "%s: pHostapdState is Null", __func__);
15457 return -EINVAL;
15458 }
15459
15460 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
15461 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
15462
15463 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
15464 {
15465 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
15466
15467 /* default value */
15468 pConfig->num_accept_mac = 0;
15469 pConfig->num_deny_mac = 0;
15470
15471 /**
15472 * access control policy
15473 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
15474 * listed in hostapd.deny file.
15475 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
15476 * listed in hostapd.accept file.
15477 */
15478 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
15479 {
15480 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
15481 }
15482 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
15483 {
15484 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
15485 }
15486 else
15487 {
15488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15489 "%s:Acl Policy : %d is not supported",
15490 __func__, params->acl_policy);
15491 return -ENOTSUPP;
15492 }
15493
15494 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
15495 {
15496 pConfig->num_accept_mac = params->n_acl_entries;
15497 for (i = 0; i < params->n_acl_entries; i++)
15498 {
15499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15500 "** Add ACL MAC entry %i in WhiletList :"
15501 MAC_ADDRESS_STR, i,
15502 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
15503
15504 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
15505 sizeof(qcmacaddr));
15506 }
15507 }
15508 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
15509 {
15510 pConfig->num_deny_mac = params->n_acl_entries;
15511 for (i = 0; i < params->n_acl_entries; i++)
15512 {
15513 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15514 "** Add ACL MAC entry %i in BlackList :"
15515 MAC_ADDRESS_STR, i,
15516 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
15517
15518 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
15519 sizeof(qcmacaddr));
15520 }
15521 }
15522
15523 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
15524 {
15525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15526 "%s: SAP Set Mac Acl fail", __func__);
15527 return -EINVAL;
15528 }
15529 }
15530 else
15531 {
15532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015533 "%s: Invalid device_mode = %s (%d)",
15534 __func__, hdd_device_modetoString(pAdapter->device_mode),
15535 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015536 return -EINVAL;
15537 }
15538
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015539 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015540 return 0;
15541}
15542
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015543static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
15544 struct net_device *dev,
15545 const struct cfg80211_acl_data *params)
15546{
15547 int ret;
15548 vos_ssr_protect(__func__);
15549 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
15550 vos_ssr_unprotect(__func__);
15551
15552 return ret;
15553}
15554
Leo Chang9056f462013-08-01 19:21:11 -070015555#ifdef WLAN_NL80211_TESTMODE
15556#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070015557void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070015558(
15559 void *pAdapter,
15560 void *indCont
15561)
15562{
Leo Changd9df8aa2013-09-26 13:32:26 -070015563 tSirLPHBInd *lphbInd;
15564 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053015565 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070015566
15567 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070015568 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070015569
c_hpothu73f35e62014-04-18 13:40:08 +053015570 if (pAdapter == NULL)
15571 {
15572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15573 "%s: pAdapter is NULL\n",__func__);
15574 return;
15575 }
15576
Leo Chang9056f462013-08-01 19:21:11 -070015577 if (NULL == indCont)
15578 {
15579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070015580 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070015581 return;
15582 }
15583
c_hpothu73f35e62014-04-18 13:40:08 +053015584 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070015585 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070015586 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053015587 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070015588 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070015589 GFP_ATOMIC);
15590 if (!skb)
15591 {
15592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15593 "LPHB timeout, NL buffer alloc fail");
15594 return;
15595 }
15596
Leo Changac3ba772013-10-07 09:47:04 -070015597 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070015598 {
15599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15600 "WLAN_HDD_TM_ATTR_CMD put fail");
15601 goto nla_put_failure;
15602 }
Leo Changac3ba772013-10-07 09:47:04 -070015603 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070015604 {
15605 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15606 "WLAN_HDD_TM_ATTR_TYPE put fail");
15607 goto nla_put_failure;
15608 }
Leo Changac3ba772013-10-07 09:47:04 -070015609 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070015610 sizeof(tSirLPHBInd), lphbInd))
15611 {
15612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15613 "WLAN_HDD_TM_ATTR_DATA put fail");
15614 goto nla_put_failure;
15615 }
Leo Chang9056f462013-08-01 19:21:11 -070015616 cfg80211_testmode_event(skb, GFP_ATOMIC);
15617 return;
15618
15619nla_put_failure:
15620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15621 "NLA Put fail");
15622 kfree_skb(skb);
15623
15624 return;
15625}
15626#endif /* FEATURE_WLAN_LPHB */
15627
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015628static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070015629{
15630 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
15631 int err = 0;
15632#ifdef FEATURE_WLAN_LPHB
15633 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070015634 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015635
15636 ENTER();
15637
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015638 err = wlan_hdd_validate_context(pHddCtx);
15639 if (0 != err)
15640 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015641 return err;
15642 }
Leo Chang9056f462013-08-01 19:21:11 -070015643#endif /* FEATURE_WLAN_LPHB */
15644
15645 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
15646 if (err)
15647 {
15648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15649 "%s Testmode INV ATTR", __func__);
15650 return err;
15651 }
15652
15653 if (!tb[WLAN_HDD_TM_ATTR_CMD])
15654 {
15655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15656 "%s Testmode INV CMD", __func__);
15657 return -EINVAL;
15658 }
15659
15660 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
15661 {
15662#ifdef FEATURE_WLAN_LPHB
15663 /* Low Power Heartbeat configuration request */
15664 case WLAN_HDD_TM_CMD_WLAN_HB:
15665 {
15666 int buf_len;
15667 void *buf;
15668 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080015669 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070015670
15671 if (!tb[WLAN_HDD_TM_ATTR_DATA])
15672 {
15673 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15674 "%s Testmode INV DATA", __func__);
15675 return -EINVAL;
15676 }
15677
15678 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
15679 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080015680
15681 hb_params_temp =(tSirLPHBReq *)buf;
15682 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
15683 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
15684 return -EINVAL;
15685
Leo Chang9056f462013-08-01 19:21:11 -070015686 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
15687 if (NULL == hb_params)
15688 {
15689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15690 "%s Request Buffer Alloc Fail", __func__);
15691 return -EINVAL;
15692 }
15693
15694 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070015695 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
15696 hb_params,
15697 wlan_hdd_cfg80211_lphb_ind_handler);
15698 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070015699 {
Leo Changd9df8aa2013-09-26 13:32:26 -070015700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15701 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070015702 vos_mem_free(hb_params);
15703 }
Leo Chang9056f462013-08-01 19:21:11 -070015704 return 0;
15705 }
15706#endif /* FEATURE_WLAN_LPHB */
15707 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15709 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070015710 return -EOPNOTSUPP;
15711 }
15712
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015713 EXIT();
15714 return err;
Leo Chang9056f462013-08-01 19:21:11 -070015715}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015716
15717static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
15718{
15719 int ret;
15720
15721 vos_ssr_protect(__func__);
15722 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
15723 vos_ssr_unprotect(__func__);
15724
15725 return ret;
15726}
Leo Chang9056f462013-08-01 19:21:11 -070015727#endif /* CONFIG_NL80211_TESTMODE */
15728
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015729static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015730 struct net_device *dev,
15731 int idx, struct survey_info *survey)
15732{
15733 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15734 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053015735 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015736 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053015737 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015738 v_S7_t snr,rssi;
15739 int status, i, j, filled = 0;
15740
15741 ENTER();
15742
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015743 if (NULL == pAdapter)
15744 {
15745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15746 "%s: HDD adapter is Null", __func__);
15747 return -ENODEV;
15748 }
15749
15750 if (NULL == wiphy)
15751 {
15752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15753 "%s: wiphy is Null", __func__);
15754 return -ENODEV;
15755 }
15756
15757 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15758 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015759 if (0 != status)
15760 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015761 return status;
15762 }
15763
Mihir Sheted9072e02013-08-21 17:02:29 +053015764 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15765
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015766 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053015767 0 != pAdapter->survey_idx ||
15768 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015769 {
15770 /* The survey dump ops when implemented completely is expected to
15771 * return a survey of all channels and the ops is called by the
15772 * kernel with incremental values of the argument 'idx' till it
15773 * returns -ENONET. But we can only support the survey for the
15774 * operating channel for now. survey_idx is used to track
15775 * that the ops is called only once and then return -ENONET for
15776 * the next iteration
15777 */
15778 pAdapter->survey_idx = 0;
15779 return -ENONET;
15780 }
15781
15782 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15783
15784 wlan_hdd_get_snr(pAdapter, &snr);
15785 wlan_hdd_get_rssi(pAdapter, &rssi);
15786
15787 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
15788 hdd_wlan_get_freq(channel, &freq);
15789
15790
15791 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
15792 {
15793 if (NULL == wiphy->bands[i])
15794 {
15795 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
15796 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
15797 continue;
15798 }
15799
15800 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
15801 {
15802 struct ieee80211_supported_band *band = wiphy->bands[i];
15803
15804 if (band->channels[j].center_freq == (v_U16_t)freq)
15805 {
15806 survey->channel = &band->channels[j];
15807 /* The Rx BDs contain SNR values in dB for the received frames
15808 * while the supplicant expects noise. So we calculate and
15809 * return the value of noise (dBm)
15810 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
15811 */
15812 survey->noise = rssi - snr;
15813 survey->filled = SURVEY_INFO_NOISE_DBM;
15814 filled = 1;
15815 }
15816 }
15817 }
15818
15819 if (filled)
15820 pAdapter->survey_idx = 1;
15821 else
15822 {
15823 pAdapter->survey_idx = 0;
15824 return -ENONET;
15825 }
15826
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015827 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015828 return 0;
15829}
15830
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015831static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
15832 struct net_device *dev,
15833 int idx, struct survey_info *survey)
15834{
15835 int ret;
15836
15837 vos_ssr_protect(__func__);
15838 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
15839 vos_ssr_unprotect(__func__);
15840
15841 return ret;
15842}
15843
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015844/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015845 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015846 * this is called when cfg80211 driver resume
15847 * driver updates latest sched_scan scan result(if any) to cfg80211 database
15848 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015849int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015850{
15851 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15852 hdd_adapter_t *pAdapter;
15853 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15854 VOS_STATUS status = VOS_STATUS_SUCCESS;
15855
15856 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015857
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015858 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015859 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015860 return 0;
15861 }
15862
15863 spin_lock(&pHddCtx->schedScan_lock);
15864 pHddCtx->isWiphySuspended = FALSE;
15865 if (TRUE != pHddCtx->isSchedScanUpdatePending)
15866 {
15867 spin_unlock(&pHddCtx->schedScan_lock);
15868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15869 "%s: Return resume is not due to PNO indication", __func__);
15870 return 0;
15871 }
15872 // Reset flag to avoid updatating cfg80211 data old results again
15873 pHddCtx->isSchedScanUpdatePending = FALSE;
15874 spin_unlock(&pHddCtx->schedScan_lock);
15875
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015876
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015877 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15878
15879 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15880 {
15881 pAdapter = pAdapterNode->pAdapter;
15882 if ( (NULL != pAdapter) &&
15883 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
15884 {
15885 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015886 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15888 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015889 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015890 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015891 {
15892 /* Acquire wakelock to handle the case where APP's tries to
15893 * suspend immediately after updating the scan results. Whis
15894 * results in app's is in suspended state and not able to
15895 * process the connect request to AP
15896 */
15897 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015898 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015899 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015900
15901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15902 "%s : cfg80211 scan result database updated", __func__);
15903
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015904 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015905 return 0;
15906
15907 }
15908 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15909 pAdapterNode = pNext;
15910 }
15911
15912 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15913 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015914 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015915 return 0;
15916}
15917
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015918int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
15919{
15920 int ret;
15921
15922 vos_ssr_protect(__func__);
15923 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
15924 vos_ssr_unprotect(__func__);
15925
15926 return ret;
15927}
15928
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015929/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015930 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015931 * this is called when cfg80211 driver suspends
15932 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015933int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015934 struct cfg80211_wowlan *wow)
15935{
15936 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015937 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015938
15939 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015940
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015941 ret = wlan_hdd_validate_context(pHddCtx);
15942 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015943 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015944 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015945 }
15946
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015947
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015948 pHddCtx->isWiphySuspended = TRUE;
15949
15950 EXIT();
15951
15952 return 0;
15953}
15954
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015955int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
15956 struct cfg80211_wowlan *wow)
15957{
15958 int ret;
15959
15960 vos_ssr_protect(__func__);
15961 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
15962 vos_ssr_unprotect(__func__);
15963
15964 return ret;
15965}
Jeff Johnson295189b2012-06-20 16:38:30 -070015966/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015967static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070015968{
15969 .add_virtual_intf = wlan_hdd_add_virtual_intf,
15970 .del_virtual_intf = wlan_hdd_del_virtual_intf,
15971 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
15972 .change_station = wlan_hdd_change_station,
15973#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
15974 .add_beacon = wlan_hdd_cfg80211_add_beacon,
15975 .del_beacon = wlan_hdd_cfg80211_del_beacon,
15976 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015977#else
15978 .start_ap = wlan_hdd_cfg80211_start_ap,
15979 .change_beacon = wlan_hdd_cfg80211_change_beacon,
15980 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070015981#endif
15982 .change_bss = wlan_hdd_cfg80211_change_bss,
15983 .add_key = wlan_hdd_cfg80211_add_key,
15984 .get_key = wlan_hdd_cfg80211_get_key,
15985 .del_key = wlan_hdd_cfg80211_del_key,
15986 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015987#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070015988 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015989#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015990 .scan = wlan_hdd_cfg80211_scan,
15991 .connect = wlan_hdd_cfg80211_connect,
15992 .disconnect = wlan_hdd_cfg80211_disconnect,
15993 .join_ibss = wlan_hdd_cfg80211_join_ibss,
15994 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
15995 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
15996 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
15997 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070015998 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
15999 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053016000 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070016001#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16002 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
16003 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
16004 .set_txq_params = wlan_hdd_set_txq_params,
16005#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016006 .get_station = wlan_hdd_cfg80211_get_station,
16007 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
16008 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016009 .add_station = wlan_hdd_cfg80211_add_station,
16010#ifdef FEATURE_WLAN_LFR
16011 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
16012 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
16013 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
16014#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016015#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
16016 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
16017#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016018#ifdef FEATURE_WLAN_TDLS
16019 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
16020 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
16021#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016022#ifdef WLAN_FEATURE_GTK_OFFLOAD
16023 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
16024#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016025#ifdef FEATURE_WLAN_SCAN_PNO
16026 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
16027 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
16028#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016029 .resume = wlan_hdd_cfg80211_resume_wlan,
16030 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016031 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070016032#ifdef WLAN_NL80211_TESTMODE
16033 .testmode_cmd = wlan_hdd_cfg80211_testmode,
16034#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016035 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070016036};
16037