blob: 642b18e7971ef5caeab35f6d36bb16a16b7416ce [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
1092 status = wlan_hdd_validate_context(pHddCtx);
1093 if (0 != status)
1094 {
1095 hddLog(VOS_TRACE_LEVEL_ERROR,
1096 FL("HDD context is not valid") );
1097 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);
1242}
1243
1244/*
1245 * hdd_link_layer_process_iface_stats () - This function is called after
1246 * receiving Link Layer Interface statistics from FW.This function converts
1247 * the firmware data to the NL data and sends the same to the kernel/upper
1248 * layers.
1249 */
1250static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1251 v_VOID_t *pData)
1252{
1253 tpSirWifiIfaceStat pWifiIfaceStat;
1254 struct sk_buff *vendor_event;
1255 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1256 int status;
1257
1258 status = wlan_hdd_validate_context(pHddCtx);
1259 if (0 != status)
1260 {
1261 hddLog(VOS_TRACE_LEVEL_ERROR,
1262 FL("HDD context is not valid") );
1263 return;
1264 }
1265 /*
1266 * Allocate a size of 4096 for the interface stats comprising
1267 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1268 * assuming that all these fit with in the limit.Please take
1269 * a call on the limit based on the data requirements on
1270 * interface statistics.
1271 */
1272 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1273 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1274 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1275 GFP_KERNEL);
1276 if (!vendor_event)
1277 {
1278 hddLog(VOS_TRACE_LEVEL_ERROR,
1279 FL("cfg80211_vendor_event_alloc failed") );
1280 return;
1281 }
1282
1283 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1284
Dino Mycle3b9536d2014-07-09 22:05:24 +05301285
1286 if (FALSE == hdd_get_interface_info( pAdapter,
1287 &pWifiIfaceStat->info))
1288 {
1289 hddLog(VOS_TRACE_LEVEL_ERROR,
1290 FL("hdd_get_interface_info get fail") );
1291 kfree_skb(vendor_event);
1292 return;
1293 }
1294
1295 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1296 vendor_event))
1297 {
1298 hddLog(VOS_TRACE_LEVEL_ERROR,
1299 FL("put_wifi_iface_stats fail") );
1300 kfree_skb(vendor_event);
1301 return;
1302 }
1303
Sunil Duttc69bccb2014-05-26 21:30:20 +05301304 hddLog(VOS_TRACE_LEVEL_INFO,
1305 "WMI_LINK_STATS_IFACE Data");
1306
1307 hddLog(VOS_TRACE_LEVEL_INFO,
1308 "LL_STATS_IFACE: "
1309 " Mode %u "
1310 " MAC %pM "
1311 " State %u "
1312 " Roaming %u "
1313 " capabilities 0x%x "
1314 " SSID %s "
1315 " BSSID %pM",
1316 pWifiIfaceStat->info.mode,
1317 pWifiIfaceStat->info.macAddr,
1318 pWifiIfaceStat->info.state,
1319 pWifiIfaceStat->info.roaming,
1320 pWifiIfaceStat->info.capabilities,
1321 pWifiIfaceStat->info.ssid,
1322 pWifiIfaceStat->info.bssid);
1323
1324 hddLog(VOS_TRACE_LEVEL_INFO,
1325 " AP country str: %c%c%c",
1326 pWifiIfaceStat->info.apCountryStr[0],
1327 pWifiIfaceStat->info.apCountryStr[1],
1328 pWifiIfaceStat->info.apCountryStr[2]);
1329
1330
1331 hddLog(VOS_TRACE_LEVEL_INFO,
1332 " Country Str Association: %c%c%c",
1333 pWifiIfaceStat->info.countryStr[0],
1334 pWifiIfaceStat->info.countryStr[1],
1335 pWifiIfaceStat->info.countryStr[2]);
1336
1337 hddLog(VOS_TRACE_LEVEL_INFO,
1338 " beaconRx %u "
1339 " mgmtRx %u "
1340 " mgmtActionRx %u "
1341 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301342 " rssiMgmt %d "
1343 " rssiData %d "
1344 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301345 pWifiIfaceStat->beaconRx,
1346 pWifiIfaceStat->mgmtRx,
1347 pWifiIfaceStat->mgmtActionRx,
1348 pWifiIfaceStat->mgmtActionTx,
1349 pWifiIfaceStat->rssiMgmt,
1350 pWifiIfaceStat->rssiData,
1351 pWifiIfaceStat->rssiAck );
1352
1353
1354 {
1355 int i;
1356 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1357 {
1358 hddLog(VOS_TRACE_LEVEL_INFO,
1359
1360 " %d) LL_STATS IFACE: "
1361 " ac: %u txMpdu: %u "
1362 " rxMpdu: %u txMcast: %u "
1363 " rxMcast: %u rxAmpdu: %u "
1364 " txAmpdu: %u mpduLost: %u "
1365 " retries: %u retriesShort: %u "
1366 " retriesLong: %u contentionTimeMin: %u "
1367 " contentionTimeMax: %u contentionTimeAvg: %u "
1368 " contentionNumSamples: %u",
1369 i,
1370 pWifiIfaceStat->AccessclassStats[i].ac,
1371 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1372 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1373 pWifiIfaceStat->AccessclassStats[i].txMcast,
1374 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1375 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1376 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1377 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1378 pWifiIfaceStat->AccessclassStats[i].retries,
1379 pWifiIfaceStat->
1380 AccessclassStats[i].retriesShort,
1381 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1382 pWifiIfaceStat->
1383 AccessclassStats[i].contentionTimeMin,
1384 pWifiIfaceStat->
1385 AccessclassStats[i].contentionTimeMax,
1386 pWifiIfaceStat->
1387 AccessclassStats[i].contentionTimeAvg,
1388 pWifiIfaceStat->
1389 AccessclassStats[i].contentionNumSamples);
1390
1391 }
1392 }
1393
Sunil Duttc69bccb2014-05-26 21:30:20 +05301394 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1395}
1396
1397/*
1398 * hdd_link_layer_process_radio_stats () - This function is called after
1399 * receiving Link Layer Radio statistics from FW.This function converts
1400 * the firmware data to the NL data and sends the same to the kernel/upper
1401 * layers.
1402 */
1403static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1404 v_VOID_t *pData)
1405{
1406 int status, i;
1407 tpSirWifiRadioStat pWifiRadioStat;
1408 tpSirWifiChannelStats pWifiChannelStats;
1409 struct sk_buff *vendor_event;
1410 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1411 struct nlattr *chList;
1412
1413 status = wlan_hdd_validate_context(pHddCtx);
1414 if (0 != status)
1415 {
1416 hddLog(VOS_TRACE_LEVEL_ERROR,
1417 FL("HDD context is not valid") );
1418 return;
1419 }
1420 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1421
1422 hddLog(VOS_TRACE_LEVEL_INFO,
1423 "LL_STATS_RADIO"
1424 " radio is %d onTime is %u "
1425 " txTime is %u rxTime is %u "
1426 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301427 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301428 " onTimePnoScan is %u onTimeHs20 is %u "
1429 " numChannels is %u",
1430 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1431 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1432 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301433 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301434 pWifiRadioStat->onTimeRoamScan,
1435 pWifiRadioStat->onTimePnoScan,
1436 pWifiRadioStat->onTimeHs20,
1437 pWifiRadioStat->numChannels);
1438 /*
1439 * Allocate a size of 4096 for the Radio stats comprising
1440 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1441 * (tSirWifiChannelStats).Each channel data is put with an
1442 * NL attribute.The size of 4096 is considered assuming that
1443 * number of channels shall not exceed beyond 60 with the
1444 * sizeof (tSirWifiChannelStats) being 24 bytes.
1445 */
1446
1447 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1448 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1449 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1450 GFP_KERNEL);
1451
1452 if (!vendor_event)
1453 {
1454 hddLog(VOS_TRACE_LEVEL_ERROR,
1455 FL("cfg80211_vendor_event_alloc failed") );
1456 return;
1457 }
1458
1459 if (nla_put_u32(vendor_event,
1460 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1461 pWifiRadioStat->radio) ||
1462 nla_put_u32(vendor_event,
1463 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1464 pWifiRadioStat->onTime) ||
1465 nla_put_u32(vendor_event,
1466 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1467 pWifiRadioStat->txTime) ||
1468 nla_put_u32(vendor_event,
1469 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1470 pWifiRadioStat->rxTime) ||
1471 nla_put_u32(vendor_event,
1472 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1473 pWifiRadioStat->onTimeScan) ||
1474 nla_put_u32(vendor_event,
1475 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1476 pWifiRadioStat->onTimeNbd) ||
1477 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301478 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1479 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301480 nla_put_u32(vendor_event,
1481 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1482 pWifiRadioStat->onTimeRoamScan) ||
1483 nla_put_u32(vendor_event,
1484 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1485 pWifiRadioStat->onTimePnoScan) ||
1486 nla_put_u32(vendor_event,
1487 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1488 pWifiRadioStat->onTimeHs20) ||
1489 nla_put_u32(vendor_event,
1490 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1491 pWifiRadioStat->numChannels))
1492 {
1493 hddLog(VOS_TRACE_LEVEL_ERROR,
1494 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1495 kfree_skb(vendor_event);
1496 return ;
1497 }
1498
1499 chList = nla_nest_start(vendor_event,
1500 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301501 if(!chList)
1502 {
1503 hddLog(VOS_TRACE_LEVEL_ERROR,
1504 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1505 __func__);
1506 kfree_skb(vendor_event);
1507 return;
1508 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301509 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1510 {
1511 struct nlattr *chInfo;
1512
1513 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1514 pWifiRadioStat->channels +
1515 (i * sizeof(tSirWifiChannelStats)));
1516
1517 hddLog(VOS_TRACE_LEVEL_INFO,
1518 " %d) Channel Info"
1519 " width is %u "
1520 " CenterFreq %u "
1521 " CenterFreq0 %u "
1522 " CenterFreq1 %u "
1523 " onTime %u "
1524 " ccaBusyTime %u",
1525 i,
1526 pWifiChannelStats->channel.width,
1527 pWifiChannelStats->channel.centerFreq,
1528 pWifiChannelStats->channel.centerFreq0,
1529 pWifiChannelStats->channel.centerFreq1,
1530 pWifiChannelStats->onTime,
1531 pWifiChannelStats->ccaBusyTime);
1532
1533
1534 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301535 if(!chInfo)
1536 {
1537 hddLog(VOS_TRACE_LEVEL_ERROR,
1538 "%s: failed to put chInfo",
1539 __func__);
1540 kfree_skb(vendor_event);
1541 return;
1542 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301543
1544 if (nla_put_u32(vendor_event,
1545 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1546 pWifiChannelStats->channel.width) ||
1547 nla_put_u32(vendor_event,
1548 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1549 pWifiChannelStats->channel.centerFreq) ||
1550 nla_put_u32(vendor_event,
1551 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1552 pWifiChannelStats->channel.centerFreq0) ||
1553 nla_put_u32(vendor_event,
1554 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1555 pWifiChannelStats->channel.centerFreq1) ||
1556 nla_put_u32(vendor_event,
1557 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1558 pWifiChannelStats->onTime) ||
1559 nla_put_u32(vendor_event,
1560 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1561 pWifiChannelStats->ccaBusyTime))
1562 {
1563 hddLog(VOS_TRACE_LEVEL_ERROR,
1564 FL("cfg80211_vendor_event_alloc failed") );
1565 kfree_skb(vendor_event);
1566 return ;
1567 }
1568 nla_nest_end(vendor_event, chInfo);
1569 }
1570 nla_nest_end(vendor_event, chList);
1571
1572 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1573 return;
1574}
1575
1576/*
1577 * hdd_link_layer_stats_ind_callback () - This function is called after
1578 * receiving Link Layer indications from FW.This callback converts the firmware
1579 * data to the NL data and send the same to the kernel/upper layers.
1580 */
1581static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1582 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301583 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301584{
Dino Mycled3d50022014-07-07 12:58:25 +05301585 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1586 hdd_adapter_t *pAdapter = NULL;
1587 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301588 int status;
1589
1590 status = wlan_hdd_validate_context(pHddCtx);
1591
1592 if (0 != status)
1593 {
1594 hddLog(VOS_TRACE_LEVEL_ERROR,
1595 FL("HDD context is not valid"));
1596 return;
1597 }
1598
Dino Mycled3d50022014-07-07 12:58:25 +05301599
1600
1601 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1602 if (NULL == pAdapter)
1603 {
1604 hddLog(VOS_TRACE_LEVEL_ERROR,
1605 FL(" MAC address %pM does not exist with host"),
1606 macAddr);
1607 return;
1608 }
1609
Sunil Duttc69bccb2014-05-26 21:30:20 +05301610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301611 "%s: Interface: %s LLStats indType: %d", __func__,
1612 pAdapter->dev->name, indType);
1613
Sunil Duttc69bccb2014-05-26 21:30:20 +05301614 switch (indType)
1615 {
1616 case SIR_HAL_LL_STATS_RESULTS_RSP:
1617 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301618 hddLog(VOS_TRACE_LEVEL_INFO,
1619 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1620 hddLog(VOS_TRACE_LEVEL_INFO,
1621 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1622 linkLayerStatsResults->paramId);
1623 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301624 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1625 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301626 hddLog(VOS_TRACE_LEVEL_INFO,
1627 "LL_STATS RESULTS RESPONSE respId = %u",
1628 linkLayerStatsResults->respId);
1629 hddLog(VOS_TRACE_LEVEL_INFO,
1630 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1631 linkLayerStatsResults->moreResultToFollow);
1632 hddLog(VOS_TRACE_LEVEL_INFO,
1633 "LL_STATS RESULTS RESPONSE result = %p",
1634 linkLayerStatsResults->result);
1635 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1636 {
1637 hdd_link_layer_process_radio_stats(pAdapter,
1638 (v_VOID_t *)linkLayerStatsResults->result);
1639 }
1640 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1641 {
1642 hdd_link_layer_process_iface_stats(pAdapter,
1643 (v_VOID_t *)linkLayerStatsResults->result);
1644 }
1645 else if ( linkLayerStatsResults->paramId &
1646 WMI_LINK_STATS_ALL_PEER )
1647 {
1648 hdd_link_layer_process_peer_stats(pAdapter,
1649 (v_VOID_t *)linkLayerStatsResults->result);
1650 } /* WMI_LINK_STATS_ALL_PEER */
1651 else
1652 {
1653 hddLog(VOS_TRACE_LEVEL_ERROR,
1654 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1655 }
1656
1657 break;
1658 }
1659 default:
1660 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1661 break;
1662 }
1663 return;
1664}
1665
1666const struct
1667nla_policy
1668qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1669{
1670 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1671 { .type = NLA_U32 },
1672 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1673 { .type = NLA_U32 },
1674};
1675
1676static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1677 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05301678 const void *data,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301679 int data_len)
1680{
1681 int status;
1682 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301683 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301684 struct net_device *dev = wdev->netdev;
1685 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1686 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Srinivas Dasari98947432014-11-07 19:41:24 +05301687 hdd_station_ctx_t *pHddStaCtx;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301688
1689 status = wlan_hdd_validate_context(pHddCtx);
1690 if (0 != status)
1691 {
1692 hddLog(VOS_TRACE_LEVEL_ERROR,
1693 FL("HDD context is not valid"));
1694 return -EINVAL;
1695 }
1696
1697 if (NULL == pAdapter)
1698 {
1699 hddLog(VOS_TRACE_LEVEL_ERROR,
1700 FL("HDD adapter is Null"));
1701 return -ENODEV;
1702 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301703 /* check the LLStats Capability */
1704 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1705 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1706 {
1707 hddLog(VOS_TRACE_LEVEL_ERROR,
1708 FL("Link Layer Statistics not supported by Firmware"));
1709 return -EINVAL;
1710 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301711
1712 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1713 (struct nlattr *)data,
1714 data_len, qca_wlan_vendor_ll_set_policy))
1715 {
1716 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1717 return -EINVAL;
1718 }
1719 if (!tb_vendor
1720 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1721 {
1722 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1723 return -EINVAL;
1724 }
1725 if (!tb_vendor[
1726 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1727 {
1728 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1729 return -EINVAL;
1730 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301731 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301732 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301733
Dino Mycledf0a5d92014-07-04 09:41:55 +05301734 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301735 nla_get_u32(
1736 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1737
Dino Mycledf0a5d92014-07-04 09:41:55 +05301738 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301739 nla_get_u32(
1740 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1741
Dino Mycled3d50022014-07-07 12:58:25 +05301742 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1743 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301744
1745
1746 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301747 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301748 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301749 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301750 hddLog(VOS_TRACE_LEVEL_INFO,
1751 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301752 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301753 hddLog(VOS_TRACE_LEVEL_INFO,
1754 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301755 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301756
1757 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1758 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301759 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301760 {
1761 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1762 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301763 return -EINVAL;
1764
1765 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301766
1767 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1768 if (VOS_STATUS_SUCCESS !=
1769 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1770 pHddStaCtx->conn_info.staId[0], WIFI_STATS_IFACE))
1771 {
1772 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1773 "WLANTL_ClearInterfaceStats Failed", __func__);
1774 return -EINVAL;
1775 }
1776
1777 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
1778 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
1779 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
1780 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
1781
Sunil Duttc69bccb2014-05-26 21:30:20 +05301782 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301783 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301784 {
1785 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1786 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301787 return -EINVAL;
1788 }
1789
1790 pAdapter->isLinkLayerStatsSet = 1;
1791
1792 return 0;
1793}
1794
1795const struct
1796nla_policy
1797qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1798{
1799 /* Unsigned 32bit value provided by the caller issuing the GET stats
1800 * command. When reporting
1801 * the stats results, the driver uses the same value to indicate
1802 * which GET request the results
1803 * correspond to.
1804 */
1805 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1806
1807 /* Unsigned 32bit value . bit mask to identify what statistics are
1808 requested for retrieval */
1809 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1810};
1811
1812static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1813 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05301814 const void *data,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301815 int data_len)
1816{
1817 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1818 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301819 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301820 struct net_device *dev = wdev->netdev;
1821 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1822 int status;
1823
1824 status = wlan_hdd_validate_context(pHddCtx);
1825 if (0 != status)
1826 {
1827 hddLog(VOS_TRACE_LEVEL_ERROR,
1828 FL("HDD context is not valid"));
1829 return -EINVAL ;
1830 }
1831
1832 if (NULL == pAdapter)
1833 {
1834 hddLog(VOS_TRACE_LEVEL_FATAL,
1835 "%s: HDD adapter is Null", __func__);
1836 return -ENODEV;
1837 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301838 /* check the LLStats Capability */
1839 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1840 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1841 {
1842 hddLog(VOS_TRACE_LEVEL_ERROR,
1843 FL("Link Layer Statistics not supported by Firmware"));
1844 return -EINVAL;
1845 }
1846
Sunil Duttc69bccb2014-05-26 21:30:20 +05301847
1848 if (!pAdapter->isLinkLayerStatsSet)
1849 {
1850 hddLog(VOS_TRACE_LEVEL_FATAL,
1851 "%s: isLinkLayerStatsSet : %d",
1852 __func__, pAdapter->isLinkLayerStatsSet);
1853 return -EINVAL;
1854 }
1855
1856 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1857 (struct nlattr *)data,
1858 data_len, qca_wlan_vendor_ll_get_policy))
1859 {
1860 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1861 return -EINVAL;
1862 }
1863
1864 if (!tb_vendor
1865 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1866 {
1867 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1868 return -EINVAL;
1869 }
1870
1871 if (!tb_vendor
1872 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1873 {
1874 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1875 return -EINVAL;
1876 }
1877
Sunil Duttc69bccb2014-05-26 21:30:20 +05301878
Dino Mycledf0a5d92014-07-04 09:41:55 +05301879 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301880 nla_get_u32( tb_vendor[
1881 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301882 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301883 nla_get_u32( tb_vendor[
1884 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1885
Dino Mycled3d50022014-07-07 12:58:25 +05301886 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1887 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301888
1889 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301890 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301891 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301892 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301893 hddLog(VOS_TRACE_LEVEL_INFO,
1894 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301895 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301896
1897 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301898 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301899 {
1900 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1901 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301902 return -EINVAL;
1903 }
1904 return 0;
1905}
1906
1907const struct
1908nla_policy
1909qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1910{
1911 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1912 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1913 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1914 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1915};
1916
1917static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1918 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05301919 const void *data,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301920 int data_len)
1921{
1922 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1923 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301924 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301925 struct net_device *dev = wdev->netdev;
1926 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1927 u32 statsClearReqMask;
1928 u8 stopReq;
1929 int status;
1930
1931 status = wlan_hdd_validate_context(pHddCtx);
1932 if (0 != status)
1933 {
1934 hddLog(VOS_TRACE_LEVEL_ERROR,
1935 FL("HDD context is not valid"));
1936 return -EINVAL;
1937 }
1938
1939 if (NULL == pAdapter)
1940 {
1941 hddLog(VOS_TRACE_LEVEL_FATAL,
1942 "%s: HDD adapter is Null", __func__);
1943 return -ENODEV;
1944 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301945 /* check the LLStats Capability */
1946 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1947 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1948 {
1949 hddLog(VOS_TRACE_LEVEL_ERROR,
1950 FL("Enable LLStats Capability"));
1951 return -EINVAL;
1952 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301953
1954 if (!pAdapter->isLinkLayerStatsSet)
1955 {
1956 hddLog(VOS_TRACE_LEVEL_FATAL,
1957 "%s: isLinkLayerStatsSet : %d",
1958 __func__, pAdapter->isLinkLayerStatsSet);
1959 return -EINVAL;
1960 }
1961
1962 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1963 (struct nlattr *)data,
1964 data_len, qca_wlan_vendor_ll_clr_policy))
1965 {
1966 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1967 return -EINVAL;
1968 }
1969
1970 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
1971
1972 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
1973 {
1974 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
1975 return -EINVAL;
1976
1977 }
1978
Sunil Duttc69bccb2014-05-26 21:30:20 +05301979
Dino Mycledf0a5d92014-07-04 09:41:55 +05301980 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301981 nla_get_u32(
1982 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
1983
Dino Mycledf0a5d92014-07-04 09:41:55 +05301984 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301985 nla_get_u8(
1986 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
1987
1988 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301989 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301990
Dino Mycled3d50022014-07-07 12:58:25 +05301991 vos_mem_copy(linkLayerStatsClearReq.macAddr,
1992 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301993
1994 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301995 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301996 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301997 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301998 hddLog(VOS_TRACE_LEVEL_INFO,
1999 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302000 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302001 hddLog(VOS_TRACE_LEVEL_INFO,
2002 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302003 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302004
2005 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302006 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302007 {
2008 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302009 hdd_station_ctx_t *pHddStaCtx;
2010
2011 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2012 if (VOS_STATUS_SUCCESS !=
2013 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2014 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2015 {
2016 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2017 "WLANTL_ClearInterfaceStats Failed", __func__);
2018 return -EINVAL;
2019 }
2020 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2021 (statsClearReqMask & WIFI_STATS_IFACE)) {
2022 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2023 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2024 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2025 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2026 }
2027
Sunil Duttc69bccb2014-05-26 21:30:20 +05302028 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2029 2 * sizeof(u32) +
2030 NLMSG_HDRLEN);
2031
2032 if (temp_skbuff != NULL)
2033 {
2034
2035 if (nla_put_u32(temp_skbuff,
2036 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2037 statsClearReqMask) ||
2038 nla_put_u32(temp_skbuff,
2039 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2040 stopReq))
2041 {
2042 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2043 kfree_skb(temp_skbuff);
2044 return -EINVAL;
2045 }
2046 /* If the ask is to stop the stats collection as part of clear
2047 * (stopReq = 1) , ensure that no further requests of get
2048 * go to the firmware by having isLinkLayerStatsSet set to 0.
2049 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302050 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302051 * case the firmware is just asked to clear the statistics.
2052 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302053 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302054 pAdapter->isLinkLayerStatsSet = 0;
2055 return cfg80211_vendor_cmd_reply(temp_skbuff);
2056 }
2057 return -ENOMEM;
2058 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302059 return -EINVAL;
2060}
2061#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2062
Dino Mycle6fb96c12014-06-10 11:52:40 +05302063#ifdef WLAN_FEATURE_EXTSCAN
2064static const struct nla_policy
2065wlan_hdd_extscan_config_policy
2066 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2067{
2068 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2069 { .type = NLA_U32 },
2070 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2071 { .type = NLA_U32 },
2072 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2073 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2074 { .type = NLA_U32 },
2075 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2076 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2077
2078 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2079 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2080 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2081 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2082 { .type = NLA_U8 },
2083 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2084 { .type = NLA_U32 },
2085 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2086 { .type = NLA_U32 },
2087 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2088 { .type = NLA_U32 },
2089 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
2090 { .type = NLA_U8 },
2091 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2092 { .type = NLA_U8 },
2093 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2094 { .type = NLA_U8 },
2095
2096 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2097 { .type = NLA_U32 },
2098 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2099 { .type = NLA_UNSPEC },
2100 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2101 { .type = NLA_S32 },
2102 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2103 { .type = NLA_S32 },
2104 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2105 { .type = NLA_U32 },
2106 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2107 { .type = NLA_U32 },
2108 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2109 { .type = NLA_U32 },
2110 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2111 = { .type = NLA_U32 },
2112 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2113 { .type = NLA_U32 },
2114 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2115 NLA_U32 },
2116};
2117
2118static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
2119{
2120 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2121 struct sk_buff *skb = NULL;
2122 tpSirEXTScanCapabilitiesEvent pData =
2123 (tpSirEXTScanCapabilitiesEvent) pMsg;
2124
2125 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2126 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2127 "or pData(%p) is null"), pData);
2128 return;
2129 }
2130
2131 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2132 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2133 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
2134 GFP_KERNEL);
2135
2136 if (!skb) {
2137 hddLog(VOS_TRACE_LEVEL_ERROR,
2138 FL("cfg80211_vendor_event_alloc failed"));
2139 return;
2140 }
2141
2142 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2143 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
2144 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
2145 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
2146 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
2147 pData->maxRssiSampleSize);
2148 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
2149 pData->maxScanReportingThreshold);
2150 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
2151 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
2152 pData->maxSignificantWifiChangeAPs);
2153 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
2154 pData->maxBsidHistoryEntries);
2155
2156 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2157 pData->requestId) ||
2158 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
2159 nla_put_u32(skb,
2160 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
2161 pData->scanCacheSize) ||
2162 nla_put_u32(skb,
2163 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
2164 pData->scanBuckets) ||
2165 nla_put_u32(skb,
2166 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
2167 pData->maxApPerScan) ||
2168 nla_put_u32(skb,
2169 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
2170 pData->maxRssiSampleSize) ||
2171 nla_put_u32(skb,
2172 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
2173 pData->maxScanReportingThreshold) ||
2174 nla_put_u32(skb,
2175 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
2176 pData->maxHotlistAPs) ||
2177 nla_put_u32(skb,
2178 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
2179 pData->maxSignificantWifiChangeAPs) ||
2180 nla_put_u32(skb,
2181 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2182 pData->maxBsidHistoryEntries)) {
2183 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2184 goto nla_put_failure;
2185 }
2186
2187 cfg80211_vendor_event(skb, GFP_KERNEL);
2188 return;
2189
2190nla_put_failure:
2191 kfree_skb(skb);
2192 return;
2193}
2194
2195
2196static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2197{
2198 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2199 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2200 struct sk_buff *skb = NULL;
2201 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2202
2203
2204 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2205 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2206 "or pData(%p) is null"), pData);
2207 return;
2208 }
2209
2210 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2211 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2212 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2213 GFP_KERNEL);
2214
2215 if (!skb) {
2216 hddLog(VOS_TRACE_LEVEL_ERROR,
2217 FL("cfg80211_vendor_event_alloc failed"));
2218 return;
2219 }
2220 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2221 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2222 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2223
2224 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2225 pData->requestId) ||
2226 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2227 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2228 goto nla_put_failure;
2229 }
2230
2231 /*
2232 * Store the Request ID for comparing with the requestID obtained
2233 * in other requests.HDD shall return a failure is the extscan_stop
2234 * request is issued with a different requestId as that of the
2235 * extscan_start request. Also, This requestId shall be used while
2236 * indicating the full scan results to the upper layers.
2237 * The requestId is stored with the assumption that the firmware
2238 * shall return the ext scan start request's requestId in ext scan
2239 * start response.
2240 */
2241 if (pData->status == 0)
2242 pMac->sme.extScanStartReqId = pData->requestId;
2243
2244
2245 cfg80211_vendor_event(skb, GFP_KERNEL);
2246 return;
2247
2248nla_put_failure:
2249 kfree_skb(skb);
2250 return;
2251}
2252
2253
2254static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2255{
2256 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2257 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2258 struct sk_buff *skb = NULL;
2259
2260 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2262 "or pData(%p) is null"), pData);
2263 return;
2264 }
2265
2266 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2267 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2268 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2269 GFP_KERNEL);
2270
2271 if (!skb) {
2272 hddLog(VOS_TRACE_LEVEL_ERROR,
2273 FL("cfg80211_vendor_event_alloc failed"));
2274 return;
2275 }
2276 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2277 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2278
2279 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2280 pData->requestId) ||
2281 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2282 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2283 goto nla_put_failure;
2284 }
2285
2286 cfg80211_vendor_event(skb, GFP_KERNEL);
2287 return;
2288
2289nla_put_failure:
2290 kfree_skb(skb);
2291 return;
2292}
2293
2294
2295static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2296 void *pMsg)
2297{
2298 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2299 struct sk_buff *skb = NULL;
2300 tpSirEXTScanSetBssidHotListRspParams pData =
2301 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2302
2303 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2304 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2305 "or pData(%p) is null"), pData);
2306 return;
2307 }
2308 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2309 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2310 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2311 GFP_KERNEL);
2312
2313 if (!skb) {
2314 hddLog(VOS_TRACE_LEVEL_ERROR,
2315 FL("cfg80211_vendor_event_alloc failed"));
2316 return;
2317 }
2318 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2319 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2320 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2321
2322 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2323 pData->requestId) ||
2324 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2325 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2326 goto nla_put_failure;
2327 }
2328
2329 cfg80211_vendor_event(skb, GFP_KERNEL);
2330 return;
2331
2332nla_put_failure:
2333 kfree_skb(skb);
2334 return;
2335}
2336
2337static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2338 void *pMsg)
2339{
2340 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2341 struct sk_buff *skb = NULL;
2342 tpSirEXTScanResetBssidHotlistRspParams pData =
2343 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2344
2345 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2346 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2347 "or pData(%p) is null"), pData);
2348 return;
2349 }
2350
2351 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2352 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2353 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2354 GFP_KERNEL);
2355
2356 if (!skb) {
2357 hddLog(VOS_TRACE_LEVEL_ERROR,
2358 FL("cfg80211_vendor_event_alloc failed"));
2359 return;
2360 }
2361 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2362 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2363
2364 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2365 pData->requestId) ||
2366 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2367 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2368 goto nla_put_failure;
2369 }
2370
2371 cfg80211_vendor_event(skb, GFP_KERNEL);
2372 return;
2373
2374nla_put_failure:
2375 kfree_skb(skb);
2376 return;
2377}
2378
2379
2380static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2381 void *pMsg)
2382{
2383 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2384 struct sk_buff *skb = NULL;
2385 tpSirEXTScanSetSignificantChangeRspParams pData =
2386 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2387
2388 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2389 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2390 "or pData(%p) is null"), pData);
2391 return;
2392 }
2393
2394 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2395 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2396 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2397 GFP_KERNEL);
2398
2399 if (!skb) {
2400 hddLog(VOS_TRACE_LEVEL_ERROR,
2401 FL("cfg80211_vendor_event_alloc failed"));
2402 return;
2403 }
2404 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2405 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2406 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2407
2408 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2409 pData->requestId) ||
2410 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2411 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2412 goto nla_put_failure;
2413 }
2414
2415 cfg80211_vendor_event(skb, GFP_KERNEL);
2416 return;
2417
2418nla_put_failure:
2419 kfree_skb(skb);
2420 return;
2421}
2422
2423
2424static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2425 void *pMsg)
2426{
2427 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2428 struct sk_buff *skb = NULL;
2429 tpSirEXTScanResetSignificantChangeRspParams pData =
2430 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2431
2432 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2433 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2434 "or pData(%p) is null"), pData);
2435 return;
2436 }
2437
2438 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2439 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2440 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2441 GFP_KERNEL);
2442
2443 if (!skb) {
2444 hddLog(VOS_TRACE_LEVEL_ERROR,
2445 FL("cfg80211_vendor_event_alloc failed"));
2446 return;
2447 }
2448 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2449 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2450 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2451
2452 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2453 pData->requestId) ||
2454 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2455 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2456 goto nla_put_failure;
2457 }
2458
2459 cfg80211_vendor_event(skb, GFP_KERNEL);
2460 return;
2461
2462nla_put_failure:
2463 kfree_skb(skb);
2464 return;
2465}
2466
2467static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2468 void *pMsg)
2469{
2470 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2471 struct sk_buff *skb = NULL;
2472 tANI_U32 i = 0, j, resultsPerEvent;
2473 tANI_S32 totalResults;
2474 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2475 tpSirWifiScanResult pSirWifiScanResult;
2476
2477 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2478 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2479 "or pData(%p) is null"), pData);
2480 return;
2481 }
2482 totalResults = pData->numOfAps;
2483 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2484 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2485 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2486
2487 do{
2488 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2489 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2490 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2491
2492 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2493 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2494 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2495 GFP_KERNEL);
2496
2497 if (!skb) {
2498 hddLog(VOS_TRACE_LEVEL_ERROR,
2499 FL("cfg80211_vendor_event_alloc failed"));
2500 return;
2501 }
2502
2503 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2504
2505 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2506 pData->requestId) ||
2507 nla_put_u32(skb,
2508 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2509 resultsPerEvent)) {
2510 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2511 goto fail;
2512 }
2513 if (nla_put_u8(skb,
2514 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2515 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2516 {
2517 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2518 goto fail;
2519 }
2520
2521 if (resultsPerEvent) {
2522 struct nlattr *aps;
2523
2524 aps = nla_nest_start(skb,
2525 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2526 if (!aps)
2527 {
2528 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2529 goto fail;
2530 }
2531
2532 for (j = 0; j < resultsPerEvent; j++, i++) {
2533 struct nlattr *ap;
2534 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2535 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2536
2537 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2538 "Ssid (%s)"
2539 "Bssid: %pM "
2540 "Channel (%u)"
2541 "Rssi (%d)"
2542 "RTT (%u)"
2543 "RTT_SD (%u)",
2544 i,
2545 pSirWifiScanResult->ts,
2546 pSirWifiScanResult->ssid,
2547 pSirWifiScanResult->bssid,
2548 pSirWifiScanResult->channel,
2549 pSirWifiScanResult->rssi,
2550 pSirWifiScanResult->rtt,
2551 pSirWifiScanResult->rtt_sd);
2552
2553 ap = nla_nest_start(skb, j + 1);
2554 if (!ap)
2555 {
2556 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2557 goto fail;
2558 }
2559
2560 if (nla_put_u64(skb,
2561 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2562 pSirWifiScanResult->ts) )
2563 {
2564 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2565 goto fail;
2566 }
2567 if (nla_put(skb,
2568 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2569 sizeof(pSirWifiScanResult->ssid),
2570 pSirWifiScanResult->ssid) )
2571 {
2572 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2573 goto fail;
2574 }
2575 if (nla_put(skb,
2576 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2577 sizeof(pSirWifiScanResult->bssid),
2578 pSirWifiScanResult->bssid) )
2579 {
2580 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2581 goto fail;
2582 }
2583 if (nla_put_u32(skb,
2584 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2585 pSirWifiScanResult->channel) )
2586 {
2587 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2588 goto fail;
2589 }
Dasari Srinivas90747d72014-10-08 12:16:15 +05302590 if (nla_put_s32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302591 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2592 pSirWifiScanResult->rssi) )
2593 {
2594 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2595 goto fail;
2596 }
2597 if (nla_put_u32(skb,
2598 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2599 pSirWifiScanResult->rtt) )
2600 {
2601 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2602 goto fail;
2603 }
2604 if (nla_put_u32(skb,
2605 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2606 pSirWifiScanResult->rtt_sd))
2607 {
2608 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2609 goto fail;
2610 }
2611
2612 nla_nest_end(skb, ap);
2613 }
2614 nla_nest_end(skb, aps);
2615
2616 }
2617 cfg80211_vendor_event(skb, GFP_KERNEL);
2618 } while (totalResults > 0);
2619
2620 return;
2621fail:
2622 kfree_skb(skb);
2623 return;
2624}
2625
2626static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2627 void *pMsg)
2628{
2629 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2630 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2631 struct sk_buff *skb = NULL;
2632 tANI_U32 i;
2633
2634 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2635 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2636 "or pData(%p) is null"), pData);
2637 return;
2638 }
2639
2640 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2641 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2642 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2643 GFP_KERNEL);
2644
2645 if (!skb) {
2646 hddLog(VOS_TRACE_LEVEL_ERROR,
2647 FL("cfg80211_vendor_event_alloc failed"));
2648 return;
2649 }
2650 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2651 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2652 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2653 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2654
2655 for (i = 0; i < pData->numOfAps; i++) {
2656 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2657 "Ssid (%s) "
2658 "Bssid (" MAC_ADDRESS_STR ") "
2659 "Channel (%u) "
2660 "Rssi (%d) "
2661 "RTT (%u) "
2662 "RTT_SD (%u) ",
2663 i,
2664 pData->ap[i].ts,
2665 pData->ap[i].ssid,
2666 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2667 pData->ap[i].channel,
2668 pData->ap[i].rssi,
2669 pData->ap[i].rtt,
2670 pData->ap[i].rtt_sd);
2671 }
2672
2673 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2674 pData->requestId) ||
2675 nla_put_u32(skb,
2676 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2677 pData->numOfAps)) {
2678 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2679 goto fail;
2680 }
2681 if (pData->numOfAps) {
2682 struct nlattr *aps;
2683
2684 aps = nla_nest_start(skb,
2685 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2686 if (!aps)
2687 goto fail;
2688
2689 for (i = 0; i < pData->numOfAps; i++) {
2690 struct nlattr *ap;
2691
2692 ap = nla_nest_start(skb, i + 1);
2693 if (!ap)
2694 goto fail;
2695
2696 if (nla_put_u64(skb,
2697 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2698 pData->ap[i].ts) ||
2699 nla_put(skb,
2700 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2701 sizeof(pData->ap[i].ssid),
2702 pData->ap[i].ssid) ||
2703 nla_put(skb,
2704 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2705 sizeof(pData->ap[i].bssid),
2706 pData->ap[i].bssid) ||
2707 nla_put_u32(skb,
2708 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2709 pData->ap[i].channel) ||
2710 nla_put_s32(skb,
2711 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2712 pData->ap[i].rssi) ||
2713 nla_put_u32(skb,
2714 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2715 pData->ap[i].rtt) ||
2716 nla_put_u32(skb,
2717 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2718 pData->ap[i].rtt_sd))
2719 goto fail;
2720
2721 nla_nest_end(skb, ap);
2722 }
2723 nla_nest_end(skb, aps);
2724
2725 if (nla_put_u8(skb,
2726 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2727 pData->moreData))
2728 goto fail;
2729 }
2730
2731 cfg80211_vendor_event(skb, GFP_KERNEL);
2732 return;
2733
2734fail:
2735 kfree_skb(skb);
2736 return;
2737
2738}
2739static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2740 void *pMsg)
2741{
2742 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2743 struct sk_buff *skb = NULL;
2744 tANI_U32 i, j;
2745 tpSirWifiSignificantChangeEvent pData =
2746 (tpSirWifiSignificantChangeEvent) pMsg;
2747
2748 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2749 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2750 "or pData(%p) is null"), pData);
2751 return;
2752 }
2753 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2754 EXTSCAN_EVENT_BUF_SIZE,
2755 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2756 GFP_KERNEL);
2757
2758 if (!skb) {
2759 hddLog(VOS_TRACE_LEVEL_ERROR,
2760 FL("cfg80211_vendor_event_alloc failed"));
2761 return;
2762 }
2763 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2764 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2765 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2766 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2767 pData->numSigRssiBss);
2768 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2769
2770 for (i = 0; i < pData->numSigRssiBss; i++) {
2771 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2772 " num RSSI %u ",
2773 i, pData->sigRssiResult[i].bssid,
2774 pData->sigRssiResult[i].channel,
2775 pData->sigRssiResult[i].numRssi);
2776
2777 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2778
2779 hddLog(VOS_TRACE_LEVEL_INFO,
2780 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05302781 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302782
2783 }
2784 }
2785
2786
2787 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2788 pData->requestId) ||
2789 nla_put_u32(skb,
2790 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2791 pData->numSigRssiBss)) {
2792 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2793 goto fail;
2794 }
2795
2796 if (pData->numSigRssiBss) {
2797 struct nlattr *aps;
2798 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2799 if (!aps)
2800 goto fail;
2801 for (i = 0; i < pData->numSigRssiBss; i++) {
2802 struct nlattr *ap;
2803
2804 ap = nla_nest_start(skb, i);
2805 if (!ap)
2806 goto fail;
2807 if (nla_put(skb,
2808 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2809 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2810 nla_put_u32(skb,
2811 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2812 pData->sigRssiResult[i].channel) ||
2813 nla_put_u32(skb,
2814 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2815 pData->sigRssiResult[i].numRssi) ||
2816 nla_put(skb,
2817 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2818 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2819 pData->sigRssiResult[i].rssi))
2820 goto fail;
2821 nla_nest_end(skb, ap);
2822 }
2823 nla_nest_end(skb, aps);
2824 if (nla_put_u8(skb,
2825 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2826 pData->moreData))
2827 goto fail;
2828 }
2829 cfg80211_vendor_event(skb, GFP_KERNEL);
2830 return;
2831fail:
2832 kfree_skb(skb);
2833 return;
2834}
2835
2836static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2837 void *pMsg)
2838{
2839 struct sk_buff *skb;
2840 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2841 tpSirWifiFullScanResultEvent pData =
2842 (tpSirWifiFullScanResultEvent) (pMsg);
2843
2844 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2845 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2846 "or pData(%p) is null"), pData);
2847 return;
2848 }
2849
2850 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2851 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2852 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2853 GFP_KERNEL);
2854
2855 if (!skb) {
2856 hddLog(VOS_TRACE_LEVEL_ERROR,
2857 FL("cfg80211_vendor_event_alloc failed"));
2858 return;
2859 }
2860
2861 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2862 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2863 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2864 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2865 "Ssid (%s)"
2866 "Bssid (" MAC_ADDRESS_STR ")"
2867 "Channel (%u)"
2868 "Rssi (%d)"
2869 "RTT (%u)"
2870 "RTT_SD (%u)"),
2871 pData->ap.ts,
2872 pData->ap.ssid,
2873 MAC_ADDR_ARRAY(pData->ap.bssid),
2874 pData->ap.channel,
2875 pData->ap.rssi,
2876 pData->ap.rtt,
2877 pData->ap.rtt_sd);
2878 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2879 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2880 pData->requestId) ||
2881 nla_put_u64(skb,
2882 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2883 pData->ap.ts) ||
2884 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2885 sizeof(pData->ap.ssid),
2886 pData->ap.ssid) ||
2887 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2888 WNI_CFG_BSSID_LEN,
2889 pData->ap.bssid) ||
2890 nla_put_u32(skb,
2891 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2892 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05302893 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302894 pData->ap.rssi) ||
2895 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2896 pData->ap.rtt) ||
2897 nla_put_u32(skb,
2898 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2899 pData->ap.rtt_sd) ||
2900 nla_put_u16(skb,
2901 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2902 pData->ap.beaconPeriod) ||
2903 nla_put_u16(skb,
2904 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2905 pData->ap.capability) ||
2906 nla_put_u32(skb,
2907 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2908 pData->ieLength))
2909 {
2910 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2911 goto nla_put_failure;
2912 }
2913 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2914 pData->ieLength,
2915 pData->ie))
2916 {
2917 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2918 goto nla_put_failure;
2919 }
2920
2921 cfg80211_vendor_event(skb, GFP_KERNEL);
2922 return;
2923
2924nla_put_failure:
2925 kfree_skb(skb);
2926 return;
2927}
2928
2929static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
2930 void *pMsg)
2931{
2932 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2933 struct sk_buff *skb = NULL;
2934 tpSirEXTScanResultsAvailableIndParams pData =
2935 (tpSirEXTScanResultsAvailableIndParams) pMsg;
2936
2937 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2939 "or pData(%p) is null"), pData);
2940 return;
2941 }
2942
2943 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2944 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2945 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
2946 GFP_KERNEL);
2947
2948 if (!skb) {
2949 hddLog(VOS_TRACE_LEVEL_ERROR,
2950 FL("cfg80211_vendor_event_alloc failed"));
2951 return;
2952 }
2953
2954 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2955 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2956 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
2957 pData->numResultsAvailable);
2958 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2959 pData->requestId) ||
2960 nla_put_u32(skb,
2961 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2962 pData->numResultsAvailable)) {
2963 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2964 goto nla_put_failure;
2965 }
2966
2967 cfg80211_vendor_event(skb, GFP_KERNEL);
2968 return;
2969
2970nla_put_failure:
2971 kfree_skb(skb);
2972 return;
2973}
2974
2975static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
2976{
2977 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2978 struct sk_buff *skb = NULL;
2979 tpSirEXTScanProgressIndParams pData =
2980 (tpSirEXTScanProgressIndParams) pMsg;
2981
2982 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2983 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2984 "or pData(%p) is null"), pData);
2985 return;
2986 }
2987
2988 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2989 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2990 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
2991 GFP_KERNEL);
2992
2993 if (!skb) {
2994 hddLog(VOS_TRACE_LEVEL_ERROR,
2995 FL("cfg80211_vendor_event_alloc failed"));
2996 return;
2997 }
2998 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2999 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3000 pData->extScanEventType);
3001 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3002 pData->status);
3003
3004 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3005 pData->extScanEventType) ||
3006 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303007 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3008 pData->requestId) ||
3009 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303010 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3011 pData->status)) {
3012 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3013 goto nla_put_failure;
3014 }
3015
3016 cfg80211_vendor_event(skb, GFP_KERNEL);
3017 return;
3018
3019nla_put_failure:
3020 kfree_skb(skb);
3021 return;
3022}
3023
3024void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3025 void *pMsg)
3026{
3027 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3028
3029 if (wlan_hdd_validate_context(pHddCtx)) {
Dasari Srinivasb46ed1d2014-10-08 13:03:08 +05303030 hddLog(VOS_TRACE_LEVEL_INFO, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303031 return;
3032 }
3033
3034 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3035
3036
3037 switch(evType) {
3038 case SIR_HAL_EXTSCAN_START_RSP:
3039 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3040 break;
3041
3042 case SIR_HAL_EXTSCAN_STOP_RSP:
3043 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3044 break;
3045 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3046 /* There is no need to send this response to upper layer
3047 Just log the message */
3048 hddLog(VOS_TRACE_LEVEL_INFO,
3049 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3050 break;
3051 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3052 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3053 break;
3054
3055 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3056 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3057 break;
3058
3059 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
3060 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
3061 break;
3062
3063 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
3064 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
3065 break;
3066 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
3067 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
3068 break;
3069 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3070 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3071 break;
3072 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3073 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3074 break;
3075 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3076 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3077 break;
3078 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3079 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3080 break;
3081 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
3082 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
3083 break;
3084 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3085 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3086 break;
3087 default:
3088 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3089 break;
3090 }
3091}
3092
3093static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3094 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303095 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303096{
Dino Myclee8843b32014-07-04 14:21:45 +05303097 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303098 struct net_device *dev = wdev->netdev;
3099 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3100 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3101 struct nlattr
3102 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3103 eHalStatus status;
3104
3105 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3106 status = wlan_hdd_validate_context(pHddCtx);
3107 if (0 != status)
3108 {
3109 hddLog(VOS_TRACE_LEVEL_ERROR,
3110 FL("HDD context is not valid"));
3111 return -EINVAL;
3112 }
Dino Myclee8843b32014-07-04 14:21:45 +05303113 /* check the EXTScan Capability */
3114 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3115 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3116 {
3117 hddLog(VOS_TRACE_LEVEL_ERROR,
3118 FL("EXTScan not enabled/supported by Firmware"));
3119 return -EINVAL;
3120 }
3121
Dino Mycle6fb96c12014-06-10 11:52:40 +05303122 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3123 data, dataLen,
3124 wlan_hdd_extscan_config_policy)) {
3125 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3126 return -EINVAL;
3127 }
3128
3129 /* Parse and fetch request Id */
3130 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3131 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3132 return -EINVAL;
3133 }
3134
Dino Mycle6fb96c12014-06-10 11:52:40 +05303135
Dino Myclee8843b32014-07-04 14:21:45 +05303136 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303137 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303138 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303139
Dino Myclee8843b32014-07-04 14:21:45 +05303140 reqMsg.sessionId = pAdapter->sessionId;
3141 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303142
Dino Myclee8843b32014-07-04 14:21:45 +05303143 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303144 if (!HAL_STATUS_SUCCESS(status)) {
3145 hddLog(VOS_TRACE_LEVEL_ERROR,
3146 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303147 return -EINVAL;
3148 }
3149
3150 return 0;
3151}
3152
3153
3154static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3155 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303156 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303157{
Dino Myclee8843b32014-07-04 14:21:45 +05303158 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303159 struct net_device *dev = wdev->netdev;
3160 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3161 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3162 struct nlattr
3163 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3164 eHalStatus status;
3165
3166 status = wlan_hdd_validate_context(pHddCtx);
3167 if (0 != status)
3168 {
3169 hddLog(VOS_TRACE_LEVEL_ERROR,
3170 FL("HDD context is not valid"));
3171 return -EINVAL;
3172 }
Dino Myclee8843b32014-07-04 14:21:45 +05303173 /* check the EXTScan Capability */
3174 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3175 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3176 {
3177 hddLog(VOS_TRACE_LEVEL_ERROR,
3178 FL("EXTScan not enabled/supported by Firmware"));
3179 return -EINVAL;
3180 }
3181
Dino Mycle6fb96c12014-06-10 11:52:40 +05303182 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3183 data, dataLen,
3184 wlan_hdd_extscan_config_policy)) {
3185 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3186 return -EINVAL;
3187 }
3188 /* Parse and fetch request Id */
3189 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3190 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3191 return -EINVAL;
3192 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303193
Dino Myclee8843b32014-07-04 14:21:45 +05303194 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303195 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3196
Dino Myclee8843b32014-07-04 14:21:45 +05303197 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303198
Dino Myclee8843b32014-07-04 14:21:45 +05303199 reqMsg.sessionId = pAdapter->sessionId;
3200 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303201
3202 /* Parse and fetch flush parameter */
3203 if (!tb
3204 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3205 {
3206 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3207 goto failed;
3208 }
Dino Myclee8843b32014-07-04 14:21:45 +05303209 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303210 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3211
Dino Myclee8843b32014-07-04 14:21:45 +05303212 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303213
Dino Myclee8843b32014-07-04 14:21:45 +05303214 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303215 if (!HAL_STATUS_SUCCESS(status)) {
3216 hddLog(VOS_TRACE_LEVEL_ERROR,
3217 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303218 return -EINVAL;
3219 }
3220 return 0;
3221
3222failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303223 return -EINVAL;
3224}
3225
3226static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3227 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303228 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303229{
3230 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3231 struct net_device *dev = wdev->netdev;
3232 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3233 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3234 struct nlattr
3235 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3236 struct nlattr
3237 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3238 struct nlattr *apTh;
3239 eHalStatus status;
3240 tANI_U8 i = 0;
3241 int rem;
3242
3243 status = wlan_hdd_validate_context(pHddCtx);
3244 if (0 != status)
3245 {
3246 hddLog(VOS_TRACE_LEVEL_ERROR,
3247 FL("HDD context is not valid"));
3248 return -EINVAL;
3249 }
Dino Myclee8843b32014-07-04 14:21:45 +05303250 /* check the EXTScan Capability */
3251 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3252 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3253 {
3254 hddLog(VOS_TRACE_LEVEL_ERROR,
3255 FL("EXTScan not enabled/supported by Firmware"));
3256 return -EINVAL;
3257 }
3258
Dino Mycle6fb96c12014-06-10 11:52:40 +05303259 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3260 data, dataLen,
3261 wlan_hdd_extscan_config_policy)) {
3262 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3263 return -EINVAL;
3264 }
3265
3266 /* Parse and fetch request Id */
3267 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3268 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3269 return -EINVAL;
3270 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303271 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3272 vos_mem_malloc(sizeof(*pReqMsg));
3273 if (!pReqMsg) {
3274 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3275 return -ENOMEM;
3276 }
3277
Dino Myclee8843b32014-07-04 14:21:45 +05303278
Dino Mycle6fb96c12014-06-10 11:52:40 +05303279 pReqMsg->requestId = nla_get_u32(
3280 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3281 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3282
3283 /* Parse and fetch number of APs */
3284 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3285 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3286 goto fail;
3287 }
3288
3289 pReqMsg->sessionId = pAdapter->sessionId;
3290 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3291
3292 pReqMsg->numAp = nla_get_u32(
3293 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3294 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3295
3296 nla_for_each_nested(apTh,
3297 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3298 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3299 nla_data(apTh), nla_len(apTh),
3300 NULL)) {
3301 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3302 goto fail;
3303 }
3304
3305 /* Parse and fetch MAC address */
3306 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3307 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3308 goto fail;
3309 }
3310 memcpy(pReqMsg->ap[i].bssid, nla_data(
3311 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3312 sizeof(tSirMacAddr));
3313 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3314
3315 /* Parse and fetch low RSSI */
3316 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3317 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3318 goto fail;
3319 }
3320 pReqMsg->ap[i].low = nla_get_s32(
3321 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3322 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3323
3324 /* Parse and fetch high RSSI */
3325 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3326 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3327 goto fail;
3328 }
3329 pReqMsg->ap[i].high = nla_get_s32(
3330 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3331 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3332 pReqMsg->ap[i].high);
3333
3334 /* Parse and fetch channel */
3335 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3337 goto fail;
3338 }
3339 pReqMsg->ap[i].channel = nla_get_u32(
3340 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3341 hddLog(VOS_TRACE_LEVEL_INFO,
3342 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3343 i++;
3344 }
3345 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3346 if (!HAL_STATUS_SUCCESS(status)) {
3347 hddLog(VOS_TRACE_LEVEL_ERROR,
3348 FL("sme_SetBssHotlist failed(err=%d)"), status);
3349 vos_mem_free(pReqMsg);
3350 return -EINVAL;
3351 }
3352
Dino Myclee8843b32014-07-04 14:21:45 +05303353 vos_mem_free(pReqMsg);
3354
Dino Mycle6fb96c12014-06-10 11:52:40 +05303355 return 0;
3356
3357fail:
3358 vos_mem_free(pReqMsg);
3359 return -EINVAL;
3360}
3361
3362static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3363 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303364 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303365{
3366 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3367 struct net_device *dev = wdev->netdev;
3368 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3369 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3370 struct nlattr
3371 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3372 struct nlattr
3373 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3374 struct nlattr *apTh;
3375 eHalStatus status;
3376 int i = 0;
3377 int rem;
3378
3379 status = wlan_hdd_validate_context(pHddCtx);
3380 if (0 != status)
3381 {
3382 hddLog(VOS_TRACE_LEVEL_ERROR,
3383 FL("HDD context is not valid"));
3384 return -EINVAL;
3385 }
Dino Myclee8843b32014-07-04 14:21:45 +05303386 /* check the EXTScan Capability */
3387 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3388 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3389 {
3390 hddLog(VOS_TRACE_LEVEL_ERROR,
3391 FL("EXTScan not enabled/supported by Firmware"));
3392 return -EINVAL;
3393 }
3394
Dino Mycle6fb96c12014-06-10 11:52:40 +05303395 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3396 data, dataLen,
3397 wlan_hdd_extscan_config_policy)) {
3398 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3399 return -EINVAL;
3400 }
3401
3402 /* Parse and fetch request Id */
3403 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3404 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3405 return -EINVAL;
3406 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303407 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303408 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303409 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303410 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3411 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303412 }
3413
Dino Myclee8843b32014-07-04 14:21:45 +05303414
3415
Dino Mycle6fb96c12014-06-10 11:52:40 +05303416 pReqMsg->requestId = nla_get_u32(
3417 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3418 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3419
3420 /* Parse and fetch RSSI sample size */
3421 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3422 {
3423 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3424 goto fail;
3425 }
3426 pReqMsg->rssiSampleSize = nla_get_u32(
3427 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3428 hddLog(VOS_TRACE_LEVEL_INFO,
3429 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3430
3431 /* Parse and fetch lost AP sample size */
3432 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3433 {
3434 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3435 goto fail;
3436 }
3437 pReqMsg->lostApSampleSize = nla_get_u32(
3438 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3439 hddLog(VOS_TRACE_LEVEL_INFO,
3440 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3441 /* Parse and fetch minimum Breaching */
3442 if (!tb
3443 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3444 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3445 goto fail;
3446 }
3447 pReqMsg->minBreaching = nla_get_u32(
3448 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3449 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3450
3451 /* Parse and fetch number of APs */
3452 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3453 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3454 goto fail;
3455 }
3456 pReqMsg->numAp = nla_get_u32(
3457 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3458 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3459
3460 pReqMsg->sessionId = pAdapter->sessionId;
3461 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3462
3463 nla_for_each_nested(apTh,
3464 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3465 if(nla_parse(tb2,
3466 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3467 nla_data(apTh), nla_len(apTh),
3468 NULL)) {
3469 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3470 goto fail;
3471 }
3472
3473 /* Parse and fetch MAC address */
3474 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3476 goto fail;
3477 }
3478 memcpy(pReqMsg->ap[i].bssid, nla_data(
3479 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3480 sizeof(tSirMacAddr));
3481
3482 /* Parse and fetch low RSSI */
3483 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3484 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3485 goto fail;
3486 }
3487 pReqMsg->ap[i].low = nla_get_s32(
3488 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3489 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3490
3491 /* Parse and fetch high RSSI */
3492 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3493 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3494 goto fail;
3495 }
3496 pReqMsg->ap[i].high = nla_get_s32(
3497 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3498 hddLog(VOS_TRACE_LEVEL_INFO,
3499 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3500
3501 /* Parse and fetch channel */
3502 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3503 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3504 goto fail;
3505 }
3506 pReqMsg->ap[i].channel = nla_get_u32(
3507 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3508 hddLog(VOS_TRACE_LEVEL_INFO,
3509 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3510 i++;
3511 }
3512
3513 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3514 if (!HAL_STATUS_SUCCESS(status)) {
3515 hddLog(VOS_TRACE_LEVEL_ERROR,
3516 FL("sme_SetSignificantChange failed(err=%d)"), status);
3517 vos_mem_free(pReqMsg);
3518 return -EINVAL;
3519 }
Dino Myclee8843b32014-07-04 14:21:45 +05303520 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303521 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3522 return 0;
3523
3524fail:
3525 vos_mem_free(pReqMsg);
3526 return -EINVAL;
3527}
3528
3529static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3530 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303531 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303532{
3533 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3534 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3535 tANI_U8 numChannels = 0;
3536 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3537 tANI_U32 requestId;
3538 tWifiBand wifiBand;
3539 eHalStatus status;
3540 struct sk_buff *replySkb;
3541 tANI_U8 i;
3542
3543 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3544 status = wlan_hdd_validate_context(pHddCtx);
3545 if (0 != status)
3546 {
3547 hddLog(VOS_TRACE_LEVEL_ERROR,
3548 FL("HDD context is not valid"));
3549 return -EINVAL;
3550 }
Dino Myclee8843b32014-07-04 14:21:45 +05303551 /* check the EXTScan Capability */
3552 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3553 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3554 {
3555 hddLog(VOS_TRACE_LEVEL_ERROR,
3556 FL("EXTScan not enabled/supported by Firmware"));
3557 return -EINVAL;
3558 }
3559
Dino Mycle6fb96c12014-06-10 11:52:40 +05303560 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3561 data, dataLen,
3562 wlan_hdd_extscan_config_policy)) {
3563 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3564 return -EINVAL;
3565 }
3566
3567 /* Parse and fetch request Id */
3568 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3569 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3570 return -EINVAL;
3571 }
3572 requestId = nla_get_u32(
3573 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3574 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3575
3576 /* Parse and fetch wifi band */
3577 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3578 {
3579 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3580 return -EINVAL;
3581 }
3582 wifiBand = nla_get_u32(
3583 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3584 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3585
3586 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3587 wifiBand, ChannelList,
3588 &numChannels);
3589 if (eHAL_STATUS_SUCCESS != status) {
3590 hddLog(VOS_TRACE_LEVEL_ERROR,
3591 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3592 return -EINVAL;
3593 }
3594 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3595 for (i = 0; i < numChannels; i++)
3596 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3597
3598 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3599 sizeof(u32) * numChannels +
3600 NLMSG_HDRLEN);
3601
3602 if (!replySkb) {
3603 hddLog(VOS_TRACE_LEVEL_ERROR,
3604 FL("valid channels: buffer alloc fail"));
3605 return -EINVAL;
3606 }
3607 if (nla_put_u32(replySkb,
3608 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3609 numChannels) ||
3610 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3611 sizeof(u32) * numChannels, ChannelList)) {
3612
3613 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3614 kfree_skb(replySkb);
3615 return -EINVAL;
3616 }
3617
3618 return cfg80211_vendor_cmd_reply(replySkb);
3619}
3620
3621static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3622 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303623 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303624{
Dino Myclee8843b32014-07-04 14:21:45 +05303625 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303626 struct net_device *dev = wdev->netdev;
3627 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3628 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3629 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3630 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3631 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3632 struct nlattr *buckets;
3633 struct nlattr *channels;
3634 int rem1;
3635 int rem2;
3636 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303637 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303638
3639 status = wlan_hdd_validate_context(pHddCtx);
3640 if (0 != status)
3641 {
3642 hddLog(VOS_TRACE_LEVEL_ERROR,
3643 FL("HDD context is not valid"));
3644 return -EINVAL;
3645 }
Dino Myclee8843b32014-07-04 14:21:45 +05303646 /* check the EXTScan Capability */
3647 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3648 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3649 {
3650 hddLog(VOS_TRACE_LEVEL_ERROR,
3651 FL("EXTScan not enabled/supported by Firmware"));
3652 return -EINVAL;
3653 }
3654
Dino Mycle6fb96c12014-06-10 11:52:40 +05303655 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3656 data, dataLen,
3657 wlan_hdd_extscan_config_policy)) {
3658 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3659 return -EINVAL;
3660 }
3661
3662 /* Parse and fetch request Id */
3663 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3664 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3665 return -EINVAL;
3666 }
3667
Dino Myclee8843b32014-07-04 14:21:45 +05303668 pReqMsg = (tpSirEXTScanStartReqParams)
3669 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303670 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303671 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3672 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303673 }
3674
3675 pReqMsg->requestId = nla_get_u32(
3676 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3677 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3678
3679 pReqMsg->sessionId = pAdapter->sessionId;
3680 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3681
3682 /* Parse and fetch base period */
3683 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3684 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3685 goto fail;
3686 }
3687 pReqMsg->basePeriod = nla_get_u32(
3688 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3689 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3690 pReqMsg->basePeriod);
3691
3692 /* Parse and fetch max AP per scan */
3693 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3695 goto fail;
3696 }
3697 pReqMsg->maxAPperScan = nla_get_u32(
3698 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3699 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3700 pReqMsg->maxAPperScan);
3701
3702 /* Parse and fetch report threshold */
3703 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3704 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3705 goto fail;
3706 }
3707 pReqMsg->reportThreshold = nla_get_u8(
3708 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3709 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3710 pReqMsg->reportThreshold);
3711
3712 /* Parse and fetch number of buckets */
3713 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3714 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3715 goto fail;
3716 }
3717 pReqMsg->numBuckets = nla_get_u8(
3718 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3719 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3720 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3721 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3722 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3723 }
3724 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3725 pReqMsg->numBuckets);
3726 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3727 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3728 goto fail;
3729 }
3730
3731 nla_for_each_nested(buckets,
3732 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3733 if(nla_parse(bucket,
3734 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3735 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3736 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3737 goto fail;
3738 }
3739
3740 /* Parse and fetch bucket spec */
3741 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3742 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3743 goto fail;
3744 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303745
3746 pReqMsg->buckets[index].bucket = nla_get_u8(
3747 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3748
3749 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
3750 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303751
3752 /* Parse and fetch wifi band */
3753 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3754 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3755 goto fail;
3756 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303757 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303758 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3759 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303760 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303761
3762 /* Parse and fetch period */
3763 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3764 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3765 goto fail;
3766 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303767 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303768 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3769 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303770 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303771
3772 /* Parse and fetch report events */
3773 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3775 goto fail;
3776 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303777 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303778 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3779 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303780 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303781
3782 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303783 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
3784 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303785 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3786 goto fail;
3787 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303788 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303789 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3790 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303791 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303792
3793 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3795 goto fail;
3796 }
3797
3798 j = 0;
3799 nla_for_each_nested(channels,
3800 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3801 if(nla_parse(channel,
3802 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3803 nla_data(channels), nla_len(channels),
3804 NULL)) { //wlan_hdd_extscan_config_policy here
3805 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3806 goto fail;
3807 }
3808
3809 /* Parse and fetch channel */
3810 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3812 goto fail;
3813 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303814 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303815 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3816 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303817 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303818
3819 /* Parse and fetch dwell time */
3820 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3821 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3822 goto fail;
3823 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303824 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303825 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3826 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303827 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303828
3829 /* Parse and fetch channel spec passive */
3830 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3831 hddLog(VOS_TRACE_LEVEL_ERROR,
3832 FL("attr channel spec passive failed"));
3833 goto fail;
3834 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303835 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303836 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3837 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303838 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303839 j++;
3840 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303841 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303842 }
3843 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3844 if (!HAL_STATUS_SUCCESS(status)) {
3845 hddLog(VOS_TRACE_LEVEL_ERROR,
3846 FL("sme_EXTScanStart failed(err=%d)"), status);
3847 vos_mem_free(pReqMsg);
3848 return -EINVAL;
3849 }
3850
Dino Myclee8843b32014-07-04 14:21:45 +05303851 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303852 return 0;
3853
3854fail:
3855 vos_mem_free(pReqMsg);
3856 return -EINVAL;
3857}
3858
3859static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
3860 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303861 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303862{
Dino Myclee8843b32014-07-04 14:21:45 +05303863 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303864 struct net_device *dev = wdev->netdev;
3865 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3866 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3867 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3868 eHalStatus status;
3869
3870 status = wlan_hdd_validate_context(pHddCtx);
3871 if (0 != status)
3872 {
3873 hddLog(VOS_TRACE_LEVEL_ERROR,
3874 FL("HDD context is not valid"));
3875 return -EINVAL;
3876 }
Dino Myclee8843b32014-07-04 14:21:45 +05303877 /* check the EXTScan Capability */
3878 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3879 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3880 {
3881 hddLog(VOS_TRACE_LEVEL_ERROR,
3882 FL("EXTScan not enabled/supported by Firmware"));
3883 return -EINVAL;
3884 }
3885
Dino Mycle6fb96c12014-06-10 11:52:40 +05303886 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3887 data, dataLen,
3888 wlan_hdd_extscan_config_policy)) {
3889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3890 return -EINVAL;
3891 }
3892
3893 /* Parse and fetch request Id */
3894 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3895 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3896 return -EINVAL;
3897 }
3898
Dino Myclee8843b32014-07-04 14:21:45 +05303899 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303900 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303901 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303902
Dino Myclee8843b32014-07-04 14:21:45 +05303903 reqMsg.sessionId = pAdapter->sessionId;
3904 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303905
Dino Myclee8843b32014-07-04 14:21:45 +05303906 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303907 if (!HAL_STATUS_SUCCESS(status)) {
3908 hddLog(VOS_TRACE_LEVEL_ERROR,
3909 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303910 return -EINVAL;
3911 }
3912
3913 return 0;
3914}
3915
3916static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
3917 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303918 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303919{
Dino Myclee8843b32014-07-04 14:21:45 +05303920 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303921 struct net_device *dev = wdev->netdev;
3922 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3923 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3924 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3925 eHalStatus status;
3926
3927 status = wlan_hdd_validate_context(pHddCtx);
3928 if (0 != status)
3929 {
3930 hddLog(VOS_TRACE_LEVEL_ERROR,
3931 FL("HDD context is not valid"));
3932 return -EINVAL;
3933 }
Dino Myclee8843b32014-07-04 14:21:45 +05303934 /* check the EXTScan Capability */
3935 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3936 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3937 {
3938 hddLog(VOS_TRACE_LEVEL_ERROR,
3939 FL("EXTScan not enabled/supported by Firmware"));
3940 return -EINVAL;
3941 }
3942
Dino Mycle6fb96c12014-06-10 11:52:40 +05303943 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3944 data, dataLen,
3945 wlan_hdd_extscan_config_policy)) {
3946 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3947 return -EINVAL;
3948 }
3949
3950 /* Parse and fetch request Id */
3951 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3952 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3953 return -EINVAL;
3954 }
3955
Dino Myclee8843b32014-07-04 14:21:45 +05303956 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303957 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303958 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303959
Dino Myclee8843b32014-07-04 14:21:45 +05303960 reqMsg.sessionId = pAdapter->sessionId;
3961 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303962
Dino Myclee8843b32014-07-04 14:21:45 +05303963 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303964 if (!HAL_STATUS_SUCCESS(status)) {
3965 hddLog(VOS_TRACE_LEVEL_ERROR,
3966 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303967 return -EINVAL;
3968 }
3969
3970 return 0;
3971}
3972
3973static int wlan_hdd_cfg80211_extscan_reset_significant_change(
3974 struct wiphy *wiphy,
3975 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303976 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303977{
Dino Myclee8843b32014-07-04 14:21:45 +05303978 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303979 struct net_device *dev = wdev->netdev;
3980 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3981 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3982 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3983 eHalStatus status;
3984
3985 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
3986 status = wlan_hdd_validate_context(pHddCtx);
3987 if (0 != status)
3988 {
3989 hddLog(VOS_TRACE_LEVEL_ERROR,
3990 FL("HDD context is not valid"));
3991 return -EINVAL;
3992 }
Dino Myclee8843b32014-07-04 14:21:45 +05303993 /* check the EXTScan Capability */
3994 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3995 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3996 {
3997 hddLog(VOS_TRACE_LEVEL_ERROR,
3998 FL("EXTScan not enabled/supported by Firmware"));
3999 return -EINVAL;
4000 }
4001
Dino Mycle6fb96c12014-06-10 11:52:40 +05304002 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4003 data, dataLen,
4004 wlan_hdd_extscan_config_policy)) {
4005 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4006 return -EINVAL;
4007 }
4008
4009 /* Parse and fetch request Id */
4010 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4011 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4012 return -EINVAL;
4013 }
4014
Dino Mycle6fb96c12014-06-10 11:52:40 +05304015
Dino Myclee8843b32014-07-04 14:21:45 +05304016 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304017 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304018 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304019
Dino Myclee8843b32014-07-04 14:21:45 +05304020 reqMsg.sessionId = pAdapter->sessionId;
4021 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304022
Dino Myclee8843b32014-07-04 14:21:45 +05304023 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304024 if (!HAL_STATUS_SUCCESS(status)) {
4025 hddLog(VOS_TRACE_LEVEL_ERROR,
4026 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304027 return -EINVAL;
4028 }
4029
4030 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
4031 return 0;
4032}
4033
4034#endif /* WLAN_FEATURE_EXTSCAN */
4035
Atul Mittal115287b2014-07-08 13:26:33 +05304036/*EXT TDLS*/
4037static const struct nla_policy
4038wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4039{
4040 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4041 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4042 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4043 {.type = NLA_S32 },
4044 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4045 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4046
4047};
4048
4049static const struct nla_policy
4050wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4051{
4052 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4053
4054};
4055
4056static const struct nla_policy
4057wlan_hdd_tdls_config_state_change_policy[
4058 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4059{
4060 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4061 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4062 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304063 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4064 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4065 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304066
4067};
4068
4069static const struct nla_policy
4070wlan_hdd_tdls_config_get_status_policy[
4071 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4072{
4073 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4074 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4075 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304076 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4077 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4078 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304079
4080};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304081
4082static const struct nla_policy
4083wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4084{
4085 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4086};
4087
4088static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
4089 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304090 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304091 int data_len)
4092{
4093
4094 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4095 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4096
4097 if (0 != wlan_hdd_validate_context(pHddCtx)){
4098 hddLog(VOS_TRACE_LEVEL_ERROR, FL("hdd Ctx invalid while spoof macAddr"));
4099 return -EINVAL;
4100 }
4101 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
4102 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN disabled in ini"));
4103 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304104 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304105 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
4106 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN not supported by FW"));
4107 return -ENOTSUPP;
4108 }
4109
4110 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4111 data, data_len, wlan_hdd_mac_config)) {
4112 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4113 return -EINVAL;
4114 }
4115
4116 /* Parse and fetch mac address */
4117 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4118 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4119 return -EINVAL;
4120 }
4121
4122 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4123 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4124 VOS_MAC_ADDR_LAST_3_BYTES);
4125
Siddharth Bhal76972212014-10-15 16:22:51 +05304126 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4127
4128 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304129 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4130 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304131 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4132 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4133 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4134 {
4135 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4136 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4137 VOS_MAC_ADDRESS_LEN);
4138 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304139 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304140
Siddharth Bhal76972212014-10-15 16:22:51 +05304141 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
4142 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304143 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4144 }
4145
4146 return 0;
4147}
4148
Atul Mittal115287b2014-07-08 13:26:33 +05304149static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4150 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304151 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304152 int data_len)
4153{
4154 u8 peer[6] = {0};
4155 struct net_device *dev = wdev->netdev;
4156 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4157 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4158 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4159 eHalStatus ret;
4160 tANI_S32 state;
4161 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304162 tANI_S32 global_operating_class = 0;
4163 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304164 struct sk_buff *skb = NULL;
4165
4166 ret = wlan_hdd_validate_context(pHddCtx);
4167 if (0 != ret) {
4168
4169 return -EINVAL;
4170 }
4171 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4172
4173 return -ENOTSUPP;
4174 }
4175 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4176 data, data_len,
4177 wlan_hdd_tdls_config_get_status_policy)) {
4178 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4179 return -EINVAL;
4180 }
4181
4182 /* Parse and fetch mac address */
4183 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4184 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4185 return -EINVAL;
4186 }
4187
4188 memcpy(peer, nla_data(
4189 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4190 sizeof(peer));
4191 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4192
4193 ret = wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
4194
4195 if (0 != ret) {
4196 hddLog(VOS_TRACE_LEVEL_ERROR,
4197 FL("get status Failed"));
4198 return -EINVAL;
4199 }
4200 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304201 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304202 NLMSG_HDRLEN);
4203
4204 if (!skb) {
4205 hddLog(VOS_TRACE_LEVEL_ERROR,
4206 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4207 return -EINVAL;
4208 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304209 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 +05304210 reason,
4211 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304212 global_operating_class,
4213 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304214 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304215 if (nla_put_s32(skb,
4216 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4217 state) ||
4218 nla_put_s32(skb,
4219 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4220 reason) ||
4221 nla_put_s32(skb,
4222 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4223 global_operating_class) ||
4224 nla_put_s32(skb,
4225 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4226 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304227
4228 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4229 goto nla_put_failure;
4230 }
4231
4232 return cfg80211_vendor_cmd_reply(skb);
4233
4234nla_put_failure:
4235 kfree_skb(skb);
4236 return -EINVAL;
4237}
4238
4239static int wlan_hdd_cfg80211_exttdls_callback(tANI_U8* mac,
4240 tANI_S32 state,
4241 tANI_S32 reason,
4242 void *ctx)
4243{
4244 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
4245 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4246 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304247 tANI_S32 global_operating_class = 0;
4248 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304249
4250 if (wlan_hdd_validate_context(pHddCtx)) {
4251 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "));
4252 return -EINVAL;
4253 }
4254
4255 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4256
4257 return -ENOTSUPP;
4258 }
4259 skb = cfg80211_vendor_event_alloc(
4260 pHddCtx->wiphy,
4261 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4262 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4263 GFP_KERNEL);
4264
4265 if (!skb) {
4266 hddLog(VOS_TRACE_LEVEL_ERROR,
4267 FL("cfg80211_vendor_event_alloc failed"));
4268 return -EINVAL;
4269 }
4270 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304271 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4272 reason,
4273 state,
4274 global_operating_class,
4275 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304276 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4277 MAC_ADDR_ARRAY(mac));
4278
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304279 if (nla_put(skb,
4280 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4281 VOS_MAC_ADDR_SIZE, mac) ||
4282 nla_put_s32(skb,
4283 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4284 state) ||
4285 nla_put_s32(skb,
4286 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4287 reason) ||
4288 nla_put_s32(skb,
4289 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4290 channel) ||
4291 nla_put_s32(skb,
4292 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4293 global_operating_class)
4294 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304295 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4296 goto nla_put_failure;
4297 }
4298
4299 cfg80211_vendor_event(skb, GFP_KERNEL);
4300 return (0);
4301
4302nla_put_failure:
4303 kfree_skb(skb);
4304 return -EINVAL;
4305}
4306
4307static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4308 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304309 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304310 int data_len)
4311{
4312 u8 peer[6] = {0};
4313 struct net_device *dev = wdev->netdev;
4314 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4315 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4316 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4317 eHalStatus status;
4318 tdls_req_params_t pReqMsg = {0};
4319
4320 status = wlan_hdd_validate_context(pHddCtx);
4321 if (0 != status) {
4322 hddLog(VOS_TRACE_LEVEL_ERROR,
4323 FL("HDD context is not valid"));
4324 return -EINVAL;
4325 }
4326 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4327
4328 return -ENOTSUPP;
4329 }
4330 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4331 data, data_len,
4332 wlan_hdd_tdls_config_enable_policy)) {
4333 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4334 return -EINVAL;
4335 }
4336
4337 /* Parse and fetch mac address */
4338 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4339 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4340 return -EINVAL;
4341 }
4342
4343 memcpy(peer, nla_data(
4344 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4345 sizeof(peer));
4346 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4347
4348 /* Parse and fetch channel */
4349 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4350 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4351 return -EINVAL;
4352 }
4353 pReqMsg.channel = nla_get_s32(
4354 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4355 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4356
4357 /* Parse and fetch global operating class */
4358 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4359 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4360 return -EINVAL;
4361 }
4362 pReqMsg.global_operating_class = nla_get_s32(
4363 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4364 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4365 pReqMsg.global_operating_class);
4366
4367 /* Parse and fetch latency ms */
4368 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4369 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4370 return -EINVAL;
4371 }
4372 pReqMsg.max_latency_ms = nla_get_s32(
4373 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4374 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4375 pReqMsg.max_latency_ms);
4376
4377 /* Parse and fetch required bandwidth kbps */
4378 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4379 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4380 return -EINVAL;
4381 }
4382
4383 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4384 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4385 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4386 pReqMsg.min_bandwidth_kbps);
4387
4388 return (wlan_hdd_tdls_extctrl_config_peer(pAdapter,
4389 peer,
4390 wlan_hdd_cfg80211_exttdls_callback));
4391}
4392
4393static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4394 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304395 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304396 int data_len)
4397{
4398 u8 peer[6] = {0};
4399 struct net_device *dev = wdev->netdev;
4400 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4401 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4402 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4403 eHalStatus status;
4404
4405 status = wlan_hdd_validate_context(pHddCtx);
4406 if (0 != status) {
4407 hddLog(VOS_TRACE_LEVEL_ERROR,
4408 FL("HDD context is not valid"));
4409 return -EINVAL;
4410 }
4411 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4412
4413 return -ENOTSUPP;
4414 }
4415 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4416 data, data_len,
4417 wlan_hdd_tdls_config_disable_policy)) {
4418 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4419 return -EINVAL;
4420 }
4421 /* Parse and fetch mac address */
4422 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4423 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4424 return -EINVAL;
4425 }
4426
4427 memcpy(peer, nla_data(
4428 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4429 sizeof(peer));
4430 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4431
4432 return (wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer));
4433}
4434
Dasari Srinivas7875a302014-09-26 17:50:57 +05304435static int
4436wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
4437 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304438 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05304439{
4440 struct net_device *dev = wdev->netdev;
4441 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4442 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4443 struct sk_buff *skb = NULL;
4444 tANI_U32 fset = 0;
4445
4446 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
4447 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
4448 fset |= WIFI_FEATURE_INFRA;
4449 }
4450
4451 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
4452 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
4453 fset |= WIFI_FEATURE_INFRA_5G;
4454 }
4455
4456#ifdef WLAN_FEATURE_P2P
4457 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
4458 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
4459 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
4460 fset |= WIFI_FEATURE_P2P;
4461 }
4462#endif
4463
4464 /* Soft-AP is supported currently by default */
4465 fset |= WIFI_FEATURE_SOFT_AP;
4466
4467#ifdef WLAN_FEATURE_EXTSCAN
4468 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
4469 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
4470 hddLog(LOG1, FL("EXTScan is supported by firmware"));
4471 fset |= WIFI_FEATURE_EXTSCAN;
4472 }
4473#endif
4474
4475#ifdef WLAN_FEATURE_NAN
4476 if (sme_IsFeatureSupportedByFW(NAN)) {
4477 hddLog(LOG1, FL("NAN is supported by firmware"));
4478 fset |= WIFI_FEATURE_NAN;
4479 }
4480#endif
4481
4482 /* D2D RTT is not supported currently by default */
4483 if (sme_IsFeatureSupportedByFW(RTT)) {
4484 hddLog(LOG1, FL("RTT is supported by firmware"));
4485 fset |= WIFI_FEATURE_D2AP_RTT;
4486 }
4487
4488#ifdef FEATURE_WLAN_BATCH_SCAN
4489 if (fset & WIFI_FEATURE_EXTSCAN) {
4490 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
4491 fset &= ~WIFI_FEATURE_BATCH_SCAN;
4492 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
4493 hddLog(LOG1, FL("Batch scan is supported by firmware"));
4494 fset |= WIFI_FEATURE_BATCH_SCAN;
4495 }
4496#endif
4497
4498#ifdef FEATURE_WLAN_SCAN_PNO
4499 if (pHddCtx->cfg_ini->configPNOScanSupport &&
4500 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
4501 hddLog(LOG1, FL("PNO is supported by firmware"));
4502 fset |= WIFI_FEATURE_PNO;
4503 }
4504#endif
4505
4506 /* STA+STA is supported currently by default */
4507 fset |= WIFI_FEATURE_ADDITIONAL_STA;
4508
4509#ifdef FEATURE_WLAN_TDLS
4510 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
4511 sme_IsFeatureSupportedByFW(TDLS)) {
4512 hddLog(LOG1, FL("TDLS is supported by firmware"));
4513 fset |= WIFI_FEATURE_TDLS;
4514 }
4515
4516 /* TDLS_OFFCHANNEL is not supported currently by default */
4517#endif
4518
4519#ifdef WLAN_AP_STA_CONCURRENCY
4520 /* AP+STA concurrency is supported currently by default */
4521 fset |= WIFI_FEATURE_AP_STA;
4522#endif
4523
4524 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
4525 NLMSG_HDRLEN);
4526
4527 if (!skb) {
4528 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4529 return -EINVAL;
4530 }
4531 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
4532
4533 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
4534 hddLog(LOGE, FL("nla put fail"));
4535 goto nla_put_failure;
4536 }
4537
4538 return cfg80211_vendor_cmd_reply(skb);
4539
4540nla_put_failure:
4541 kfree_skb(skb);
4542 return -EINVAL;
4543}
4544
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304545static int
4546wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
4547 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304548 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304549{
4550 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
4551 uint8_t i, feature_sets, max_feature_sets;
4552 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
4553 struct sk_buff *reply_skb;
4554
4555 ENTER();
4556
4557 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
4558 data, data_len, NULL)) {
4559 hddLog(LOGE, FL("Invalid ATTR"));
4560 return -EINVAL;
4561 }
4562
4563 /* Parse and fetch max feature set */
4564 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
4565 hddLog(LOGE, FL("Attr max feature set size failed"));
4566 return -EINVAL;
4567 }
4568 max_feature_sets = nla_get_u32(
4569 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
4570 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
4571
4572 /* Fill feature combination matrix */
4573 feature_sets = 0;
4574 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4575 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4576 WIFI_FEATURE_P2P;
4577
4578 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4579 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4580 WIFI_FEATURE_SOFT_AP;
4581
4582 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4583 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
4584 WIFI_FEATURE_SOFT_AP;
4585
4586 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4587 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4588 WIFI_FEATURE_SOFT_AP |
4589 WIFI_FEATURE_P2P;
4590
4591 /* Add more feature combinations here */
4592
4593 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
4594 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
4595 hddLog(LOG1, "Feature set matrix");
4596 for (i = 0; i < feature_sets; i++)
4597 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
4598
4599 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4600 sizeof(u32) * feature_sets +
4601 NLMSG_HDRLEN);
4602
4603 if (reply_skb) {
4604 if (nla_put_u32(reply_skb,
4605 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
4606 feature_sets) ||
4607 nla_put(reply_skb,
4608 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
4609 sizeof(u32) * feature_sets, feature_set_matrix)) {
4610 hddLog(LOGE, FL("nla put fail"));
4611 kfree_skb(reply_skb);
4612 return -EINVAL;
4613 }
4614
4615 return cfg80211_vendor_cmd_reply(reply_skb);
4616 }
4617 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
4618 return -ENOMEM;
4619
4620max_buffer_err:
4621 hddLog(LOGE, FL("Feature set max buffer size reached. feature_sets(%d) max(%d)"),
4622 feature_sets, WLAN_HDD_MAX_FEATURE_SET);
4623 return -EINVAL;
4624}
4625
Agarwal Ashish738843c2014-09-25 12:27:56 +05304626static const struct nla_policy
4627wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
4628 +1] =
4629{
4630 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
4631};
4632
4633static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
4634 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304635 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05304636 int data_len)
4637{
4638 struct net_device *dev = wdev->netdev;
4639 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4640 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4641 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4642 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
4643 eHalStatus status;
4644 u32 dfsFlag = 0;
4645
4646 status = wlan_hdd_validate_context(pHddCtx);
4647 if (0 != status) {
4648 hddLog(VOS_TRACE_LEVEL_ERROR,
4649 FL("HDD context is not valid"));
4650 return -EINVAL;
4651 }
4652 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
4653 data, data_len,
4654 wlan_hdd_set_no_dfs_flag_config_policy)) {
4655 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4656 return -EINVAL;
4657 }
4658
4659 /* Parse and fetch required bandwidth kbps */
4660 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
4661 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
4662 return -EINVAL;
4663 }
4664
4665 dfsFlag = nla_get_u32(
4666 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
4667 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
4668 dfsFlag);
4669
4670 pHddCtx->disable_dfs_flag = dfsFlag;
4671
4672 sme_disable_dfs_channel(hHal, dfsFlag);
4673 sme_FilterScanResults(hHal, pAdapter->sessionId);
4674 return 0;
4675}
Atul Mittal115287b2014-07-08 13:26:33 +05304676
Mukul Sharma2a271632014-10-13 14:59:01 +05304677const struct
4678nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
4679{
4680 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
4681 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
4682};
4683
4684static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05304685 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05304686{
4687
4688 u8 bssid[6] = {0};
4689 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4690 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
4691 eHalStatus status = eHAL_STATUS_SUCCESS;
4692 v_U32_t isFwrRoamEnabled = FALSE;
4693 int ret;
4694
4695 if (NULL == pHddCtx) {
4696 hddLog(VOS_TRACE_LEVEL_ERROR,
4697 FL("HDD context is not valid"));
4698 return -EINVAL;
4699 }
4700
4701 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
4702 data, data_len,
4703 qca_wlan_vendor_attr);
4704 if (ret){
4705 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4706 return -EINVAL;
4707 }
4708
4709 /* Parse and fetch Enable flag */
4710 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
4711 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
4712 return -EINVAL;
4713 }
4714
4715 isFwrRoamEnabled = nla_get_u32(
4716 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
4717
4718 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
4719
4720 /* Parse and fetch bssid */
4721 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
4722 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
4723 return -EINVAL;
4724 }
4725
4726 memcpy(bssid, nla_data(
4727 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
4728 sizeof(bssid));
4729 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
4730
4731 //Update roaming
4732 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
4733 return status;
4734}
4735
Sunil Duttc69bccb2014-05-26 21:30:20 +05304736const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
4737{
Mukul Sharma2a271632014-10-13 14:59:01 +05304738 {
4739 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4740 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
4741 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4742 WIPHY_VENDOR_CMD_NEED_NETDEV |
4743 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304744 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05304745 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304746#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4747 {
4748 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4749 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
4750 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4751 WIPHY_VENDOR_CMD_NEED_NETDEV |
4752 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304753 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05304754 },
4755
4756 {
4757 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4758 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
4759 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4760 WIPHY_VENDOR_CMD_NEED_NETDEV |
4761 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304762 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05304763 },
4764
4765 {
4766 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4767 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
4768 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4769 WIPHY_VENDOR_CMD_NEED_NETDEV |
4770 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304771 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05304772 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304773#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304774#ifdef WLAN_FEATURE_EXTSCAN
4775 {
4776 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4777 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
4778 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4779 WIPHY_VENDOR_CMD_NEED_NETDEV |
4780 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304781 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05304782 },
4783 {
4784 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4785 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
4786 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4787 WIPHY_VENDOR_CMD_NEED_NETDEV |
4788 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304789 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05304790 },
4791 {
4792 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4793 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
4794 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4795 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304796 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05304797 },
4798 {
4799 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4800 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
4801 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4802 WIPHY_VENDOR_CMD_NEED_NETDEV |
4803 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304804 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05304805 },
4806 {
4807 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4808 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
4809 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4810 WIPHY_VENDOR_CMD_NEED_NETDEV |
4811 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304812 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05304813 },
4814 {
4815 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4816 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
4817 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4818 WIPHY_VENDOR_CMD_NEED_NETDEV |
4819 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304820 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05304821 },
4822 {
4823 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4824 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
4825 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4826 WIPHY_VENDOR_CMD_NEED_NETDEV |
4827 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304828 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05304829 },
4830 {
4831 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4832 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
4833 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4834 WIPHY_VENDOR_CMD_NEED_NETDEV |
4835 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304836 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05304837 },
4838 {
4839 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4840 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
4841 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4842 WIPHY_VENDOR_CMD_NEED_NETDEV |
4843 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304844 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05304845 },
4846#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304847/*EXT TDLS*/
4848 {
4849 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4850 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
4851 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4852 WIPHY_VENDOR_CMD_NEED_NETDEV |
4853 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304854 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05304855 },
4856 {
4857 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4858 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
4859 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4860 WIPHY_VENDOR_CMD_NEED_NETDEV |
4861 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304862 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05304863 },
4864 {
4865 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4866 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
4867 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4868 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304869 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05304870 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05304871 {
4872 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4873 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
4874 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4875 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304876 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05304877 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05304878 {
4879 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4880 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
4881 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4882 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304883 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05304884 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304885 {
4886 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4887 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
4888 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4889 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304890 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304891 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304892 {
4893 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4894 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
4895 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4896 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304897 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304898 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304899};
4900
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004901/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05304902static const
4903struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004904{
4905#ifdef FEATURE_WLAN_CH_AVOID
4906 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05304907 .vendor_id = QCA_NL80211_VENDOR_ID,
4908 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004909 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304910#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
4911#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4912 {
4913 /* Index = 1*/
4914 .vendor_id = QCA_NL80211_VENDOR_ID,
4915 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
4916 },
4917 {
4918 /* Index = 2*/
4919 .vendor_id = QCA_NL80211_VENDOR_ID,
4920 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
4921 },
4922 {
4923 /* Index = 3*/
4924 .vendor_id = QCA_NL80211_VENDOR_ID,
4925 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
4926 },
4927 {
4928 /* Index = 4*/
4929 .vendor_id = QCA_NL80211_VENDOR_ID,
4930 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
4931 },
4932 {
4933 /* Index = 5*/
4934 .vendor_id = QCA_NL80211_VENDOR_ID,
4935 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
4936 },
4937 {
4938 /* Index = 6*/
4939 .vendor_id = QCA_NL80211_VENDOR_ID,
4940 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
4941 },
4942#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304943#ifdef WLAN_FEATURE_EXTSCAN
4944 {
4945 .vendor_id = QCA_NL80211_VENDOR_ID,
4946 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
4947 },
4948 {
4949 .vendor_id = QCA_NL80211_VENDOR_ID,
4950 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
4951 },
4952 {
4953 .vendor_id = QCA_NL80211_VENDOR_ID,
4954 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
4955 },
4956 {
4957 .vendor_id = QCA_NL80211_VENDOR_ID,
4958 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
4959 },
4960 {
4961 .vendor_id = QCA_NL80211_VENDOR_ID,
4962 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
4963 },
4964 {
4965 .vendor_id = QCA_NL80211_VENDOR_ID,
4966 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
4967 },
4968 {
4969 .vendor_id = QCA_NL80211_VENDOR_ID,
4970 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
4971 },
4972 {
4973 .vendor_id = QCA_NL80211_VENDOR_ID,
4974 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
4975 },
4976 {
4977 .vendor_id = QCA_NL80211_VENDOR_ID,
4978 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
4979 },
4980 {
4981 .vendor_id = QCA_NL80211_VENDOR_ID,
4982 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
4983 },
4984 {
4985 .vendor_id = QCA_NL80211_VENDOR_ID,
4986 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
4987 },
4988 {
4989 .vendor_id = QCA_NL80211_VENDOR_ID,
4990 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
4991 },
4992 {
4993 .vendor_id = QCA_NL80211_VENDOR_ID,
4994 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
4995 },
4996#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304997/*EXT TDLS*/
4998 {
4999 .vendor_id = QCA_NL80211_VENDOR_ID,
5000 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
5001 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005002};
5003
Jeff Johnson295189b2012-06-20 16:38:30 -07005004/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305005 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305006 * This function is called by hdd_wlan_startup()
5007 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305008 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07005009 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305010struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07005011{
5012 struct wiphy *wiphy;
5013 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305014 /*
5015 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07005016 */
5017 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
5018
5019 if (!wiphy)
5020 {
5021 /* Print error and jump into err label and free the memory */
5022 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
5023 return NULL;
5024 }
5025
Sunil Duttc69bccb2014-05-26 21:30:20 +05305026
Jeff Johnson295189b2012-06-20 16:38:30 -07005027 return wiphy;
5028}
5029
5030/*
5031 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305032 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07005033 * private ioctl to change the band value
5034 */
5035int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
5036{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305037 int i, j;
5038 eNVChannelEnabledType channelEnabledState;
5039
Jeff Johnsone7245742012-09-05 17:12:55 -07005040 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305041
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305042 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005043 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305044
5045 if (NULL == wiphy->bands[i])
5046 {
5047 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5048 __func__, i);
5049 continue;
5050 }
5051
5052 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5053 {
5054 struct ieee80211_supported_band *band = wiphy->bands[i];
5055
5056 channelEnabledState = vos_nv_getChannelEnabledState(
5057 band->channels[j].hw_value);
5058
5059 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
5060 {
Abhishek Singh678227a2014-11-04 10:52:38 +05305061 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305062 continue;
5063 }
5064 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
5065 {
5066 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5067 continue;
5068 }
5069
5070 if (NV_CHANNEL_DISABLE == channelEnabledState ||
5071 NV_CHANNEL_INVALID == channelEnabledState)
5072 {
5073 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5074 }
5075 else if (NV_CHANNEL_DFS == channelEnabledState)
5076 {
5077 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5078 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
5079 }
5080 else
5081 {
5082 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
5083 |IEEE80211_CHAN_RADAR);
5084 }
5085 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005086 }
5087 return 0;
5088}
5089/*
5090 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305091 * This function is called by hdd_wlan_startup()
5092 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005093 * This function is used to initialize and register wiphy structure.
5094 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305095int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005096 struct wiphy *wiphy,
5097 hdd_config_t *pCfg
5098 )
5099{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305100 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305101 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5102
Jeff Johnsone7245742012-09-05 17:12:55 -07005103 ENTER();
5104
Jeff Johnson295189b2012-06-20 16:38:30 -07005105 /* Now bind the underlying wlan device with wiphy */
5106 set_wiphy_dev(wiphy, dev);
5107
5108 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005109
Kiet Lam6c583332013-10-14 05:37:09 +05305110#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005111 /* the flag for the other case would be initialzed in
5112 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005113 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305114#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005115
Amar Singhalfddc28c2013-09-05 13:03:40 -07005116 /* This will disable updating of NL channels from passive to
5117 * active if a beacon is received on passive channel. */
5118 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07005119
Amar Singhalfddc28c2013-09-05 13:03:40 -07005120
Amar Singhala49cbc52013-10-08 18:37:44 -07005121
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005122#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005123 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5124 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5125 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005126 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05305127 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005128#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005129
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005130#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005131 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005132#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005133 || pCfg->isFastRoamIniFeatureEnabled
5134#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005135#ifdef FEATURE_WLAN_ESE
5136 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005137#endif
5138 )
5139 {
5140 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5141 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005142#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005143#ifdef FEATURE_WLAN_TDLS
5144 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5145 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5146#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305147#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305148 if (pCfg->configPNOScanSupport)
5149 {
5150 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5151 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5152 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5153 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5154 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305155#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005156
Amar Singhalfddc28c2013-09-05 13:03:40 -07005157#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005158 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5159 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005160 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005161 driver need to determine what to do with both
5162 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005163
5164 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005165#else
5166 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005167#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005168
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305169 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5170
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05305171 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005172
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305173 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5174
Jeff Johnson295189b2012-06-20 16:38:30 -07005175 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305176 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07005177 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07005178 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5179 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005180 | BIT(NL80211_IFTYPE_AP);
5181
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305182 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005183 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305184#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5185 if( pCfg->enableMCC )
5186 {
5187 /* Currently, supports up to two channels */
5188 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005189
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305190 if( !pCfg->allowMCCGODiffBI )
5191 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005192
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305193 }
5194 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5195 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005196#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305197 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005198
Jeff Johnson295189b2012-06-20 16:38:30 -07005199 /* Before registering we need to update the ht capabilitied based
5200 * on ini values*/
5201 if( !pCfg->ShortGI20MhzEnable )
5202 {
5203 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5204 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5205 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5206 }
5207
5208 if( !pCfg->ShortGI40MhzEnable )
5209 {
5210 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5211 }
5212
5213 if( !pCfg->nChannelBondingMode5GHz )
5214 {
5215 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5216 }
5217
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305218 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305219 if (true == hdd_is_5g_supported(pHddCtx))
5220 {
5221 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5222 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305223
5224 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5225 {
5226
5227 if (NULL == wiphy->bands[i])
5228 {
5229 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5230 __func__, i);
5231 continue;
5232 }
5233
5234 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5235 {
5236 struct ieee80211_supported_band *band = wiphy->bands[i];
5237
5238 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5239 {
5240 // Enable social channels for P2P
5241 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5242 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5243 else
5244 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5245 continue;
5246 }
5247 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5248 {
5249 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5250 continue;
5251 }
5252 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005253 }
5254 /*Initialise the supported cipher suite details*/
5255 wiphy->cipher_suites = hdd_cipher_suites;
5256 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5257
5258 /*signal strength in mBm (100*dBm) */
5259 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5260
5261#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305262 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005263#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005264
Sunil Duttc69bccb2014-05-26 21:30:20 +05305265 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
5266 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005267 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
5268 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
5269
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305270 EXIT();
5271 return 0;
5272}
5273
5274/* In this function we are registering wiphy. */
5275int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
5276{
5277 ENTER();
5278 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005279 if (0 > wiphy_register(wiphy))
5280 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305281 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07005282 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
5283 return -EIO;
5284 }
5285
5286 EXIT();
5287 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305288}
Jeff Johnson295189b2012-06-20 16:38:30 -07005289
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305290/* In this function we are updating channel list when,
5291 regulatory domain is FCC and country code is US.
5292 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
5293 As per FCC smart phone is not a indoor device.
5294 GO should not opeate on indoor channels */
5295void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
5296{
5297 int j;
5298 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5299 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
5300 //Default counrtycode from NV at the time of wiphy initialization.
5301 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
5302 &defaultCountryCode[0]))
5303 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005304 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305305 }
5306 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
5307 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305308 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
5309 {
5310 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
5311 return;
5312 }
5313 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
5314 {
5315 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
5316 // Mark UNII -1 band channel as passive
5317 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
5318 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
5319 }
5320 }
5321}
5322
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305323/* This function registers for all frame which supplicant is interested in */
5324void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005325{
Jeff Johnson295189b2012-06-20 16:38:30 -07005326 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5327 /* Register for all P2P action, public action etc frames */
5328 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5329
Jeff Johnsone7245742012-09-05 17:12:55 -07005330 ENTER();
5331
Jeff Johnson295189b2012-06-20 16:38:30 -07005332 /* Right now we are registering these frame when driver is getting
5333 initialized. Once we will move to 2.6.37 kernel, in which we have
5334 frame register ops, we will move this code as a part of that */
5335 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305336 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07005337 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5338
5339 /* GAS Initial Response */
5340 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5341 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305342
Jeff Johnson295189b2012-06-20 16:38:30 -07005343 /* GAS Comeback Request */
5344 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5345 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5346
5347 /* GAS Comeback Response */
5348 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5349 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5350
5351 /* P2P Public Action */
5352 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305353 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005354 P2P_PUBLIC_ACTION_FRAME_SIZE );
5355
5356 /* P2P Action */
5357 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5358 (v_U8_t*)P2P_ACTION_FRAME,
5359 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07005360
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05305361 /* WNM BSS Transition Request frame */
5362 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5363 (v_U8_t*)WNM_BSS_ACTION_FRAME,
5364 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005365
5366 /* WNM-Notification */
5367 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5368 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5369 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005370}
5371
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305372void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005373{
Jeff Johnson295189b2012-06-20 16:38:30 -07005374 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5375 /* Register for all P2P action, public action etc frames */
5376 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5377
Jeff Johnsone7245742012-09-05 17:12:55 -07005378 ENTER();
5379
Jeff Johnson295189b2012-06-20 16:38:30 -07005380 /* Right now we are registering these frame when driver is getting
5381 initialized. Once we will move to 2.6.37 kernel, in which we have
5382 frame register ops, we will move this code as a part of that */
5383 /* GAS Initial Request */
5384
5385 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5386 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5387
5388 /* GAS Initial Response */
5389 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5390 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305391
Jeff Johnson295189b2012-06-20 16:38:30 -07005392 /* GAS Comeback Request */
5393 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5394 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5395
5396 /* GAS Comeback Response */
5397 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5398 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5399
5400 /* P2P Public Action */
5401 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305402 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005403 P2P_PUBLIC_ACTION_FRAME_SIZE );
5404
5405 /* P2P Action */
5406 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5407 (v_U8_t*)P2P_ACTION_FRAME,
5408 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005409 /* WNM-Notification */
5410 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5411 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5412 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005413}
5414
5415#ifdef FEATURE_WLAN_WAPI
5416void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
5417 const u8 *mac_addr, u8 *key , int key_Len)
5418{
5419 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5420 tCsrRoamSetKey setKey;
5421 v_BOOL_t isConnected = TRUE;
5422 int status = 0;
5423 v_U32_t roamId= 0xFF;
5424 tANI_U8 *pKeyPtr = NULL;
5425 int n = 0;
5426
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305427 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
5428 __func__, hdd_device_modetoString(pAdapter->device_mode),
5429 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005430
Gopichand Nakkalae7480202013-02-11 15:24:22 +05305431 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005432 setKey.keyId = key_index; // Store Key ID
5433 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
5434 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
5435 setKey.paeRole = 0 ; // the PAE role
5436 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
5437 {
5438 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
5439 }
5440 else
5441 {
5442 isConnected = hdd_connIsConnected(pHddStaCtx);
5443 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
5444 }
5445 setKey.keyLength = key_Len;
5446 pKeyPtr = setKey.Key;
5447 memcpy( pKeyPtr, key, key_Len);
5448
Arif Hussain6d2a3322013-11-17 19:50:10 -08005449 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005450 __func__, key_Len);
5451 for (n = 0 ; n < key_Len; n++)
5452 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
5453 __func__,n,setKey.Key[n]);
5454
5455 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
5456 if ( isConnected )
5457 {
5458 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
5459 pAdapter->sessionId, &setKey, &roamId );
5460 }
5461 if ( status != 0 )
5462 {
5463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5464 "[%4d] sme_RoamSetKey returned ERROR status= %d",
5465 __LINE__, status );
5466 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
5467 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05305468 /* Need to clear any trace of key value in the memory.
5469 * Thus zero out the memory even though it is local
5470 * variable.
5471 */
5472 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005473}
5474#endif /* FEATURE_WLAN_WAPI*/
5475
5476#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305477int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005478 beacon_data_t **ppBeacon,
5479 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005480#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305481int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005482 beacon_data_t **ppBeacon,
5483 struct cfg80211_beacon_data *params,
5484 int dtim_period)
5485#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305486{
Jeff Johnson295189b2012-06-20 16:38:30 -07005487 int size;
5488 beacon_data_t *beacon = NULL;
5489 beacon_data_t *old = NULL;
5490 int head_len,tail_len;
5491
Jeff Johnsone7245742012-09-05 17:12:55 -07005492 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005493 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305494 {
5495 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5496 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005497 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305498 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005499
5500 old = pAdapter->sessionCtx.ap.beacon;
5501
5502 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305503 {
5504 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5505 FL("session(%d) old and new heads points to NULL"),
5506 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005507 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305508 }
5509
5510 if (params->tail && !params->tail_len)
5511 {
5512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5513 FL("tail_len is zero but tail is not NULL"));
5514 return -EINVAL;
5515 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005516
Jeff Johnson295189b2012-06-20 16:38:30 -07005517#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
5518 /* Kernel 3.0 is not updating dtim_period for set beacon */
5519 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305520 {
5521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5522 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005523 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305524 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005525#endif
5526
5527 if(params->head)
5528 head_len = params->head_len;
5529 else
5530 head_len = old->head_len;
5531
5532 if(params->tail || !old)
5533 tail_len = params->tail_len;
5534 else
5535 tail_len = old->tail_len;
5536
5537 size = sizeof(beacon_data_t) + head_len + tail_len;
5538
5539 beacon = kzalloc(size, GFP_KERNEL);
5540
5541 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305542 {
5543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5544 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005545 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305546 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005547
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005548#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005549 if(params->dtim_period || !old )
5550 beacon->dtim_period = params->dtim_period;
5551 else
5552 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005553#else
5554 if(dtim_period || !old )
5555 beacon->dtim_period = dtim_period;
5556 else
5557 beacon->dtim_period = old->dtim_period;
5558#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305559
Jeff Johnson295189b2012-06-20 16:38:30 -07005560 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
5561 beacon->tail = beacon->head + head_len;
5562 beacon->head_len = head_len;
5563 beacon->tail_len = tail_len;
5564
5565 if(params->head) {
5566 memcpy (beacon->head,params->head,beacon->head_len);
5567 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305568 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07005569 if(old)
5570 memcpy (beacon->head,old->head,beacon->head_len);
5571 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305572
Jeff Johnson295189b2012-06-20 16:38:30 -07005573 if(params->tail) {
5574 memcpy (beacon->tail,params->tail,beacon->tail_len);
5575 }
5576 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305577 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07005578 memcpy (beacon->tail,old->tail,beacon->tail_len);
5579 }
5580
5581 *ppBeacon = beacon;
5582
5583 kfree(old);
5584
5585 return 0;
5586
5587}
Jeff Johnson295189b2012-06-20 16:38:30 -07005588
5589v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
5590{
5591 int left = length;
5592 v_U8_t *ptr = pIes;
5593 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305594
Jeff Johnson295189b2012-06-20 16:38:30 -07005595 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305596 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005597 elem_id = ptr[0];
5598 elem_len = ptr[1];
5599 left -= 2;
5600 if(elem_len > left)
5601 {
5602 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005603 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005604 eid,elem_len,left);
5605 return NULL;
5606 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305607 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005608 {
5609 return ptr;
5610 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305611
Jeff Johnson295189b2012-06-20 16:38:30 -07005612 left -= elem_len;
5613 ptr += (elem_len + 2);
5614 }
5615 return NULL;
5616}
5617
Jeff Johnson295189b2012-06-20 16:38:30 -07005618/* Check if rate is 11g rate or not */
5619static int wlan_hdd_rate_is_11g(u8 rate)
5620{
Sanjay Devnani28322e22013-06-21 16:13:40 -07005621 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005622 u8 i;
5623 for (i = 0; i < 8; i++)
5624 {
5625 if(rate == gRateArray[i])
5626 return TRUE;
5627 }
5628 return FALSE;
5629}
5630
5631/* Check for 11g rate and set proper 11g only mode */
5632static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
5633 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
5634{
5635 u8 i, num_rates = pIe[0];
5636
5637 pIe += 1;
5638 for ( i = 0; i < num_rates; i++)
5639 {
5640 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
5641 {
5642 /* If rate set have 11g rate than change the mode to 11G */
5643 *pSapHw_mode = eSAP_DOT11_MODE_11g;
5644 if (pIe[i] & BASIC_RATE_MASK)
5645 {
5646 /* If we have 11g rate as basic rate, it means mode
5647 is 11g only mode.
5648 */
5649 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
5650 *pCheckRatesfor11g = FALSE;
5651 }
5652 }
5653 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
5654 {
5655 *require_ht = TRUE;
5656 }
5657 }
5658 return;
5659}
5660
5661static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
5662{
5663 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5664 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5665 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5666 u8 checkRatesfor11g = TRUE;
5667 u8 require_ht = FALSE;
5668 u8 *pIe=NULL;
5669
5670 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
5671
5672 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
5673 pBeacon->head_len, WLAN_EID_SUPP_RATES);
5674 if (pIe != NULL)
5675 {
5676 pIe += 1;
5677 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5678 &pConfig->SapHw_mode);
5679 }
5680
5681 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5682 WLAN_EID_EXT_SUPP_RATES);
5683 if (pIe != NULL)
5684 {
5685
5686 pIe += 1;
5687 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5688 &pConfig->SapHw_mode);
5689 }
5690
5691 if( pConfig->channel > 14 )
5692 {
5693 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
5694 }
5695
5696 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5697 WLAN_EID_HT_CAPABILITY);
5698
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305699 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005700 {
5701 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
5702 if(require_ht)
5703 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
5704 }
5705}
5706
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305707static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
5708 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
5709{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005710 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305711 v_U8_t *pIe = NULL;
5712 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5713
5714 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
5715 pBeacon->tail, pBeacon->tail_len);
5716
5717 if (pIe)
5718 {
5719 ielen = pIe[1] + 2;
5720 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5721 {
5722 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
5723 }
5724 else
5725 {
5726 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
5727 return -EINVAL;
5728 }
5729 *total_ielen += ielen;
5730 }
5731 return 0;
5732}
5733
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005734static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
5735 v_U8_t *genie, v_U8_t *total_ielen)
5736{
5737 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5738 int left = pBeacon->tail_len;
5739 v_U8_t *ptr = pBeacon->tail;
5740 v_U8_t elem_id, elem_len;
5741 v_U16_t ielen = 0;
5742
5743 if ( NULL == ptr || 0 == left )
5744 return;
5745
5746 while (left >= 2)
5747 {
5748 elem_id = ptr[0];
5749 elem_len = ptr[1];
5750 left -= 2;
5751 if (elem_len > left)
5752 {
5753 hddLog( VOS_TRACE_LEVEL_ERROR,
5754 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
5755 elem_id, elem_len, left);
5756 return;
5757 }
5758 if (IE_EID_VENDOR == elem_id)
5759 {
5760 /* skipping the VSIE's which we don't want to include or
5761 * it will be included by existing code
5762 */
5763 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
5764#ifdef WLAN_FEATURE_WFD
5765 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
5766#endif
5767 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5768 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5769 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
5770 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5771 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
5772 {
5773 ielen = ptr[1] + 2;
5774 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5775 {
5776 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
5777 *total_ielen += ielen;
5778 }
5779 else
5780 {
5781 hddLog( VOS_TRACE_LEVEL_ERROR,
5782 "IE Length is too big "
5783 "IEs eid=%d elem_len=%d total_ie_lent=%d",
5784 elem_id, elem_len, *total_ielen);
5785 }
5786 }
5787 }
5788
5789 left -= elem_len;
5790 ptr += (elem_len + 2);
5791 }
5792 return;
5793}
5794
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005795#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005796static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5797 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005798#else
5799static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5800 struct cfg80211_beacon_data *params)
5801#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005802{
5803 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305804 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005805 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07005806 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005807
5808 genie = vos_mem_malloc(MAX_GENIE_LEN);
5809
5810 if(genie == NULL) {
5811
5812 return -ENOMEM;
5813 }
5814
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305815 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5816 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005817 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305818 hddLog(LOGE,
5819 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305820 ret = -EINVAL;
5821 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005822 }
5823
5824#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305825 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5826 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
5827 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305828 hddLog(LOGE,
5829 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305830 ret = -EINVAL;
5831 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005832 }
5833#endif
5834
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305835 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5836 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005837 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305838 hddLog(LOGE,
5839 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305840 ret = -EINVAL;
5841 goto done;
5842 }
5843
5844 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
5845 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005846 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07005847 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005848
5849 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5850 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
5851 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
5852 {
5853 hddLog(LOGE,
5854 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005855 ret = -EINVAL;
5856 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005857 }
5858
5859 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5860 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5861 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5862 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5863 ==eHAL_STATUS_FAILURE)
5864 {
5865 hddLog(LOGE,
5866 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005867 ret = -EINVAL;
5868 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005869 }
5870
5871 // Added for ProResp IE
5872 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
5873 {
5874 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
5875 u8 probe_rsp_ie_len[3] = {0};
5876 u8 counter = 0;
5877 /* Check Probe Resp Length if it is greater then 255 then Store
5878 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
5879 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
5880 Store More then 255 bytes into One Variable.
5881 */
5882 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
5883 {
5884 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
5885 {
5886 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
5887 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
5888 }
5889 else
5890 {
5891 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
5892 rem_probe_resp_ie_len = 0;
5893 }
5894 }
5895
5896 rem_probe_resp_ie_len = 0;
5897
5898 if (probe_rsp_ie_len[0] > 0)
5899 {
5900 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5901 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
5902 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5903 probe_rsp_ie_len[0], NULL,
5904 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5905 {
5906 hddLog(LOGE,
5907 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005908 ret = -EINVAL;
5909 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005910 }
5911 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
5912 }
5913
5914 if (probe_rsp_ie_len[1] > 0)
5915 {
5916 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5917 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
5918 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5919 probe_rsp_ie_len[1], NULL,
5920 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5921 {
5922 hddLog(LOGE,
5923 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005924 ret = -EINVAL;
5925 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005926 }
5927 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
5928 }
5929
5930 if (probe_rsp_ie_len[2] > 0)
5931 {
5932 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5933 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
5934 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5935 probe_rsp_ie_len[2], NULL,
5936 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5937 {
5938 hddLog(LOGE,
5939 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005940 ret = -EINVAL;
5941 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005942 }
5943 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
5944 }
5945
5946 if (probe_rsp_ie_len[1] == 0 )
5947 {
5948 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5949 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
5950 eANI_BOOLEAN_FALSE) )
5951 {
5952 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005953 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005954 }
5955 }
5956
5957 if (probe_rsp_ie_len[2] == 0 )
5958 {
5959 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5960 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
5961 eANI_BOOLEAN_FALSE) )
5962 {
5963 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005964 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005965 }
5966 }
5967
5968 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5969 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5970 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5971 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5972 == eHAL_STATUS_FAILURE)
5973 {
5974 hddLog(LOGE,
5975 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005976 ret = -EINVAL;
5977 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005978 }
5979 }
5980 else
5981 {
5982 // Reset WNI_CFG_PROBE_RSP Flags
5983 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
5984
5985 hddLog(VOS_TRACE_LEVEL_INFO,
5986 "%s: No Probe Response IE received in set beacon",
5987 __func__);
5988 }
5989
5990 // Added for AssocResp IE
5991 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
5992 {
5993 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5994 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
5995 params->assocresp_ies_len, NULL,
5996 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5997 {
5998 hddLog(LOGE,
5999 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006000 ret = -EINVAL;
6001 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006002 }
6003
6004 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6005 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
6006 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6007 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6008 == eHAL_STATUS_FAILURE)
6009 {
6010 hddLog(LOGE,
6011 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006012 ret = -EINVAL;
6013 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006014 }
6015 }
6016 else
6017 {
6018 hddLog(VOS_TRACE_LEVEL_INFO,
6019 "%s: No Assoc Response IE received in set beacon",
6020 __func__);
6021
6022 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6023 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6024 eANI_BOOLEAN_FALSE) )
6025 {
6026 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006027 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006028 }
6029 }
6030
Jeff Johnsone7245742012-09-05 17:12:55 -07006031done:
Jeff Johnson295189b2012-06-20 16:38:30 -07006032 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306033 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006034}
Jeff Johnson295189b2012-06-20 16:38:30 -07006035
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306036/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006037 * FUNCTION: wlan_hdd_validate_operation_channel
6038 * called by wlan_hdd_cfg80211_start_bss() and
6039 * wlan_hdd_cfg80211_set_channel()
6040 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306041 * channel list.
6042 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006043VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006044{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306045
Jeff Johnson295189b2012-06-20 16:38:30 -07006046 v_U32_t num_ch = 0;
6047 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6048 u32 indx = 0;
6049 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306050 v_U8_t fValidChannel = FALSE, count = 0;
6051 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306052
Jeff Johnson295189b2012-06-20 16:38:30 -07006053 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6054
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306055 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006056 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306057 /* Validate the channel */
6058 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006059 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306060 if ( channel == rfChannels[count].channelNum )
6061 {
6062 fValidChannel = TRUE;
6063 break;
6064 }
6065 }
6066 if (fValidChannel != TRUE)
6067 {
6068 hddLog(VOS_TRACE_LEVEL_ERROR,
6069 "%s: Invalid Channel [%d]", __func__, channel);
6070 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006071 }
6072 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306073 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006074 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306075 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6076 valid_ch, &num_ch))
6077 {
6078 hddLog(VOS_TRACE_LEVEL_ERROR,
6079 "%s: failed to get valid channel list", __func__);
6080 return VOS_STATUS_E_FAILURE;
6081 }
6082 for (indx = 0; indx < num_ch; indx++)
6083 {
6084 if (channel == valid_ch[indx])
6085 {
6086 break;
6087 }
6088 }
6089
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306090 if (indx >= num_ch)
6091 {
6092 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6093 {
6094 eCsrBand band;
6095 unsigned int freq;
6096
6097 sme_GetFreqBand(hHal, &band);
6098
6099 if (eCSR_BAND_5G == band)
6100 {
6101#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6102 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6103 {
6104 freq = ieee80211_channel_to_frequency(channel,
6105 IEEE80211_BAND_2GHZ);
6106 }
6107 else
6108 {
6109 freq = ieee80211_channel_to_frequency(channel,
6110 IEEE80211_BAND_5GHZ);
6111 }
6112#else
6113 freq = ieee80211_channel_to_frequency(channel);
6114#endif
6115 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6116 return VOS_STATUS_SUCCESS;
6117 }
6118 }
6119
6120 hddLog(VOS_TRACE_LEVEL_ERROR,
6121 "%s: Invalid Channel [%d]", __func__, channel);
6122 return VOS_STATUS_E_FAILURE;
6123 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006124 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306125
Jeff Johnson295189b2012-06-20 16:38:30 -07006126 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306127
Jeff Johnson295189b2012-06-20 16:38:30 -07006128}
6129
Viral Modi3a32cc52013-02-08 11:14:52 -08006130/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306131 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08006132 * This function is used to set the channel number
6133 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306134static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08006135 struct ieee80211_channel *chan,
6136 enum nl80211_channel_type channel_type
6137 )
6138{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306139 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006140 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006141 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006142 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306143 hdd_context_t *pHddCtx;
6144 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006145
6146 ENTER();
6147
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306148
Viral Modi3a32cc52013-02-08 11:14:52 -08006149 if( NULL == dev )
6150 {
6151 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006152 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006153 return -ENODEV;
6154 }
6155 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306156
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306157 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6158 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6159 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006160 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306161 "%s: device_mode = %s (%d) freq = %d", __func__,
6162 hdd_device_modetoString(pAdapter->device_mode),
6163 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306164
6165 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6166 status = wlan_hdd_validate_context(pHddCtx);
6167
6168 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006169 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6171 "%s: HDD context is not valid", __func__);
6172 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006173 }
6174
6175 /*
6176 * Do freq to chan conversion
6177 * TODO: for 11a
6178 */
6179
6180 channel = ieee80211_frequency_to_channel(freq);
6181
6182 /* Check freq range */
6183 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6184 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6185 {
6186 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006187 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006188 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6189 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6190 return -EINVAL;
6191 }
6192
6193 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6194
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306195 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6196 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006197 {
6198 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6199 {
6200 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006201 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006202 return -EINVAL;
6203 }
6204 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6205 "%s: set channel to [%d] for device mode =%d",
6206 __func__, channel,pAdapter->device_mode);
6207 }
6208 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006209 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006210 )
6211 {
6212 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6213 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6214 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6215
6216 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6217 {
6218 /* Link is up then return cant set channel*/
6219 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006220 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006221 return -EINVAL;
6222 }
6223
6224 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6225 pHddStaCtx->conn_info.operationChannel = channel;
6226 pRoamProfile->ChannelInfo.ChannelList =
6227 &pHddStaCtx->conn_info.operationChannel;
6228 }
6229 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006230 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006231 )
6232 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306233 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6234 {
6235 if(VOS_STATUS_SUCCESS !=
6236 wlan_hdd_validate_operation_channel(pAdapter,channel))
6237 {
6238 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006239 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306240 return -EINVAL;
6241 }
6242 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6243 }
6244 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006245 {
6246 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6247
6248 /* If auto channel selection is configured as enable/ 1 then ignore
6249 channel set by supplicant
6250 */
6251 if ( cfg_param->apAutoChannelSelection )
6252 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306253 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6254 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006255 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306256 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6257 __func__, hdd_device_modetoString(pAdapter->device_mode),
6258 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006259 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306260 else
6261 {
6262 if(VOS_STATUS_SUCCESS !=
6263 wlan_hdd_validate_operation_channel(pAdapter,channel))
6264 {
6265 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006266 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306267 return -EINVAL;
6268 }
6269 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6270 }
Viral Modi3a32cc52013-02-08 11:14:52 -08006271 }
6272 }
6273 else
6274 {
6275 hddLog(VOS_TRACE_LEVEL_FATAL,
6276 "%s: Invalid device mode failed to set valid channel", __func__);
6277 return -EINVAL;
6278 }
6279 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306280 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006281}
6282
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306283static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
6284 struct net_device *dev,
6285 struct ieee80211_channel *chan,
6286 enum nl80211_channel_type channel_type
6287 )
6288{
6289 int ret;
6290
6291 vos_ssr_protect(__func__);
6292 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
6293 vos_ssr_unprotect(__func__);
6294
6295 return ret;
6296}
6297
Jeff Johnson295189b2012-06-20 16:38:30 -07006298#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6299static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6300 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006301#else
6302static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6303 struct cfg80211_beacon_data *params,
6304 const u8 *ssid, size_t ssid_len,
6305 enum nl80211_hidden_ssid hidden_ssid)
6306#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006307{
6308 tsap_Config_t *pConfig;
6309 beacon_data_t *pBeacon = NULL;
6310 struct ieee80211_mgmt *pMgmt_frame;
6311 v_U8_t *pIe=NULL;
6312 v_U16_t capab_info;
6313 eCsrAuthType RSNAuthType;
6314 eCsrEncryptionType RSNEncryptType;
6315 eCsrEncryptionType mcRSNEncryptType;
6316 int status = VOS_STATUS_SUCCESS;
6317 tpWLAN_SAPEventCB pSapEventCallback;
6318 hdd_hostapd_state_t *pHostapdState;
6319 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
6320 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306321 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006322 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306323 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07006324 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08006325 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05306326 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07006327 v_BOOL_t MFPCapable = VOS_FALSE;
6328 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306329 eHddDot11Mode sapDot11Mode =
6330 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07006331
6332 ENTER();
6333
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306334 iniConfig = pHddCtx->cfg_ini;
6335
Jeff Johnson295189b2012-06-20 16:38:30 -07006336 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
6337
6338 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6339
6340 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6341
6342 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6343
6344 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
6345
6346 //channel is already set in the set_channel Call back
6347 //pConfig->channel = pCommitConfig->channel;
6348
6349 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306350 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07006351 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
6352
6353 pConfig->dtim_period = pBeacon->dtim_period;
6354
Arif Hussain6d2a3322013-11-17 19:50:10 -08006355 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07006356 pConfig->dtim_period);
6357
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08006358 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07006359 {
6360 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006361 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05306362 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
6363 {
6364 tANI_BOOLEAN restartNeeded;
6365 pConfig->ieee80211d = 1;
6366 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
6367 sme_setRegInfo(hHal, pConfig->countryCode);
6368 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
6369 }
6370 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006371 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07006372 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07006373 pConfig->ieee80211d = 1;
6374 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
6375 sme_setRegInfo(hHal, pConfig->countryCode);
6376 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07006377 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006378 else
6379 {
6380 pConfig->ieee80211d = 0;
6381 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306382 /*
6383 * If auto channel is configured i.e. channel is 0,
6384 * so skip channel validation.
6385 */
6386 if( AUTO_CHANNEL_SELECT != pConfig->channel )
6387 {
6388 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
6389 {
6390 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006391 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306392 return -EINVAL;
6393 }
6394 }
6395 else
6396 {
6397 if(1 != pHddCtx->is_dynamic_channel_range_set)
6398 {
6399 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
6400 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
6401 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
6402 }
6403 pHddCtx->is_dynamic_channel_range_set = 0;
6404 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006405 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006406 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006407 {
6408 pConfig->ieee80211d = 0;
6409 }
6410 pConfig->authType = eSAP_AUTO_SWITCH;
6411
6412 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306413
6414 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07006415 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
6416
6417 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
6418
6419 /*Set wps station to configured*/
6420 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
6421
6422 if(pIe)
6423 {
6424 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
6425 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006426 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07006427 return -EINVAL;
6428 }
6429 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
6430 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006431 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07006432 /* Check 15 bit of WPS IE as it contain information for wps state
6433 * WPS state
6434 */
6435 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
6436 {
6437 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
6438 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
6439 {
6440 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
6441 }
6442 }
6443 }
6444 else
6445 {
6446 pConfig->wps_state = SAP_WPS_DISABLED;
6447 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306448 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07006449
c_hpothufe599e92014-06-16 11:38:55 +05306450 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6451 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6452 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
6453 eCSR_ENCRYPT_TYPE_NONE;
6454
Jeff Johnson295189b2012-06-20 16:38:30 -07006455 pConfig->RSNWPAReqIELength = 0;
6456 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306457 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006458 WLAN_EID_RSN);
6459 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306460 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006461 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6462 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6463 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306464 /* The actual processing may eventually be more extensive than
6465 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07006466 * by the app.
6467 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306468 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006469 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6470 &RSNEncryptType,
6471 &mcRSNEncryptType,
6472 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006473 &MFPCapable,
6474 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006475 pConfig->pRSNWPAReqIE[1]+2,
6476 pConfig->pRSNWPAReqIE );
6477
6478 if( VOS_STATUS_SUCCESS == status )
6479 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306480 /* Now copy over all the security attributes you have
6481 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006482 * */
6483 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6484 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6485 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6486 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306487 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006488 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006489 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6490 }
6491 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306492
Jeff Johnson295189b2012-06-20 16:38:30 -07006493 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6494 pBeacon->tail, pBeacon->tail_len);
6495
6496 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
6497 {
6498 if (pConfig->pRSNWPAReqIE)
6499 {
6500 /*Mixed mode WPA/WPA2*/
6501 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
6502 pConfig->RSNWPAReqIELength += pIe[1] + 2;
6503 }
6504 else
6505 {
6506 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6507 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6508 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306509 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006510 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6511 &RSNEncryptType,
6512 &mcRSNEncryptType,
6513 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006514 &MFPCapable,
6515 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006516 pConfig->pRSNWPAReqIE[1]+2,
6517 pConfig->pRSNWPAReqIE );
6518
6519 if( VOS_STATUS_SUCCESS == status )
6520 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306521 /* Now copy over all the security attributes you have
6522 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006523 * */
6524 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6525 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6526 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6527 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306528 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006529 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006530 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6531 }
6532 }
6533 }
6534
Jeff Johnson4416a782013-03-25 14:17:50 -07006535 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
6536 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
6537 return -EINVAL;
6538 }
6539
Jeff Johnson295189b2012-06-20 16:38:30 -07006540 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
6541
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006542#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006543 if (params->ssid != NULL)
6544 {
6545 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
6546 pConfig->SSIDinfo.ssid.length = params->ssid_len;
6547 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6548 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6549 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006550#else
6551 if (ssid != NULL)
6552 {
6553 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
6554 pConfig->SSIDinfo.ssid.length = ssid_len;
6555 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6556 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6557 }
6558#endif
6559
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306560 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07006561 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306562
Jeff Johnson295189b2012-06-20 16:38:30 -07006563 /* default value */
6564 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
6565 pConfig->num_accept_mac = 0;
6566 pConfig->num_deny_mac = 0;
6567
6568 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6569 pBeacon->tail, pBeacon->tail_len);
6570
6571 /* pIe for black list is following form:
6572 type : 1 byte
6573 length : 1 byte
6574 OUI : 4 bytes
6575 acl type : 1 byte
6576 no of mac addr in black list: 1 byte
6577 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306578 */
6579 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006580 {
6581 pConfig->SapMacaddr_acl = pIe[6];
6582 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006583 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006584 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306585 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
6586 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006587 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6588 for (i = 0; i < pConfig->num_deny_mac; i++)
6589 {
6590 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6591 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306592 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006593 }
6594 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6595 pBeacon->tail, pBeacon->tail_len);
6596
6597 /* pIe for white list is following form:
6598 type : 1 byte
6599 length : 1 byte
6600 OUI : 4 bytes
6601 acl type : 1 byte
6602 no of mac addr in white list: 1 byte
6603 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306604 */
6605 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006606 {
6607 pConfig->SapMacaddr_acl = pIe[6];
6608 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006609 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006610 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306611 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
6612 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006613 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6614 for (i = 0; i < pConfig->num_accept_mac; i++)
6615 {
6616 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6617 acl_entry++;
6618 }
6619 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306620
Jeff Johnson295189b2012-06-20 16:38:30 -07006621 wlan_hdd_set_sapHwmode(pHostapdAdapter);
6622
Jeff Johnsone7245742012-09-05 17:12:55 -07006623#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006624 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05306625 * This is valid only if mode is set to 11n in hostapd, either AUTO or
6626 * 11ac in .ini and 11ac is supported by both host and firmware.
6627 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
6628 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006629 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
6630 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306631 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
6632 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
6633 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
6634 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
6635 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07006636 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306637 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07006638 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306639 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006640
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306641 /* If ACS disable and selected channel <= 14
6642 * OR
6643 * ACS enabled and ACS operating band is choosen as 2.4
6644 * AND
6645 * VHT in 2.4G Disabled
6646 * THEN
6647 * Fallback to 11N mode
6648 */
6649 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
6650 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05306651 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306652 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006653 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306654 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
6655 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006656 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
6657 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006658 }
6659#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306660
Jeff Johnson295189b2012-06-20 16:38:30 -07006661 // ht_capab is not what the name conveys,this is used for protection bitmap
6662 pConfig->ht_capab =
6663 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
6664
6665 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
6666 {
6667 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
6668 return -EINVAL;
6669 }
6670
6671 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306672 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07006673 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
6674 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306675 pConfig->obssProtEnabled =
6676 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07006677
Chet Lanctot8cecea22014-02-11 19:09:36 -08006678#ifdef WLAN_FEATURE_11W
6679 pConfig->mfpCapable = MFPCapable;
6680 pConfig->mfpRequired = MFPRequired;
6681 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
6682 pConfig->mfpCapable, pConfig->mfpRequired);
6683#endif
6684
Arif Hussain6d2a3322013-11-17 19:50:10 -08006685 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07006686 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006687 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
6688 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
6689 (int)pConfig->channel);
6690 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
6691 pConfig->SapHw_mode, pConfig->privacy,
6692 pConfig->authType);
6693 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
6694 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
6695 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
6696 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07006697
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306698 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006699 {
6700 //Bss already started. just return.
6701 //TODO Probably it should update some beacon params.
6702 hddLog( LOGE, "Bss Already started...Ignore the request");
6703 EXIT();
6704 return 0;
6705 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306706
Agarwal Ashish51325b52014-06-16 16:50:49 +05306707 if (vos_max_concurrent_connections_reached()) {
6708 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6709 return -EINVAL;
6710 }
6711
Jeff Johnson295189b2012-06-20 16:38:30 -07006712 pConfig->persona = pHostapdAdapter->device_mode;
6713
Peng Xu2446a892014-09-05 17:21:18 +05306714 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
6715 if ( NULL != psmeConfig)
6716 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05306717 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05306718 sme_GetConfigParam(hHal, psmeConfig);
6719 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05306720#ifdef WLAN_FEATURE_AP_HT40_24G
6721 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
6722 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
6723 && pHddCtx->cfg_ini->apHT40_24GEnabled)
6724 {
6725 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
6726 sme_UpdateConfig (hHal, psmeConfig);
6727 }
6728#endif
Peng Xu2446a892014-09-05 17:21:18 +05306729 vos_mem_free(psmeConfig);
6730 }
Peng Xuafc34e32014-09-25 13:23:55 +05306731 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05306732
Jeff Johnson295189b2012-06-20 16:38:30 -07006733 pSapEventCallback = hdd_hostapd_SAPEventCB;
6734 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
6735 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
6736 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006737 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006738 return -EINVAL;
6739 }
6740
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306741 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07006742 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
6743
6744 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306745
Jeff Johnson295189b2012-06-20 16:38:30 -07006746 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306747 {
6748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006749 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07006750 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07006751 VOS_ASSERT(0);
6752 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306753
Jeff Johnson295189b2012-06-20 16:38:30 -07006754 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05306755 /* Initialize WMM configuation */
6756 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306757 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006758
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006759#ifdef WLAN_FEATURE_P2P_DEBUG
6760 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
6761 {
6762 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
6763 {
6764 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6765 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006766 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006767 }
6768 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
6769 {
6770 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6771 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006772 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006773 }
6774 }
6775#endif
6776
Jeff Johnson295189b2012-06-20 16:38:30 -07006777 pHostapdState->bCommit = TRUE;
6778 EXIT();
6779
6780 return 0;
6781}
6782
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006783#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05306784static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306785 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006786 struct beacon_parameters *params)
6787{
6788 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306789 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306790 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006791
6792 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306793
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306794 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6795 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
6796 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306797 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
6798 hdd_device_modetoString(pAdapter->device_mode),
6799 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006800
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306801 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6802 status = wlan_hdd_validate_context(pHddCtx);
6803
6804 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006805 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6807 "%s: HDD context is not valid", __func__);
6808 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006809 }
6810
Agarwal Ashish51325b52014-06-16 16:50:49 +05306811 if (vos_max_concurrent_connections_reached()) {
6812 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6813 return -EINVAL;
6814 }
6815
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306816 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006817 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006818 )
6819 {
6820 beacon_data_t *old,*new;
6821
6822 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306823
Jeff Johnson295189b2012-06-20 16:38:30 -07006824 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306825 {
6826 hddLog(VOS_TRACE_LEVEL_WARN,
6827 FL("already beacon info added to session(%d)"),
6828 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006829 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306830 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006831
6832 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6833
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306834 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07006835 {
6836 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006837 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006838 return -EINVAL;
6839 }
6840
6841 pAdapter->sessionCtx.ap.beacon = new;
6842
6843 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6844 }
6845
6846 EXIT();
6847 return status;
6848}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306849
Mukul Sharmab0e0a982014-12-15 18:58:53 +05306850static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
6851 struct net_device *dev,
6852 struct beacon_parameters *params)
6853{
6854 int ret;
6855
6856 vos_ssr_protect(__func__);
6857 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
6858 vos_ssr_unprotect(__func__);
6859
6860 return ret;
6861}
6862
6863static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006864 struct net_device *dev,
6865 struct beacon_parameters *params)
6866{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306867 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306868 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6869 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306870 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006871
6872 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306873 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6874 TRACE_CODE_HDD_CFG80211_SET_BEACON,
6875 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
6876 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6877 __func__, hdd_device_modetoString(pAdapter->device_mode),
6878 pAdapter->device_mode);
6879
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306880 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6881 status = wlan_hdd_validate_context(pHddCtx);
6882
6883 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006884 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6886 "%s: HDD context is not valid", __func__);
6887 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006888 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306889
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306890 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006891 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306892 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006893 {
6894 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306895
Jeff Johnson295189b2012-06-20 16:38:30 -07006896 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306897
Jeff Johnson295189b2012-06-20 16:38:30 -07006898 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306899 {
6900 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6901 FL("session(%d) old and new heads points to NULL"),
6902 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006903 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306904 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006905
6906 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6907
6908 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306909 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006910 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006911 return -EINVAL;
6912 }
6913
6914 pAdapter->sessionCtx.ap.beacon = new;
6915
6916 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6917 }
6918
6919 EXIT();
6920 return status;
6921}
6922
Mukul Sharmab0e0a982014-12-15 18:58:53 +05306923static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
6924 struct net_device *dev,
6925 struct beacon_parameters *params)
6926{
6927 int ret;
6928
6929 vos_ssr_protect(__func__);
6930 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
6931 vos_ssr_unprotect(__func__);
6932
6933 return ret;
6934}
6935
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006936#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6937
6938#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05306939static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006940 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006941#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05306942static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006943 struct net_device *dev)
6944#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006945{
6946 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07006947 hdd_context_t *pHddCtx = NULL;
6948 hdd_scaninfo_t *pScanInfo = NULL;
6949 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306950 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306951 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006952
6953 ENTER();
6954
6955 if (NULL == pAdapter)
6956 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006958 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006959 return -ENODEV;
6960 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006961
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306962 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6963 TRACE_CODE_HDD_CFG80211_STOP_AP,
6964 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306965 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6966 status = wlan_hdd_validate_context(pHddCtx);
6967
6968 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006969 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306970 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6971 "%s: HDD context is not valid", __func__);
6972 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07006973 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006974
6975 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
6976 if (NULL == staAdapter)
6977 {
6978 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
6979 if (NULL == staAdapter)
6980 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07006981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6982 "%s: HDD adapter context for STA/P2P-CLI is Null",
6983 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006984 }
6985 }
6986
6987 pScanInfo = &pHddCtx->scan_info;
6988
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306989 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6990 __func__, hdd_device_modetoString(pAdapter->device_mode),
6991 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006992
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306993 ret = wlan_hdd_scan_abort(pAdapter);
6994
Girish Gowli4bf7a632014-06-12 13:42:11 +05306995 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07006996 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306997 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6998 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306999
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307000 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07007001 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307002 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7003 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08007004
Jeff Johnsone7245742012-09-05 17:12:55 -07007005 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307006 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07007007 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307008 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07007009 }
7010
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05307011 /* Delete all associated STAs before stopping AP/P2P GO */
7012 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05307013 hdd_hostapd_stop(dev);
7014
Jeff Johnson295189b2012-06-20 16:38:30 -07007015 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007016 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007017 )
7018 {
7019 beacon_data_t *old;
7020
7021 old = pAdapter->sessionCtx.ap.beacon;
7022
7023 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307024 {
7025 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7026 FL("session(%d) beacon data points to NULL"),
7027 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007028 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307029 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007030
Jeff Johnson295189b2012-06-20 16:38:30 -07007031 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007032
7033 mutex_lock(&pHddCtx->sap_lock);
7034 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7035 {
Jeff Johnson4416a782013-03-25 14:17:50 -07007036 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007037 {
7038 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7039
7040 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7041
7042 if (!VOS_IS_STATUS_SUCCESS(status))
7043 {
7044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007045 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007046 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307047 }
7048 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007049 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307050 /* BSS stopped, clear the active sessions for this device mode */
7051 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007052 }
7053 mutex_unlock(&pHddCtx->sap_lock);
7054
7055 if(status != VOS_STATUS_SUCCESS)
7056 {
7057 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007058 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007059 return -EINVAL;
7060 }
7061
Jeff Johnson4416a782013-03-25 14:17:50 -07007062 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007063 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
7064 ==eHAL_STATUS_FAILURE)
7065 {
7066 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007067 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007068 }
7069
Jeff Johnson4416a782013-03-25 14:17:50 -07007070 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007071 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7072 eANI_BOOLEAN_FALSE) )
7073 {
7074 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007075 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007076 }
7077
7078 // Reset WNI_CFG_PROBE_RSP Flags
7079 wlan_hdd_reset_prob_rspies(pAdapter);
7080
7081 pAdapter->sessionCtx.ap.beacon = NULL;
7082 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007083#ifdef WLAN_FEATURE_P2P_DEBUG
7084 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7085 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
7086 {
7087 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
7088 "GO got removed");
7089 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
7090 }
7091#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007092 }
7093 EXIT();
7094 return status;
7095}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007096
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307097#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7098static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
7099 struct net_device *dev)
7100{
7101 int ret;
7102
7103 vos_ssr_protect(__func__);
7104 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
7105 vos_ssr_unprotect(__func__);
7106
7107 return ret;
7108}
7109#else
7110static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7111 struct net_device *dev)
7112{
7113 int ret;
7114
7115 vos_ssr_protect(__func__);
7116 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7117 vos_ssr_unprotect(__func__);
7118
7119 return ret;
7120}
7121#endif
7122
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007123#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7124
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307125static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307126 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007127 struct cfg80211_ap_settings *params)
7128{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307129 hdd_adapter_t *pAdapter;
7130 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307131 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007132
7133 ENTER();
7134
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307135 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007136 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307137 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307138 "%s: Device is Null", __func__);
7139 return -ENODEV;
7140 }
7141
7142 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7143 if (NULL == pAdapter)
7144 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307145 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307146 "%s: HDD adapter is Null", __func__);
7147 return -ENODEV;
7148 }
7149
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307150 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7151 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
7152 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307153 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7154 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307156 "%s: HDD adapter magic is invalid", __func__);
7157 return -ENODEV;
7158 }
7159
7160 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307161 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307162
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307163 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307164 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307165 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7166 "%s: HDD context is not valid", __func__);
7167 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307168 }
7169
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307170 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7171 __func__, hdd_device_modetoString(pAdapter->device_mode),
7172 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307173
7174 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007175 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007176 )
7177 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307178 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007179
7180 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307181
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007182 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307183 {
7184 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7185 FL("already beacon info added to session(%d)"),
7186 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007187 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307188 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007189
7190 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
7191
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307192 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007193 {
7194 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307195 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007196 return -EINVAL;
7197 }
7198 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007199#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007200 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7201#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7202 params->channel, params->channel_type);
7203#else
7204 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7205#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007206#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007207 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
7208 params->ssid_len, params->hidden_ssid);
7209 }
7210
7211 EXIT();
7212 return status;
7213}
7214
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307215static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7216 struct net_device *dev,
7217 struct cfg80211_ap_settings *params)
7218{
7219 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007220
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307221 vos_ssr_protect(__func__);
7222 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
7223 vos_ssr_unprotect(__func__);
7224
7225 return ret;
7226}
7227
7228static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007229 struct net_device *dev,
7230 struct cfg80211_beacon_data *params)
7231{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307232 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307233 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307234 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007235
7236 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307237
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307238 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7239 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7240 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007241 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007242 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307243
7244 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7245 status = wlan_hdd_validate_context(pHddCtx);
7246
7247 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007248 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7250 "%s: HDD context is not valid", __func__);
7251 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007252 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007253
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307254 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007255 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307256 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007257 {
7258 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307259
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007260 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307261
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007262 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307263 {
7264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7265 FL("session(%d) beacon data points to NULL"),
7266 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007267 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307268 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007269
7270 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
7271
7272 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307273 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007274 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007275 return -EINVAL;
7276 }
7277
7278 pAdapter->sessionCtx.ap.beacon = new;
7279
7280 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
7281 }
7282
7283 EXIT();
7284 return status;
7285}
7286
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307287static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
7288 struct net_device *dev,
7289 struct cfg80211_beacon_data *params)
7290{
7291 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007292
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307293 vos_ssr_protect(__func__);
7294 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
7295 vos_ssr_unprotect(__func__);
7296
7297 return ret;
7298}
7299
7300#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007301
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307302static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007303 struct net_device *dev,
7304 struct bss_parameters *params)
7305{
7306 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307307 hdd_context_t *pHddCtx;
7308 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007309
7310 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307311
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307312 if (NULL == pAdapter)
7313 {
7314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7315 "%s: HDD adapter is Null", __func__);
7316 return -ENODEV;
7317 }
7318 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7319
7320 ret = wlan_hdd_validate_context(pHddCtx);
7321 if (0 != ret)
7322 {
7323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7324 "%s: HDD context is not valid", __func__);
7325 return ret;
7326 }
7327
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307328 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7329 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
7330 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307331 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7332 __func__, hdd_device_modetoString(pAdapter->device_mode),
7333 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007334
7335 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007336 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307337 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007338 {
7339 /* ap_isolate == -1 means that in change bss, upper layer doesn't
7340 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307341 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07007342 {
7343 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307344 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007345 }
7346
7347 EXIT();
7348 return 0;
7349}
7350
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307351static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
7352 struct net_device *dev,
7353 struct bss_parameters *params)
7354{
7355 int ret;
7356
7357 vos_ssr_protect(__func__);
7358 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
7359 vos_ssr_unprotect(__func__);
7360
7361 return ret;
7362}
Kiet Lam10841362013-11-01 11:36:50 +05307363/* FUNCTION: wlan_hdd_change_country_code_cd
7364* to wait for contry code completion
7365*/
7366void* wlan_hdd_change_country_code_cb(void *pAdapter)
7367{
7368 hdd_adapter_t *call_back_pAdapter = pAdapter;
7369 complete(&call_back_pAdapter->change_country_code);
7370 return NULL;
7371}
7372
Jeff Johnson295189b2012-06-20 16:38:30 -07007373/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307374 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07007375 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
7376 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307377int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007378 struct net_device *ndev,
7379 enum nl80211_iftype type,
7380 u32 *flags,
7381 struct vif_params *params
7382 )
7383{
7384 struct wireless_dev *wdev;
7385 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007386 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07007387 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007388 tCsrRoamProfile *pRoamProfile = NULL;
7389 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307390 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007391 eMib_dot11DesiredBssType connectedBssType;
7392 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307393 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007394
7395 ENTER();
7396
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307397 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007398 {
7399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7400 "%s: Adapter context is null", __func__);
7401 return VOS_STATUS_E_FAILURE;
7402 }
7403
7404 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7405 if (!pHddCtx)
7406 {
7407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7408 "%s: HDD context is null", __func__);
7409 return VOS_STATUS_E_FAILURE;
7410 }
7411
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307412 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7413 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
7414 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307415 status = wlan_hdd_validate_context(pHddCtx);
7416
7417 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007418 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307419 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7420 "%s: HDD context is not valid", __func__);
7421 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007422 }
7423
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307424 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7425 __func__, hdd_device_modetoString(pAdapter->device_mode),
7426 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007427
Agarwal Ashish51325b52014-06-16 16:50:49 +05307428 if (vos_max_concurrent_connections_reached()) {
7429 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7430 return -EINVAL;
7431 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307432 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007433 wdev = ndev->ieee80211_ptr;
7434
7435#ifdef WLAN_BTAMP_FEATURE
7436 if((NL80211_IFTYPE_P2P_CLIENT == type)||
7437 (NL80211_IFTYPE_ADHOC == type)||
7438 (NL80211_IFTYPE_AP == type)||
7439 (NL80211_IFTYPE_P2P_GO == type))
7440 {
7441 pHddCtx->isAmpAllowed = VOS_FALSE;
7442 // stop AMP traffic
7443 status = WLANBAP_StopAmp();
7444 if(VOS_STATUS_SUCCESS != status )
7445 {
7446 pHddCtx->isAmpAllowed = VOS_TRUE;
7447 hddLog(VOS_TRACE_LEVEL_FATAL,
7448 "%s: Failed to stop AMP", __func__);
7449 return -EINVAL;
7450 }
7451 }
7452#endif //WLAN_BTAMP_FEATURE
7453 /* Reset the current device mode bit mask*/
7454 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7455
7456 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007457 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07007458 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07007459 )
7460 {
7461 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007462 if (!pWextState)
7463 {
7464 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7465 "%s: pWextState is null", __func__);
7466 return VOS_STATUS_E_FAILURE;
7467 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007468 pRoamProfile = &pWextState->roamProfile;
7469 LastBSSType = pRoamProfile->BSSType;
7470
7471 switch (type)
7472 {
7473 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007474 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007475 hddLog(VOS_TRACE_LEVEL_INFO,
7476 "%s: setting interface Type to INFRASTRUCTURE", __func__);
7477 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07007478#ifdef WLAN_FEATURE_11AC
7479 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
7480 {
7481 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
7482 }
7483#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307484 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07007485 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007486 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007487 //Check for sub-string p2p to confirm its a p2p interface
7488 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307489 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007490 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7491 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7492 }
7493 else
7494 {
7495 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007496 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007497 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007498 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05307499
Jeff Johnson295189b2012-06-20 16:38:30 -07007500 case NL80211_IFTYPE_ADHOC:
7501 hddLog(VOS_TRACE_LEVEL_INFO,
7502 "%s: setting interface Type to ADHOC", __func__);
7503 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
7504 pRoamProfile->phyMode =
7505 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07007506 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007507 wdev->iftype = type;
7508 break;
7509
7510 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007511 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007512 {
7513 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7514 "%s: setting interface Type to %s", __func__,
7515 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
7516
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007517 //Cancel any remain on channel for GO mode
7518 if (NL80211_IFTYPE_P2P_GO == type)
7519 {
7520 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
7521 }
Mohit Khanna0f232092012-09-11 14:46:08 -07007522 if (NL80211_IFTYPE_AP == type)
7523 {
7524 /* As Loading WLAN Driver one interface being created for p2p device
7525 * address. This will take one HW STA and the max number of clients
7526 * that can connect to softAP will be reduced by one. so while changing
7527 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
7528 * interface as it is not required in SoftAP mode.
7529 */
7530
7531 // Get P2P Adapter
7532 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
7533
7534 if (pP2pAdapter)
7535 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307536 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07007537 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
7538 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
7539 }
7540 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05307541 //Disable IMPS & BMPS for SAP/GO
7542 if(VOS_STATUS_E_FAILURE ==
7543 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
7544 {
7545 //Fail to Exit BMPS
7546 VOS_ASSERT(0);
7547 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05307548
7549 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
7550
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307551#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07007552
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307553 /* A Mutex Lock is introduced while changing the mode to
7554 * protect the concurrent access for the Adapters by TDLS
7555 * module.
7556 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307557 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307558#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007559 //De-init the adapter.
Jeff Johnson295189b2012-06-20 16:38:30 -07007560 hdd_deinit_adapter( pHddCtx, pAdapter );
7561 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07007562 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7563 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307564#ifdef FEATURE_WLAN_TDLS
7565 mutex_unlock(&pHddCtx->tdls_lock);
7566#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007567 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
7568 (pConfig->apRandomBssidEnabled))
7569 {
7570 /* To meet Android requirements create a randomized
7571 MAC address of the form 02:1A:11:Fx:xx:xx */
7572 get_random_bytes(&ndev->dev_addr[3], 3);
7573 ndev->dev_addr[0] = 0x02;
7574 ndev->dev_addr[1] = 0x1A;
7575 ndev->dev_addr[2] = 0x11;
7576 ndev->dev_addr[3] |= 0xF0;
7577 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
7578 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08007579 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
7580 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007581 }
7582
Jeff Johnson295189b2012-06-20 16:38:30 -07007583 hdd_set_ap_ops( pAdapter->dev );
7584
Kiet Lam10841362013-11-01 11:36:50 +05307585 /* This is for only SAP mode where users can
7586 * control country through ini.
7587 * P2P GO follows station country code
7588 * acquired during the STA scanning. */
7589 if((NL80211_IFTYPE_AP == type) &&
7590 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
7591 {
7592 int status = 0;
7593 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
7594 "%s: setting country code from INI ", __func__);
7595 init_completion(&pAdapter->change_country_code);
7596 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
7597 (void *)(tSmeChangeCountryCallback)
7598 wlan_hdd_change_country_code_cb,
7599 pConfig->apCntryCode, pAdapter,
7600 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05307601 eSIR_FALSE,
7602 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05307603 if (eHAL_STATUS_SUCCESS == status)
7604 {
7605 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307606 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05307607 &pAdapter->change_country_code,
7608 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307609 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05307610 {
7611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307612 FL("SME Timed out while setting country code %ld"),
7613 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08007614
7615 if (pHddCtx->isLogpInProgress)
7616 {
7617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7618 "%s: LOGP in Progress. Ignore!!!", __func__);
7619 return -EAGAIN;
7620 }
Kiet Lam10841362013-11-01 11:36:50 +05307621 }
7622 }
7623 else
7624 {
7625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007626 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05307627 return -EINVAL;
7628 }
7629 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007630 status = hdd_init_ap_mode(pAdapter);
7631 if(status != VOS_STATUS_SUCCESS)
7632 {
7633 hddLog(VOS_TRACE_LEVEL_FATAL,
7634 "%s: Error initializing the ap mode", __func__);
7635 return -EINVAL;
7636 }
7637 hdd_set_conparam(1);
7638
Jeff Johnson295189b2012-06-20 16:38:30 -07007639 /*interface type changed update in wiphy structure*/
7640 if(wdev)
7641 {
7642 wdev->iftype = type;
7643 pHddCtx->change_iface = type;
7644 }
7645 else
7646 {
7647 hddLog(VOS_TRACE_LEVEL_ERROR,
7648 "%s: ERROR !!!! Wireless dev is NULL", __func__);
7649 return -EINVAL;
7650 }
7651 goto done;
7652 }
7653
7654 default:
7655 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7656 __func__);
7657 return -EOPNOTSUPP;
7658 }
7659 }
7660 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007661 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007662 )
7663 {
7664 switch(type)
7665 {
7666 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007667 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007668 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05307669
7670 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307671#ifdef FEATURE_WLAN_TDLS
7672
7673 /* A Mutex Lock is introduced while changing the mode to
7674 * protect the concurrent access for the Adapters by TDLS
7675 * module.
7676 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307677 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307678#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07007679 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007680 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007681 //Check for sub-string p2p to confirm its a p2p interface
7682 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007683 {
7684 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7685 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7686 }
7687 else
7688 {
7689 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007690 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007691 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007692 hdd_set_conparam(0);
7693 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007694 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
7695 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307696#ifdef FEATURE_WLAN_TDLS
7697 mutex_unlock(&pHddCtx->tdls_lock);
7698#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05307699 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007700 if( VOS_STATUS_SUCCESS != status )
7701 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07007702 /* In case of JB, for P2P-GO, only change interface will be called,
7703 * This is the right place to enable back bmps_imps()
7704 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307705 if (pHddCtx->hdd_wlan_suspended)
7706 {
7707 hdd_set_pwrparams(pHddCtx);
7708 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007709 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007710 goto done;
7711 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007712 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007713 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007714 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7715 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007716 goto done;
7717 default:
7718 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7719 __func__);
7720 return -EOPNOTSUPP;
7721
7722 }
7723
7724 }
7725 else
7726 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307727 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
7728 __func__, hdd_device_modetoString(pAdapter->device_mode),
7729 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007730 return -EOPNOTSUPP;
7731 }
7732
7733
7734 if(pRoamProfile)
7735 {
7736 if ( LastBSSType != pRoamProfile->BSSType )
7737 {
7738 /*interface type changed update in wiphy structure*/
7739 wdev->iftype = type;
7740
7741 /*the BSS mode changed, We need to issue disconnect
7742 if connected or in IBSS disconnect state*/
7743 if ( hdd_connGetConnectedBssType(
7744 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
7745 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
7746 {
7747 /*need to issue a disconnect to CSR.*/
7748 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7749 if( eHAL_STATUS_SUCCESS ==
7750 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
7751 pAdapter->sessionId,
7752 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
7753 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307754 ret = wait_for_completion_interruptible_timeout(
7755 &pAdapter->disconnect_comp_var,
7756 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7757 if (ret <= 0)
7758 {
7759 hddLog(VOS_TRACE_LEVEL_ERROR,
7760 FL("wait on disconnect_comp_var failed %ld"), ret);
7761 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007762 }
7763 }
7764 }
7765 }
7766
7767done:
7768 /*set bitmask based on updated value*/
7769 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07007770
7771 /* Only STA mode support TM now
7772 * all other mode, TM feature should be disabled */
7773 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
7774 (~VOS_STA & pHddCtx->concurrency_mode) )
7775 {
7776 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
7777 }
7778
Jeff Johnson295189b2012-06-20 16:38:30 -07007779#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307780 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05307781 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07007782 {
7783 //we are ok to do AMP
7784 pHddCtx->isAmpAllowed = VOS_TRUE;
7785 }
7786#endif //WLAN_BTAMP_FEATURE
7787 EXIT();
7788 return 0;
7789}
7790
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307791/*
7792 * FUNCTION: wlan_hdd_cfg80211_change_iface
7793 * wrapper function to protect the actual implementation from SSR.
7794 */
7795int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
7796 struct net_device *ndev,
7797 enum nl80211_iftype type,
7798 u32 *flags,
7799 struct vif_params *params
7800 )
7801{
7802 int ret;
7803
7804 vos_ssr_protect(__func__);
7805 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
7806 vos_ssr_unprotect(__func__);
7807
7808 return ret;
7809}
7810
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007811#ifdef FEATURE_WLAN_TDLS
7812static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
7813 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
7814{
7815 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7816 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7817 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007818 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307819 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307820 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007821
7822 ENTER();
7823
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307824 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007825 {
7826 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7827 "Invalid arguments");
7828 return -EINVAL;
7829 }
Hoonki Lee27511902013-03-14 18:19:06 -07007830
7831 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
7832 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
7833 {
7834 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7835 "%s: TDLS mode is disabled OR not enabled in FW."
7836 MAC_ADDRESS_STR " Request declined.",
7837 __func__, MAC_ADDR_ARRAY(mac));
7838 return -ENOTSUPP;
7839 }
7840
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007841 if (pHddCtx->isLogpInProgress)
7842 {
7843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7844 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05307845 wlan_hdd_tdls_set_link_status(pAdapter,
7846 mac,
7847 eTDLS_LINK_IDLE,
7848 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007849 return -EBUSY;
7850 }
7851
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05307852 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007853
7854 if ( NULL == pTdlsPeer ) {
7855 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7856 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
7857 __func__, MAC_ADDR_ARRAY(mac), update);
7858 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007859 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007860
7861 /* in add station, we accept existing valid staId if there is */
7862 if ((0 == update) &&
7863 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
7864 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007865 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007866 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007867 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007868 " link_status %d. staId %d. add station ignored.",
7869 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
7870 return 0;
7871 }
7872 /* in change station, we accept only when staId is valid */
7873 if ((1 == update) &&
7874 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
7875 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
7876 {
7877 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7878 "%s: " MAC_ADDRESS_STR
7879 " link status %d. staId %d. change station %s.",
7880 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
7881 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
7882 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007883 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007884
7885 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307886 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007887 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7889 "%s: " MAC_ADDRESS_STR
7890 " TDLS setup is ongoing. Request declined.",
7891 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07007892 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007893 }
7894
7895 /* first to check if we reached to maximum supported TDLS peer.
7896 TODO: for now, return -EPERM looks working fine,
7897 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307898 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
7899 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007900 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7902 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307903 " TDLS Max peer already connected. Request declined."
7904 " Num of peers (%d), Max allowed (%d).",
7905 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
7906 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007907 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007908 }
7909 else
7910 {
7911 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307912 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007913 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007914 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007915 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7916 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
7917 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007918 return -EPERM;
7919 }
7920 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007921 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05307922 wlan_hdd_tdls_set_link_status(pAdapter,
7923 mac,
7924 eTDLS_LINK_CONNECTING,
7925 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007926
Jeff Johnsond75fe012013-04-06 10:53:06 -07007927 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307928 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007929 {
7930 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7931 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007932 if(StaParams->htcap_present)
7933 {
7934 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7935 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
7936 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7937 "ht_capa->extended_capabilities: %0x",
7938 StaParams->HTCap.extendedHtCapInfo);
7939 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007940 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7941 "params->capability: %0x",StaParams->capability);
7942 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007943 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007944 if(StaParams->vhtcap_present)
7945 {
7946 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7947 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
7948 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
7949 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
7950 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007951 {
7952 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007953 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007954 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
7955 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7956 "[%d]: %x ", i, StaParams->supported_rates[i]);
7957 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07007958 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307959 else if ((1 == update) && (NULL == StaParams))
7960 {
7961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7962 "%s : update is true, but staParams is NULL. Error!", __func__);
7963 return -EPERM;
7964 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007965
7966 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
7967
7968 if (!update)
7969 {
7970 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7971 pAdapter->sessionId, mac);
7972 }
7973 else
7974 {
7975 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7976 pAdapter->sessionId, mac, StaParams);
7977 }
7978
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307979 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007980 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
7981
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307982 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007983 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007984 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307985 "%s: timeout waiting for tdls add station indication %ld",
7986 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007987 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007988 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307989
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007990 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
7991 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007992 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007993 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007994 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007995 }
7996
7997 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007998
7999error:
Atul Mittal115287b2014-07-08 13:26:33 +05308000 wlan_hdd_tdls_set_link_status(pAdapter,
8001 mac,
8002 eTDLS_LINK_IDLE,
8003 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008004 return -EPERM;
8005
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008006}
8007#endif
8008
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308009static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008010 struct net_device *dev,
8011 u8 *mac,
8012 struct station_parameters *params)
8013{
8014 VOS_STATUS status = VOS_STATUS_SUCCESS;
8015 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05308016 hdd_context_t *pHddCtx;
8017 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008018 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308019 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008020#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008021 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008022 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308023 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008024#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008025 ENTER();
8026
Gopichand Nakkala29149562013-05-10 21:43:41 +05308027 if ((NULL == pAdapter))
8028 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308030 "invalid adapter ");
8031 return -EINVAL;
8032 }
8033
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308034 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8035 TRACE_CODE_HDD_CHANGE_STATION,
8036 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05308037 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308038
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308039 ret = wlan_hdd_validate_context(pHddCtx);
8040 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05308041 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8043 "%s: HDD context is not valid", __func__);
8044 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308045 }
8046
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308047 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8048
8049 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008050 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8052 "invalid HDD station context");
8053 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008054 }
8055
Jeff Johnson295189b2012-06-20 16:38:30 -07008056 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
8057
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008058 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8059 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07008060 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008061 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07008062 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308063 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07008064 WLANTL_STA_AUTHENTICATED);
8065
Gopichand Nakkala29149562013-05-10 21:43:41 +05308066 if (status != VOS_STATUS_SUCCESS)
8067 {
8068 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8069 "%s: Not able to change TL state to AUTHENTICATED", __func__);
8070 return -EINVAL;
8071 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008072 }
8073 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07008074 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8075 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308076#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008077 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8078 StaParams.capability = params->capability;
8079 StaParams.uapsd_queues = params->uapsd_queues;
8080 StaParams.max_sp = params->max_sp;
8081
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308082 /* Convert (first channel , number of channels) tuple to
8083 * the total list of channels. This goes with the assumption
8084 * that if the first channel is < 14, then the next channels
8085 * are an incremental of 1 else an incremental of 4 till the number
8086 * of channels.
8087 */
8088 if (0 != params->supported_channels_len) {
8089 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
8090 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
8091 {
8092 int wifi_chan_index;
8093 StaParams.supported_channels[j] = params->supported_channels[i];
8094 wifi_chan_index =
8095 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
8096 no_of_channels = params->supported_channels[i+1];
8097 for(k=1; k <= no_of_channels; k++)
8098 {
8099 StaParams.supported_channels[j+1] =
8100 StaParams.supported_channels[j] + wifi_chan_index;
8101 j+=1;
8102 }
8103 }
8104 StaParams.supported_channels_len = j;
8105 }
8106 vos_mem_copy(StaParams.supported_oper_classes,
8107 params->supported_oper_classes,
8108 params->supported_oper_classes_len);
8109 StaParams.supported_oper_classes_len =
8110 params->supported_oper_classes_len;
8111
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008112 if (0 != params->ext_capab_len)
8113 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
8114 sizeof(StaParams.extn_capability));
8115
8116 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008117 {
8118 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008119 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008120 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008121
8122 StaParams.supported_rates_len = params->supported_rates_len;
8123
8124 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
8125 * The supported_rates array , for all the structures propogating till Add Sta
8126 * to the firmware has to be modified , if the supplicant (ieee80211) is
8127 * modified to send more rates.
8128 */
8129
8130 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
8131 */
8132 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
8133 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
8134
8135 if (0 != StaParams.supported_rates_len) {
8136 int i = 0;
8137 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
8138 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008140 "Supported Rates with Length %d", StaParams.supported_rates_len);
8141 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008142 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008143 "[%d]: %0x", i, StaParams.supported_rates[i]);
8144 }
8145
8146 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008147 {
8148 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008149 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008150 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008151
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008152 if (0 != params->ext_capab_len ) {
8153 /*Define A Macro : TODO Sunil*/
8154 if ((1<<4) & StaParams.extn_capability[3]) {
8155 isBufSta = 1;
8156 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308157 /* TDLS Channel Switching Support */
8158 if ((1<<6) & StaParams.extn_capability[3]) {
8159 isOffChannelSupported = 1;
8160 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008161 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308162 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
8163 &StaParams, isBufSta,
8164 isOffChannelSupported);
8165
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308166 if (VOS_STATUS_SUCCESS != status) {
8167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8168 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
8169 return -EINVAL;
8170 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008171 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
8172
8173 if (VOS_STATUS_SUCCESS != status) {
8174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8175 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
8176 return -EINVAL;
8177 }
8178 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008179#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05308180 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008181 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008182 return status;
8183}
8184
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308185static int wlan_hdd_change_station(struct wiphy *wiphy,
8186 struct net_device *dev,
8187 u8 *mac,
8188 struct station_parameters *params)
8189{
8190 int ret;
8191
8192 vos_ssr_protect(__func__);
8193 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
8194 vos_ssr_unprotect(__func__);
8195
8196 return ret;
8197}
8198
Jeff Johnson295189b2012-06-20 16:38:30 -07008199/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308200 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008201 * This function is used to initialize the key information
8202 */
8203#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308204static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008205 struct net_device *ndev,
8206 u8 key_index, bool pairwise,
8207 const u8 *mac_addr,
8208 struct key_params *params
8209 )
8210#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308211static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008212 struct net_device *ndev,
8213 u8 key_index, const u8 *mac_addr,
8214 struct key_params *params
8215 )
8216#endif
8217{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008218 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07008219 tCsrRoamSetKey setKey;
8220 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308221 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008222 v_U32_t roamId= 0xFF;
8223 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008224 hdd_hostapd_state_t *pHostapdState;
8225 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008226 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308227 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008228
8229 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308230
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308231 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8232 TRACE_CODE_HDD_CFG80211_ADD_KEY,
8233 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308234 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8235 status = wlan_hdd_validate_context(pHddCtx);
8236
8237 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008238 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8240 "%s: HDD context is not valid", __func__);
8241 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008242 }
8243
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308244 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8245 __func__, hdd_device_modetoString(pAdapter->device_mode),
8246 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008247
8248 if (CSR_MAX_NUM_KEY <= key_index)
8249 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008250 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008251 key_index);
8252
8253 return -EINVAL;
8254 }
8255
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008256 if (CSR_MAX_KEY_LEN < params->key_len)
8257 {
8258 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
8259 params->key_len);
8260
8261 return -EINVAL;
8262 }
8263
8264 hddLog(VOS_TRACE_LEVEL_INFO,
8265 "%s: called with key index = %d & key length %d",
8266 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008267
8268 /*extract key idx, key len and key*/
8269 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8270 setKey.keyId = key_index;
8271 setKey.keyLength = params->key_len;
8272 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
8273
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008274 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07008275 {
8276 case WLAN_CIPHER_SUITE_WEP40:
8277 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
8278 break;
8279
8280 case WLAN_CIPHER_SUITE_WEP104:
8281 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
8282 break;
8283
8284 case WLAN_CIPHER_SUITE_TKIP:
8285 {
8286 u8 *pKey = &setKey.Key[0];
8287 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
8288
8289 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
8290
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008291 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07008292
8293 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008294 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008295 |--------------|----------|----------|
8296 <---16bytes---><--8bytes--><--8bytes-->
8297
8298 */
8299 /*Sme expects the 32 bytes key to be in the below order
8300
8301 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008302 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008303 |--------------|----------|----------|
8304 <---16bytes---><--8bytes--><--8bytes-->
8305 */
8306 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008307 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07008308
8309 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008310 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008311
8312 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008313 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008314
8315
8316 break;
8317 }
8318
8319 case WLAN_CIPHER_SUITE_CCMP:
8320 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
8321 break;
8322
8323#ifdef FEATURE_WLAN_WAPI
8324 case WLAN_CIPHER_SUITE_SMS4:
8325 {
8326 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8327 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
8328 params->key, params->key_len);
8329 return 0;
8330 }
8331#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008332
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008333#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07008334 case WLAN_CIPHER_SUITE_KRK:
8335 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
8336 break;
8337#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008338
8339#ifdef WLAN_FEATURE_11W
8340 case WLAN_CIPHER_SUITE_AES_CMAC:
8341 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07008342 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07008343#endif
8344
Jeff Johnson295189b2012-06-20 16:38:30 -07008345 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008346 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07008347 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308348 status = -EOPNOTSUPP;
8349 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008350 }
8351
8352 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
8353 __func__, setKey.encType);
8354
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008355 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07008356#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8357 (!pairwise)
8358#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008359 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07008360#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008361 )
8362 {
8363 /* set group key*/
8364 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8365 "%s- %d: setting Broadcast key",
8366 __func__, __LINE__);
8367 setKey.keyDirection = eSIR_RX_ONLY;
8368 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8369 }
8370 else
8371 {
8372 /* set pairwise key*/
8373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8374 "%s- %d: setting pairwise key",
8375 __func__, __LINE__);
8376 setKey.keyDirection = eSIR_TX_RX;
8377 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8378 }
8379 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
8380 {
8381 setKey.keyDirection = eSIR_TX_RX;
8382 /*Set the group key*/
8383 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8384 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07008385
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008386 if ( 0 != status )
8387 {
8388 hddLog(VOS_TRACE_LEVEL_ERROR,
8389 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308390 status = -EINVAL;
8391 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008392 }
8393 /*Save the keys here and call sme_RoamSetKey for setting
8394 the PTK after peer joins the IBSS network*/
8395 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
8396 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308397 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008398 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05308399 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
8400 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
8401 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008402 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008403 if( pHostapdState->bssState == BSS_START )
8404 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008405 status = WLANSAP_SetKeySta( pVosContext, &setKey);
8406
8407 if ( status != eHAL_STATUS_SUCCESS )
8408 {
8409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8410 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8411 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308412 status = -EINVAL;
8413 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008414 }
8415 }
8416
8417 /* Saving WEP keys */
8418 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
8419 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
8420 {
8421 //Save the wep key in ap context. Issue setkey after the BSS is started.
8422 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8423 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
8424 }
8425 else
8426 {
8427 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008428 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008429 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
8430 }
8431 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008432 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
8433 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008434 {
8435 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8436 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8437
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308438#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8439 if (!pairwise)
8440#else
8441 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8442#endif
8443 {
8444 /* set group key*/
8445 if (pHddStaCtx->roam_info.deferKeyComplete)
8446 {
8447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8448 "%s- %d: Perform Set key Complete",
8449 __func__, __LINE__);
8450 hdd_PerformRoamSetKeyComplete(pAdapter);
8451 }
8452 }
8453
Jeff Johnson295189b2012-06-20 16:38:30 -07008454 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
8455
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08008456 pWextState->roamProfile.Keys.defaultIndex = key_index;
8457
8458
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008459 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008460 params->key, params->key_len);
8461
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308462
Jeff Johnson295189b2012-06-20 16:38:30 -07008463 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8464
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308465 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008466 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308467 __func__, setKey.peerMac[0], setKey.peerMac[1],
8468 setKey.peerMac[2], setKey.peerMac[3],
8469 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008470 setKey.keyDirection);
8471
Nirav Shah4f765af2015-01-21 19:51:30 +05308472 /* Wait for EAPOL M4 before setting key.
8473 * No need to consider Dynamic WEP as we will receive M8.
8474 */
8475 if ( (setKey.encType == eCSR_ENCRYPT_TYPE_AES ||
8476 setKey.encType == eCSR_ENCRYPT_TYPE_TKIP) &&
8477 ( 1
8478#if defined WLAN_FEATURE_VOWIFI_11R
8479 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_FT_RSN
8480 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_FT_RSN_PSK
8481#endif
8482#ifdef FEATURE_WLAN_ESE
8483 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_CCKM_WPA
8484 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_CCKM_RSN
8485#endif
8486 ))
Jeff Johnson295189b2012-06-20 16:38:30 -07008487 {
Nirav Shah4f765af2015-01-21 19:51:30 +05308488 vos_status = wlan_hdd_check_ula_done(pAdapter);
8489
8490 if ( vos_status != VOS_STATUS_SUCCESS )
8491 {
8492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008493 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8494 __LINE__, vos_status );
8495
Nirav Shah4f765af2015-01-21 19:51:30 +05308496 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008497
Nirav Shah4f765af2015-01-21 19:51:30 +05308498 status = -EINVAL;
8499 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008500
Nirav Shah4f765af2015-01-21 19:51:30 +05308501 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008502 }
8503
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008504#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308505 /* The supplicant may attempt to set the PTK once pre-authentication
8506 is done. Save the key in the UMAC and include it in the ADD BSS
8507 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008508 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308509 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008510 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308511 hddLog(VOS_TRACE_LEVEL_INFO_MED,
8512 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308513 status = 0;
8514 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308515 }
8516 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
8517 {
8518 hddLog(VOS_TRACE_LEVEL_ERROR,
8519 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308520 status = -EINVAL;
8521 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008522 }
8523#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07008524
8525 /* issue set key request to SME*/
8526 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8527 pAdapter->sessionId, &setKey, &roamId );
8528
8529 if ( 0 != status )
8530 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308531 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008532 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
8533 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308534 status = -EINVAL;
8535 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008536 }
8537
8538
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308539 /* in case of IBSS as there was no information available about WEP keys during
8540 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07008541 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308542 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
8543 !( ( IW_AUTH_KEY_MGMT_802_1X
8544 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07008545 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
8546 )
8547 &&
8548 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
8549 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
8550 )
8551 )
8552 {
8553 setKey.keyDirection = eSIR_RX_ONLY;
8554 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8555
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308556 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008557 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308558 __func__, setKey.peerMac[0], setKey.peerMac[1],
8559 setKey.peerMac[2], setKey.peerMac[3],
8560 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008561 setKey.keyDirection);
8562
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308563 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008564 pAdapter->sessionId, &setKey, &roamId );
8565
8566 if ( 0 != status )
8567 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308568 hddLog(VOS_TRACE_LEVEL_ERROR,
8569 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008570 __func__, status);
8571 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308572 status = -EINVAL;
8573 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008574 }
8575 }
8576 }
8577
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308578end:
8579 /* Need to clear any trace of key value in the memory.
8580 * Thus zero out the memory even though it is local
8581 * variable.
8582 */
8583 vos_mem_zero(&setKey, sizeof(setKey));
8584
8585 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008586}
8587
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308588#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8589static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8590 struct net_device *ndev,
8591 u8 key_index, bool pairwise,
8592 const u8 *mac_addr,
8593 struct key_params *params
8594 )
8595#else
8596static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8597 struct net_device *ndev,
8598 u8 key_index, const u8 *mac_addr,
8599 struct key_params *params
8600 )
8601#endif
8602{
8603 int ret;
8604 vos_ssr_protect(__func__);
8605#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8606 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
8607 mac_addr, params);
8608#else
8609 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
8610 params);
8611#endif
8612 vos_ssr_unprotect(__func__);
8613
8614 return ret;
8615}
8616
Jeff Johnson295189b2012-06-20 16:38:30 -07008617/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308618 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008619 * This function is used to get the key information
8620 */
8621#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308622static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308623 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008624 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308625 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008626 const u8 *mac_addr, void *cookie,
8627 void (*callback)(void *cookie, struct key_params*)
8628 )
8629#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308630static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308631 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008632 struct net_device *ndev,
8633 u8 key_index, const u8 *mac_addr, void *cookie,
8634 void (*callback)(void *cookie, struct key_params*)
8635 )
8636#endif
8637{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308638 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308639 hdd_wext_state_t *pWextState = NULL;
8640 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008641 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308642 hdd_context_t *pHddCtx;
8643 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008644
8645 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308646
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308647 if (NULL == pAdapter)
8648 {
8649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8650 "%s: HDD adapter is Null", __func__);
8651 return -ENODEV;
8652 }
8653
8654 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8655 ret = wlan_hdd_validate_context(pHddCtx);
8656 if (0 != ret)
8657 {
8658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8659 "%s: HDD context is not valid", __func__);
8660 return ret;
8661 }
8662
8663 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8664 pRoamProfile = &(pWextState->roamProfile);
8665
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308666 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8667 __func__, hdd_device_modetoString(pAdapter->device_mode),
8668 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308669
Jeff Johnson295189b2012-06-20 16:38:30 -07008670 memset(&params, 0, sizeof(params));
8671
8672 if (CSR_MAX_NUM_KEY <= key_index)
8673 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07008675 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308676 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008677
8678 switch(pRoamProfile->EncryptionType.encryptionType[0])
8679 {
8680 case eCSR_ENCRYPT_TYPE_NONE:
8681 params.cipher = IW_AUTH_CIPHER_NONE;
8682 break;
8683
8684 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
8685 case eCSR_ENCRYPT_TYPE_WEP40:
8686 params.cipher = WLAN_CIPHER_SUITE_WEP40;
8687 break;
8688
8689 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
8690 case eCSR_ENCRYPT_TYPE_WEP104:
8691 params.cipher = WLAN_CIPHER_SUITE_WEP104;
8692 break;
8693
8694 case eCSR_ENCRYPT_TYPE_TKIP:
8695 params.cipher = WLAN_CIPHER_SUITE_TKIP;
8696 break;
8697
8698 case eCSR_ENCRYPT_TYPE_AES:
8699 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
8700 break;
8701
8702 default:
8703 params.cipher = IW_AUTH_CIPHER_NONE;
8704 break;
8705 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308706
c_hpothuaaf19692014-05-17 17:01:48 +05308707 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8708 TRACE_CODE_HDD_CFG80211_GET_KEY,
8709 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308710
Jeff Johnson295189b2012-06-20 16:38:30 -07008711 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
8712 params.seq_len = 0;
8713 params.seq = NULL;
8714 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
8715 callback(cookie, &params);
8716 return 0;
8717}
8718
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308719#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8720static int wlan_hdd_cfg80211_get_key(
8721 struct wiphy *wiphy,
8722 struct net_device *ndev,
8723 u8 key_index, bool pairwise,
8724 const u8 *mac_addr, void *cookie,
8725 void (*callback)(void *cookie, struct key_params*)
8726 )
8727#else
8728static int wlan_hdd_cfg80211_get_key(
8729 struct wiphy *wiphy,
8730 struct net_device *ndev,
8731 u8 key_index, const u8 *mac_addr, void *cookie,
8732 void (*callback)(void *cookie, struct key_params*)
8733 )
8734#endif
8735{
8736 int ret;
8737
8738 vos_ssr_protect(__func__);
8739#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8740 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
8741 mac_addr, cookie, callback);
8742#else
8743 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
8744 callback);
8745#endif
8746 vos_ssr_unprotect(__func__);
8747
8748 return ret;
8749}
8750
Jeff Johnson295189b2012-06-20 16:38:30 -07008751/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308752 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008753 * This function is used to delete the key information
8754 */
8755#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308756static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008757 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308758 u8 key_index,
8759 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008760 const u8 *mac_addr
8761 )
8762#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308763static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008764 struct net_device *ndev,
8765 u8 key_index,
8766 const u8 *mac_addr
8767 )
8768#endif
8769{
8770 int status = 0;
8771
8772 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308773 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07008774 //it is observed that this is invalidating peer
8775 //key index whenever re-key is done. This is affecting data link.
8776 //It should be ok to ignore del_key.
8777#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308778 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
8779 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008780 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
8781 tCsrRoamSetKey setKey;
8782 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308783
Jeff Johnson295189b2012-06-20 16:38:30 -07008784 ENTER();
8785
8786 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
8787 __func__,pAdapter->device_mode);
8788
8789 if (CSR_MAX_NUM_KEY <= key_index)
8790 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308791 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008792 key_index);
8793
8794 return -EINVAL;
8795 }
8796
8797 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8798 setKey.keyId = key_index;
8799
8800 if (mac_addr)
8801 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8802 else
8803 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
8804
8805 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
8806
8807 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008808 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308809 )
8810 {
8811
8812 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07008813 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8814 if( pHostapdState->bssState == BSS_START)
8815 {
8816 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308817
Jeff Johnson295189b2012-06-20 16:38:30 -07008818 if ( status != eHAL_STATUS_SUCCESS )
8819 {
8820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8821 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8822 __LINE__, status );
8823 }
8824 }
8825 }
8826 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308827 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07008828 )
8829 {
8830 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8831
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308832 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8833
8834 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008835 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308836 __func__, setKey.peerMac[0], setKey.peerMac[1],
8837 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07008838 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308839 if(pAdapter->sessionCtx.station.conn_info.connState ==
8840 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07008841 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308842 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008843 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308844
Jeff Johnson295189b2012-06-20 16:38:30 -07008845 if ( 0 != status )
8846 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308847 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008848 "%s: sme_RoamSetKey failure, returned %d",
8849 __func__, status);
8850 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8851 return -EINVAL;
8852 }
8853 }
8854 }
8855#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008856 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008857 return status;
8858}
8859
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308860#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8861static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
8862 struct net_device *ndev,
8863 u8 key_index,
8864 bool pairwise,
8865 const u8 *mac_addr
8866 )
8867#else
8868static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
8869 struct net_device *ndev,
8870 u8 key_index,
8871 const u8 *mac_addr
8872 )
8873#endif
8874{
8875 int ret;
8876
8877 vos_ssr_protect(__func__);
8878#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8879 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
8880 mac_addr);
8881#else
8882 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
8883#endif
8884 vos_ssr_unprotect(__func__);
8885
8886 return ret;
8887}
8888
Jeff Johnson295189b2012-06-20 16:38:30 -07008889/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308890 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008891 * This function is used to set the default tx key index
8892 */
8893#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308894static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008895 struct net_device *ndev,
8896 u8 key_index,
8897 bool unicast, bool multicast)
8898#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308899static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008900 struct net_device *ndev,
8901 u8 key_index)
8902#endif
8903{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308904 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308905 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308906 hdd_wext_state_t *pWextState;
8907 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308908 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008909
8910 ENTER();
8911
Gopichand Nakkala29149562013-05-10 21:43:41 +05308912 if ((NULL == pAdapter))
8913 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308915 "invalid adapter");
8916 return -EINVAL;
8917 }
8918
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308919 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8920 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
8921 pAdapter->sessionId, key_index));
8922
Gopichand Nakkala29149562013-05-10 21:43:41 +05308923 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8924 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8925
8926 if ((NULL == pWextState) || (NULL == pHddStaCtx))
8927 {
8928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8929 "invalid Wext state or HDD context");
8930 return -EINVAL;
8931 }
8932
Arif Hussain6d2a3322013-11-17 19:50:10 -08008933 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008934 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308935
Jeff Johnson295189b2012-06-20 16:38:30 -07008936 if (CSR_MAX_NUM_KEY <= key_index)
8937 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308938 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008939 key_index);
8940
8941 return -EINVAL;
8942 }
8943
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308944 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8945 status = wlan_hdd_validate_context(pHddCtx);
8946
8947 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008948 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8950 "%s: HDD context is not valid", __func__);
8951 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008952 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308953
Jeff Johnson295189b2012-06-20 16:38:30 -07008954 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008955 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308956 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008957 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308958 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08008959 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308960 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08008961 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07008962 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308963 {
8964 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07008965 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308966
Jeff Johnson295189b2012-06-20 16:38:30 -07008967 tCsrRoamSetKey setKey;
8968 v_U32_t roamId= 0xFF;
8969 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308970
8971 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008972 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308973
Jeff Johnson295189b2012-06-20 16:38:30 -07008974 Keys->defaultIndex = (u8)key_index;
8975 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8976 setKey.keyId = key_index;
8977 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308978
8979 vos_mem_copy(&setKey.Key[0],
8980 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008981 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308982
Gopichand Nakkala29149562013-05-10 21:43:41 +05308983 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308984
8985 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07008986 &pHddStaCtx->conn_info.bssId[0],
8987 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308988
Gopichand Nakkala29149562013-05-10 21:43:41 +05308989 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
8990 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
8991 eCSR_ENCRYPT_TYPE_WEP104)
8992 {
8993 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
8994 even though ap is configured for WEP-40 encryption. In this canse the key length
8995 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
8996 type(104) and switching encryption type to 40*/
8997 pWextState->roamProfile.EncryptionType.encryptionType[0] =
8998 eCSR_ENCRYPT_TYPE_WEP40;
8999 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
9000 eCSR_ENCRYPT_TYPE_WEP40;
9001 }
9002
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309003 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07009004 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309005
Jeff Johnson295189b2012-06-20 16:38:30 -07009006 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309007 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009008 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309009
Jeff Johnson295189b2012-06-20 16:38:30 -07009010 if ( 0 != status )
9011 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309012 hddLog(VOS_TRACE_LEVEL_ERROR,
9013 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009014 status);
9015 return -EINVAL;
9016 }
9017 }
9018 }
9019
9020 /* In SoftAp mode setting key direction for default mode */
9021 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
9022 {
9023 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
9024 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
9025 (eCSR_ENCRYPT_TYPE_AES !=
9026 pWextState->roamProfile.EncryptionType.encryptionType[0])
9027 )
9028 {
9029 /* Saving key direction for default key index to TX default */
9030 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9031 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
9032 }
9033 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309034
Jeff Johnson295189b2012-06-20 16:38:30 -07009035 return status;
9036}
9037
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309038#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9039static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9040 struct net_device *ndev,
9041 u8 key_index,
9042 bool unicast, bool multicast)
9043#else
9044static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9045 struct net_device *ndev,
9046 u8 key_index)
9047#endif
9048{
9049 int ret;
9050 vos_ssr_protect(__func__);
9051#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9052 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
9053 multicast);
9054#else
9055 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
9056#endif
9057 vos_ssr_unprotect(__func__);
9058
9059 return ret;
9060}
9061
Jeff Johnson295189b2012-06-20 16:38:30 -07009062/*
9063 * FUNCTION: wlan_hdd_cfg80211_inform_bss
9064 * This function is used to inform the BSS details to nl80211 interface.
9065 */
9066static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
9067 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
9068{
9069 struct net_device *dev = pAdapter->dev;
9070 struct wireless_dev *wdev = dev->ieee80211_ptr;
9071 struct wiphy *wiphy = wdev->wiphy;
9072 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
9073 int chan_no;
9074 int ie_length;
9075 const char *ie;
9076 unsigned int freq;
9077 struct ieee80211_channel *chan;
9078 int rssi = 0;
9079 struct cfg80211_bss *bss = NULL;
9080
9081 ENTER();
9082
9083 if( NULL == pBssDesc )
9084 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009085 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009086 return bss;
9087 }
9088
9089 chan_no = pBssDesc->channelId;
9090 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
9091 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
9092
9093 if( NULL == ie )
9094 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009095 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009096 return bss;
9097 }
9098
9099#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9100 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9101 {
9102 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9103 }
9104 else
9105 {
9106 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9107 }
9108#else
9109 freq = ieee80211_channel_to_frequency(chan_no);
9110#endif
9111
9112 chan = __ieee80211_get_channel(wiphy, freq);
9113
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05309114 if (!chan) {
9115 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
9116 return NULL;
9117 }
9118
Abhishek Singhaee43942014-06-16 18:55:47 +05309119 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07009120
Abhishek Singhaee43942014-06-16 18:55:47 +05309121 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309122 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07009123 pBssDesc->capabilityInfo,
9124 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05309125 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07009126}
9127
9128
9129
9130/*
9131 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
9132 * This function is used to inform the BSS details to nl80211 interface.
9133 */
9134struct cfg80211_bss*
9135wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
9136 tSirBssDescription *bss_desc
9137 )
9138{
9139 /*
9140 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
9141 already exists in bss data base of cfg80211 for that particular BSS ID.
9142 Using cfg80211_inform_bss_frame to update the bss entry instead of
9143 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
9144 now there is no possibility to get the mgmt(probe response) frame from PE,
9145 converting bss_desc to ieee80211_mgmt(probe response) and passing to
9146 cfg80211_inform_bss_frame.
9147 */
9148 struct net_device *dev = pAdapter->dev;
9149 struct wireless_dev *wdev = dev->ieee80211_ptr;
9150 struct wiphy *wiphy = wdev->wiphy;
9151 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009152#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9153 qcom_ie_age *qie_age = NULL;
9154 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
9155#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009156 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009157#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009158 const char *ie =
9159 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
9160 unsigned int freq;
9161 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309162 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009163 struct cfg80211_bss *bss_status = NULL;
9164 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
9165 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07009166 hdd_context_t *pHddCtx;
9167 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07009168#ifdef WLAN_OPEN_SOURCE
9169 struct timespec ts;
9170#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009171
Wilson Yangf80a0542013-10-07 13:02:37 -07009172 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9173 status = wlan_hdd_validate_context(pHddCtx);
9174
9175 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309176 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009177 {
9178 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9179 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9180 return NULL;
9181 }
9182
9183
9184 if (0 != status)
9185 {
9186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9187 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009188 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009189 }
9190
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309191 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07009192 if (!mgmt)
9193 {
9194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9195 "%s: memory allocation failed ", __func__);
9196 return NULL;
9197 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009198
Jeff Johnson295189b2012-06-20 16:38:30 -07009199 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07009200
9201#ifdef WLAN_OPEN_SOURCE
9202 /* Android does not want the timestamp from the frame.
9203 Instead it wants a monotonic increasing value */
9204 get_monotonic_boottime(&ts);
9205 mgmt->u.probe_resp.timestamp =
9206 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
9207#else
9208 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009209 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
9210 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07009211
9212#endif
9213
Jeff Johnson295189b2012-06-20 16:38:30 -07009214 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
9215 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009216
9217#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9218 /* GPS Requirement: need age ie per entry. Using vendor specific. */
9219 /* Assuming this is the last IE, copy at the end */
9220 ie_length -=sizeof(qcom_ie_age);
9221 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
9222 qie_age->element_id = QCOM_VENDOR_IE_ID;
9223 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
9224 qie_age->oui_1 = QCOM_OUI1;
9225 qie_age->oui_2 = QCOM_OUI2;
9226 qie_age->oui_3 = QCOM_OUI3;
9227 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
9228 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
9229#endif
9230
Jeff Johnson295189b2012-06-20 16:38:30 -07009231 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05309232 if (bss_desc->fProbeRsp)
9233 {
9234 mgmt->frame_control |=
9235 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
9236 }
9237 else
9238 {
9239 mgmt->frame_control |=
9240 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
9241 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009242
9243#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309244 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009245 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
9246 {
9247 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9248 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309249 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009250 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
9251
9252 {
9253 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9254 }
9255 else
9256 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309257 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
9258 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07009259 kfree(mgmt);
9260 return NULL;
9261 }
9262#else
9263 freq = ieee80211_channel_to_frequency(chan_no);
9264#endif
9265 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009266 /*when the band is changed on the fly using the GUI, three things are done
9267 * 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)
9268 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
9269 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
9270 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
9271 * and discards the channels correponding to previous band and calls back with zero bss results.
9272 * 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
9273 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
9274 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
9275 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
9276 * So drop the bss and continue to next bss.
9277 */
9278 if(chan == NULL)
9279 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309280 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07009281 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009282 return NULL;
9283 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009284 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309285 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07009286 * */
9287 if (( eConnectionState_Associated ==
9288 pAdapter->sessionCtx.station.conn_info.connState ) &&
9289 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
9290 pAdapter->sessionCtx.station.conn_info.bssId,
9291 WNI_CFG_BSSID_LEN)))
9292 {
9293 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
9294 rssi = (pAdapter->rssi * 100);
9295 }
9296 else
9297 {
9298 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
9299 }
9300
Nirav Shah20ac06f2013-12-12 18:14:06 +05309301 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
9302 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
9303 chan->center_freq, (int)(rssi/100));
9304
Jeff Johnson295189b2012-06-20 16:38:30 -07009305 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
9306 frame_len, rssi, GFP_KERNEL);
9307 kfree(mgmt);
9308 return bss_status;
9309}
9310
9311/*
9312 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
9313 * This function is used to update the BSS data base of CFG8011
9314 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309315struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009316 tCsrRoamInfo *pRoamInfo
9317 )
9318{
9319 tCsrRoamConnectedProfile roamProfile;
9320 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9321 struct cfg80211_bss *bss = NULL;
9322
9323 ENTER();
9324
9325 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
9326 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
9327
9328 if (NULL != roamProfile.pBssDesc)
9329 {
Girish Gowlif4b68022014-08-28 23:18:57 +05309330 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9331 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009332
9333 if (NULL == bss)
9334 {
9335 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
9336 __func__);
9337 }
9338
9339 sme_RoamFreeConnectProfile(hHal, &roamProfile);
9340 }
9341 else
9342 {
9343 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
9344 __func__);
9345 }
9346 return bss;
9347}
9348
9349/*
9350 * FUNCTION: wlan_hdd_cfg80211_update_bss
9351 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309352static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
9353 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07009354 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309355{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309356 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009357 tCsrScanResultInfo *pScanResult;
9358 eHalStatus status = 0;
9359 tScanResultHandle pResult;
9360 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009361 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009362
9363 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309364
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309365 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9366 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
9367 NO_SESSION, pAdapter->sessionId));
9368
Wilson Yangf80a0542013-10-07 13:02:37 -07009369 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9370
9371 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009372 {
Wilson Yangf80a0542013-10-07 13:02:37 -07009373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9374 "%s:LOGP in Progress. Ignore!!!",__func__);
9375 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009376 }
9377
Wilson Yangf80a0542013-10-07 13:02:37 -07009378
9379 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309380 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009381 {
9382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9383 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9384 return VOS_STATUS_E_PERM;
9385 }
9386
9387
Jeff Johnson295189b2012-06-20 16:38:30 -07009388 /*
9389 * start getting scan results and populate cgf80211 BSS database
9390 */
9391 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
9392
9393 /* no scan results */
9394 if (NULL == pResult)
9395 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309396 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
9397 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009398 return status;
9399 }
9400
9401 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
9402
9403 while (pScanResult)
9404 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309405 /*
9406 * cfg80211_inform_bss() is not updating ie field of bss entry, if
9407 * entry already exists in bss data base of cfg80211 for that
9408 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
9409 * bss entry instead of cfg80211_inform_bss, But this call expects
9410 * mgmt packet as input. As of now there is no possibility to get
9411 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07009412 * ieee80211_mgmt(probe response) and passing to c
9413 * fg80211_inform_bss_frame.
9414 * */
9415
9416 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9417 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309418
Jeff Johnson295189b2012-06-20 16:38:30 -07009419
9420 if (NULL == bss_status)
9421 {
9422 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009423 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009424 }
9425 else
9426 {
Yue Maf49ba872013-08-19 12:04:25 -07009427 cfg80211_put_bss(
9428#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
9429 wiphy,
9430#endif
9431 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009432 }
9433
9434 pScanResult = sme_ScanResultGetNext(hHal, pResult);
9435 }
9436
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309437 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07009438
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309439 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009440}
9441
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009442void
9443hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
9444{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309445 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08009446 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009447} /****** end hddPrintMacAddr() ******/
9448
9449void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009450hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009451{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309452 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009453 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009454 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
9455 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
9456 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009457} /****** end hddPrintPmkId() ******/
9458
9459//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
9460//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
9461
9462//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
9463//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
9464
9465#define dump_bssid(bssid) \
9466 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009467 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
9468 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009469 }
9470
9471#define dump_pmkid(pMac, pmkid) \
9472 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009473 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
9474 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009475 }
9476
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009477#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009478/*
9479 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
9480 * This function is used to notify the supplicant of a new PMKSA candidate.
9481 */
9482int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309483 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009484 int index, bool preauth )
9485{
Jeff Johnsone7245742012-09-05 17:12:55 -07009486#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009487 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009488 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009489
9490 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07009491 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009492
9493 if( NULL == pRoamInfo )
9494 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009495 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009496 return -EINVAL;
9497 }
9498
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009499 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
9500 {
9501 dump_bssid(pRoamInfo->bssid);
9502 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009503 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009504 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009505#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309506 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009507}
9508#endif //FEATURE_WLAN_LFR
9509
Yue Maef608272013-04-08 23:09:17 -07009510#ifdef FEATURE_WLAN_LFR_METRICS
9511/*
9512 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
9513 * 802.11r/LFR metrics reporting function to report preauth initiation
9514 *
9515 */
9516#define MAX_LFR_METRICS_EVENT_LENGTH 100
9517VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
9518 tCsrRoamInfo *pRoamInfo)
9519{
9520 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9521 union iwreq_data wrqu;
9522
9523 ENTER();
9524
9525 if (NULL == pAdapter)
9526 {
9527 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9528 return VOS_STATUS_E_FAILURE;
9529 }
9530
9531 /* create the event */
9532 memset(&wrqu, 0, sizeof(wrqu));
9533 memset(metrics_notification, 0, sizeof(metrics_notification));
9534
9535 wrqu.data.pointer = metrics_notification;
9536 wrqu.data.length = scnprintf(metrics_notification,
9537 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
9538 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9539
9540 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9541
9542 EXIT();
9543
9544 return VOS_STATUS_SUCCESS;
9545}
9546
9547/*
9548 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
9549 * 802.11r/LFR metrics reporting function to report preauth completion
9550 * or failure
9551 */
9552VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
9553 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
9554{
9555 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9556 union iwreq_data wrqu;
9557
9558 ENTER();
9559
9560 if (NULL == pAdapter)
9561 {
9562 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9563 return VOS_STATUS_E_FAILURE;
9564 }
9565
9566 /* create the event */
9567 memset(&wrqu, 0, sizeof(wrqu));
9568 memset(metrics_notification, 0, sizeof(metrics_notification));
9569
9570 scnprintf(metrics_notification, sizeof(metrics_notification),
9571 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
9572 MAC_ADDR_ARRAY(pRoamInfo->bssid));
9573
9574 if (1 == preauth_status)
9575 strncat(metrics_notification, " TRUE", 5);
9576 else
9577 strncat(metrics_notification, " FALSE", 6);
9578
9579 wrqu.data.pointer = metrics_notification;
9580 wrqu.data.length = strlen(metrics_notification);
9581
9582 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9583
9584 EXIT();
9585
9586 return VOS_STATUS_SUCCESS;
9587}
9588
9589/*
9590 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
9591 * 802.11r/LFR metrics reporting function to report handover initiation
9592 *
9593 */
9594VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
9595 tCsrRoamInfo *pRoamInfo)
9596{
9597 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9598 union iwreq_data wrqu;
9599
9600 ENTER();
9601
9602 if (NULL == pAdapter)
9603 {
9604 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9605 return VOS_STATUS_E_FAILURE;
9606 }
9607
9608 /* create the event */
9609 memset(&wrqu, 0, sizeof(wrqu));
9610 memset(metrics_notification, 0, sizeof(metrics_notification));
9611
9612 wrqu.data.pointer = metrics_notification;
9613 wrqu.data.length = scnprintf(metrics_notification,
9614 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
9615 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9616
9617 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9618
9619 EXIT();
9620
9621 return VOS_STATUS_SUCCESS;
9622}
9623#endif
9624
Jeff Johnson295189b2012-06-20 16:38:30 -07009625/*
9626 * FUNCTION: hdd_cfg80211_scan_done_callback
9627 * scanning callback function, called after finishing scan
9628 *
9629 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309630static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07009631 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
9632{
9633 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309634 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009635 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009636 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9637 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07009638 struct cfg80211_scan_request *req = NULL;
9639 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309640 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309641 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +05309642 tANI_U8 i;
Jeff Johnson295189b2012-06-20 16:38:30 -07009643
9644 ENTER();
9645
9646 hddLog(VOS_TRACE_LEVEL_INFO,
9647 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08009648 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009649 __func__, halHandle, pContext, (int) scanId, (int) status);
9650
Kiet Lamac06e2c2013-10-23 16:25:07 +05309651 pScanInfo->mScanPendingCounter = 0;
9652
Jeff Johnson295189b2012-06-20 16:38:30 -07009653 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309654 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009655 &pScanInfo->scan_req_completion_event,
9656 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309657 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009658 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309659 hddLog(VOS_TRACE_LEVEL_ERROR,
9660 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07009661 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009662 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009663 }
9664
Yue Maef608272013-04-08 23:09:17 -07009665 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07009666 {
9667 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009668 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009669 }
9670
9671 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309672 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07009673 {
9674 hddLog(VOS_TRACE_LEVEL_INFO,
9675 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009676 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07009677 (int) scanId);
9678 }
9679
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309680 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009681 pAdapter);
9682
9683 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309684 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009685
9686
9687 /* If any client wait scan result through WEXT
9688 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009689 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07009690 {
9691 /* The other scan request waiting for current scan finish
9692 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009693 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009694 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009695 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07009696 }
9697 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009698 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009699 {
9700 struct net_device *dev = pAdapter->dev;
9701 union iwreq_data wrqu;
9702 int we_event;
9703 char *msg;
9704
9705 memset(&wrqu, '\0', sizeof(wrqu));
9706 we_event = SIOCGIWSCAN;
9707 msg = NULL;
9708 wireless_send_event(dev, we_event, &wrqu, msg);
9709 }
9710 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009711 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009712
9713 /* Get the Scan Req */
9714 req = pAdapter->request;
9715
9716 if (!req)
9717 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009718 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009719 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07009720 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009721 }
9722
Jeff Johnson295189b2012-06-20 16:38:30 -07009723 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009724 /* Scan is no longer pending */
9725 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009726
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +05309727 /* last_scan_timestamp is used to decide if new scan
9728 * is needed or not on station interface. If last station
9729 * scan time and new station scan time is less then
9730 * last_scan_timestamp ; driver will return cached scan.
9731 */
9732 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
9733 {
9734 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
9735
9736 if ( req->n_channels )
9737 {
9738 for (i = 0; i < req->n_channels ; i++ )
9739 {
9740 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
9741 }
9742 /* store no of channel scanned */
9743 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
9744 }
9745
9746 }
9747
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07009748 /*
9749 * cfg80211_scan_done informing NL80211 about completion
9750 * of scanning
9751 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309752 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
9753 {
9754 aborted = true;
9755 }
9756 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009757 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07009758
Siddharth Bhal76972212014-10-15 16:22:51 +05309759 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
9760 /* Generate new random mac addr for next scan */
9761 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
9762 hdd_processSpoofMacAddrRequest(pHddCtx);
9763 }
9764
Jeff Johnsone7245742012-09-05 17:12:55 -07009765allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009766 /* release the wake lock at the end of the scan*/
9767 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009768
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009769 /* Acquire wakelock to handle the case where APP's tries to suspend
9770 * immediatly after the driver gets connect request(i.e after scan)
9771 * from supplicant, this result in app's is suspending and not able
9772 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309773 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009774
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009775#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05309776 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
9777 {
9778 wlan_hdd_tdls_scan_done_callback(pAdapter);
9779 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009780#endif
9781
Jeff Johnson295189b2012-06-20 16:38:30 -07009782 EXIT();
9783 return 0;
9784}
9785
9786/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05309787 * FUNCTION: hdd_isConnectionInProgress
9788 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009789 *
9790 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +05309791v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009792{
9793 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9794 hdd_station_ctx_t *pHddStaCtx = NULL;
9795 hdd_adapter_t *pAdapter = NULL;
9796 VOS_STATUS status = 0;
9797 v_U8_t staId = 0;
9798 v_U8_t *staMac = NULL;
9799
c_hpothu9b781ba2013-12-30 20:57:45 +05309800 if (TRUE == pHddCtx->btCoexModeSet)
9801 {
9802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05309803 FL("BTCoex Mode operation in progress"));
9804 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05309805 }
9806
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009807 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9808
9809 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9810 {
9811 pAdapter = pAdapterNode->pAdapter;
9812
9813 if( pAdapter )
9814 {
9815 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309816 "%s: Adapter with device mode %s (%d) exists",
9817 __func__, hdd_device_modetoString(pAdapter->device_mode),
9818 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +05309819 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +05309820 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9821 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
9822 (eConnectionState_Connecting ==
9823 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
9824 {
9825 hddLog(VOS_TRACE_LEVEL_ERROR,
9826 "%s: %p(%d) Connection is in progress", __func__,
9827 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
9828 return VOS_TRUE;
9829 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +05309830 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
9831 smeNeighborRoamIsHandoffInProgress(WLAN_HDD_GET_HAL_CTX(pAdapter)))
9832 {
9833 hddLog(VOS_TRACE_LEVEL_ERROR,
9834 "%s: %p(%d) Reassociation is in progress", __func__,
9835 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
9836 return VOS_TRUE;
9837 }
9838 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309839 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9840 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009841 {
9842 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9843 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309844 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009845 {
9846 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
9847 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009848 "%s: client " MAC_ADDRESS_STR
9849 " is in the middle of WPS/EAPOL exchange.", __func__,
9850 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309851 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009852 }
9853 }
9854 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
9855 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
9856 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05309857 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9858 ptSapContext pSapCtx = NULL;
9859 pSapCtx = VOS_GET_SAP_CB(pVosContext);
9860 if(pSapCtx == NULL){
9861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9862 FL("psapCtx is NULL"));
9863 return VOS_FALSE;
9864 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009865 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
9866 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05309867 if ((pSapCtx->aStaInfo[staId].isUsed) &&
9868 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009869 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05309870 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009871
9872 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009873 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
9874 "middle of WPS/EAPOL exchange.", __func__,
9875 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309876 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009877 }
9878 }
9879 }
9880 }
9881 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9882 pAdapterNode = pNext;
9883 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05309884 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309885}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009886
9887/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309888 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07009889 * this scan respond to scan trigger and update cfg80211 scan database
9890 * later, scan dump command can be used to recieve scan results
9891 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309892int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009893#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9894 struct net_device *dev,
9895#endif
9896 struct cfg80211_scan_request *request)
9897{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309898 hdd_adapter_t *pAdapter = NULL;
9899 hdd_context_t *pHddCtx = NULL;
9900 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309901 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009902 tCsrScanRequest scanRequest;
9903 tANI_U8 *channelList = NULL, i;
9904 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309905 int status;
9906 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009907 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +05309908 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009909
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309910#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
9911 struct net_device *dev = NULL;
9912 if (NULL == request)
9913 {
9914 hddLog(VOS_TRACE_LEVEL_ERROR,
9915 "%s: scan req param null", __func__);
9916 return -EINVAL;
9917 }
9918 dev = request->wdev->netdev;
9919#endif
9920
9921 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
9922 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9923 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9924
Jeff Johnson295189b2012-06-20 16:38:30 -07009925 ENTER();
9926
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309927
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309928 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9929 __func__, hdd_device_modetoString(pAdapter->device_mode),
9930 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309931
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309932 status = wlan_hdd_validate_context(pHddCtx);
9933
9934 if (0 != status)
9935 {
9936 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9937 "%s: HDD context is not valid", __func__);
9938 return status;
9939 }
9940
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309941 if (NULL == pwextBuf)
9942 {
9943 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
9944 __func__);
9945 return -EIO;
9946 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309947 cfg_param = pHddCtx->cfg_ini;
9948 pScanInfo = &pHddCtx->scan_info;
9949
Jeff Johnson295189b2012-06-20 16:38:30 -07009950#ifdef WLAN_BTAMP_FEATURE
9951 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009952 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07009953 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009954 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009955 "%s: No scanning when AMP is on", __func__);
9956 return -EOPNOTSUPP;
9957 }
9958#endif
9959 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009960 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009961 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009962 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309963 "%s: Not scanning on device_mode = %s (%d)",
9964 __func__, hdd_device_modetoString(pAdapter->device_mode),
9965 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009966 return -EOPNOTSUPP;
9967 }
9968
9969 if (TRUE == pScanInfo->mScanPending)
9970 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309971 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
9972 {
9973 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
9974 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009975 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009976 }
9977
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309978 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07009979 //Channel and action frame is pending
9980 //Otherwise Cancel Remain On Channel and allow Scan
9981 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009982 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07009983 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309984 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009985 return -EBUSY;
9986 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009987#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009988 /* if tdls disagree scan right now, return immediately.
9989 tdls will schedule the scan when scan is allowed. (return SUCCESS)
9990 or will reject the scan if any TDLS is in progress. (return -EBUSY)
9991 */
9992 status = wlan_hdd_tdls_scan_callback (pAdapter,
9993 wiphy,
9994#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9995 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07009996#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009997 request);
9998 if(status <= 0)
9999 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010000 if(!status)
10001 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
10002 "scan rejected %d", __func__, status);
10003 else
10004 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
10005 __func__, status);
10006
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010007 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010008 }
10009#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -070010010
Jeff Johnson295189b2012-06-20 16:38:30 -070010011 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
10012 {
10013 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080010014 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010015 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010016 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010017 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
10018 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010019 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010020 "%s: MAX TM Level Scan not allowed", __func__);
10021 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010022 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010023 }
10024 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
10025
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010026 /* Check if scan is allowed at this point of time.
10027 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010028 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010029 {
10030 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
10031 return -EBUSY;
10032 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010033
Jeff Johnson295189b2012-06-20 16:38:30 -070010034 vos_mem_zero( &scanRequest, sizeof(scanRequest));
10035
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010036 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
10037 (int)request->n_ssids);
10038
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010039
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010040 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
10041 * Becasue of this, driver is assuming that this is not wildcard scan and so
10042 * is not aging out the scan results.
10043 */
10044 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010045 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010046 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010047 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010048
10049 if ((request->ssids) && (0 < request->n_ssids))
10050 {
10051 tCsrSSIDInfo *SsidInfo;
10052 int j;
10053 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
10054 /* Allocate num_ssid tCsrSSIDInfo structure */
10055 SsidInfo = scanRequest.SSIDs.SSIDList =
10056 ( tCsrSSIDInfo *)vos_mem_malloc(
10057 request->n_ssids*sizeof(tCsrSSIDInfo));
10058
10059 if(NULL == scanRequest.SSIDs.SSIDList)
10060 {
10061 hddLog(VOS_TRACE_LEVEL_ERROR,
10062 "%s: memory alloc failed SSIDInfo buffer", __func__);
10063 return -ENOMEM;
10064 }
10065
10066 /* copy all the ssid's and their length */
10067 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
10068 {
10069 /* get the ssid length */
10070 SsidInfo->SSID.length = request->ssids[j].ssid_len;
10071 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
10072 SsidInfo->SSID.length);
10073 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
10074 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
10075 j, SsidInfo->SSID.ssId);
10076 }
10077 /* set the scan type to active */
10078 scanRequest.scanType = eSIR_ACTIVE_SCAN;
10079 }
10080 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070010081 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010082 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10083 TRACE_CODE_HDD_CFG80211_SCAN,
10084 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070010085 /* set the scan type to active */
10086 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010087 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010088 else
10089 {
10090 /*Set the scan type to default type, in this case it is ACTIVE*/
10091 scanRequest.scanType = pScanInfo->scan_mode;
10092 }
10093 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
10094 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070010095
10096 /* set BSSType to default type */
10097 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
10098
10099 /*TODO: scan the requested channels only*/
10100
10101 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010102 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070010103 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010104 hddLog(VOS_TRACE_LEVEL_WARN,
10105 "No of Scan Channels exceeded limit: %d", request->n_channels);
10106 request->n_channels = MAX_CHANNEL;
10107 }
10108
10109 hddLog(VOS_TRACE_LEVEL_INFO,
10110 "No of Scan Channels: %d", request->n_channels);
10111
10112
10113 if( request->n_channels )
10114 {
10115 char chList [(request->n_channels*5)+1];
10116 int len;
10117 channelList = vos_mem_malloc( request->n_channels );
10118 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053010119 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010120 hddLog(VOS_TRACE_LEVEL_ERROR,
10121 "%s: memory alloc failed channelList", __func__);
10122 status = -ENOMEM;
10123 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053010124 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010125
10126 for( i = 0, len = 0; i < request->n_channels ; i++ )
10127 {
10128 channelList[i] = request->channels[i]->hw_value;
10129 len += snprintf(chList+len, 5, "%d ", channelList[i]);
10130 }
10131
Nirav Shah20ac06f2013-12-12 18:14:06 +053010132 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010133 "Channel-List: %s ", chList);
10134 }
c_hpothu53512302014-04-15 18:49:53 +053010135
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010136 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
10137 scanRequest.ChannelInfo.ChannelList = channelList;
10138
10139 /* set requestType to full scan */
10140 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10141
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010142 /* if there is back to back scan happening in driver with in
10143 * nDeferScanTimeInterval interval driver should defer new scan request
10144 * and should provide last cached scan results instead of new channel list.
10145 * This rule is not applicable if scan is p2p scan.
10146 * This condition will work only in case when last request no of channels
10147 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053010148 * This should be done only in connected state
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010149 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010150
Agarwal Ashish57e84372014-12-05 18:26:53 +053010151 if ((VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
10152 {
10153 if ( pScanInfo->last_scan_timestamp !=0 &&
10154 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
10155 {
10156 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
10157 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
10158 vos_mem_compare(pScanInfo->last_scan_channelList,
10159 channelList, pScanInfo->last_scan_numChannels))
10160 {
10161 hddLog(VOS_TRACE_LEVEL_WARN,
10162 " New and old station scan time differ is less then %u",
10163 pHddCtx->cfg_ini->nDeferScanTimeInterval);
10164
10165 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010166 pAdapter);
10167
Agarwal Ashish57e84372014-12-05 18:26:53 +053010168 hddLog(VOS_TRACE_LEVEL_WARN,
10169 "Return old cached scan as all channels"
10170 "and no of channles are same");
10171 if (0 > ret)
10172 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010173
Agarwal Ashish57e84372014-12-05 18:26:53 +053010174 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
10175 return eHAL_STATUS_SUCCESS ;
10176 }
10177 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010178 }
10179
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010180 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10181 * search (Flush on both full scan and social scan but not on single
10182 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10183 */
10184
10185 /* Supplicant does single channel scan after 8-way handshake
10186 * and in that case driver shoudnt flush scan results. If
10187 * driver flushes the scan results here and unfortunately if
10188 * the AP doesnt respond to our probe req then association
10189 * fails which is not desired
10190 */
10191
10192 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
10193 {
10194 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
10195 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
10196 pAdapter->sessionId );
10197 }
10198
10199 if( request->ie_len )
10200 {
10201 /* save this for future association (join requires this) */
10202 /*TODO: Array needs to be converted to dynamic allocation,
10203 * as multiple ie.s can be sent in cfg80211_scan_request structure
10204 * CR 597966
10205 */
10206 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
10207 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
10208 pScanInfo->scanAddIE.length = request->ie_len;
10209
10210 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10211 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10212 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010213 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010214 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070010215 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010216 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
10217 memcpy( pwextBuf->roamProfile.addIEScan,
10218 request->ie, request->ie_len);
10219 }
10220 else
10221 {
10222 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
10223 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070010224 }
10225
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010226 }
10227 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
10228 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
10229
10230 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
10231 request->ie_len);
10232 if (pP2pIe != NULL)
10233 {
10234#ifdef WLAN_FEATURE_P2P_DEBUG
10235 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
10236 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
10237 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053010238 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010239 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
10240 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10241 "Go nego completed to Connection is started");
10242 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10243 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053010244 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010245 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
10246 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010247 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010248 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
10249 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10250 "Disconnected state to Connection is started");
10251 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10252 "for 4way Handshake");
10253 }
10254#endif
10255
10256 /* no_cck will be set during p2p find to disable 11b rates */
10257 if(TRUE == request->no_cck)
10258 {
10259 hddLog(VOS_TRACE_LEVEL_INFO,
10260 "%s: This is a P2P Search", __func__);
10261 scanRequest.p2pSearch = 1;
10262
10263 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053010264 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010265 /* set requestType to P2P Discovery */
10266 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
10267 }
10268
10269 /*
10270 Skip Dfs Channel in case of P2P Search
10271 if it is set in ini file
10272 */
10273 if(cfg_param->skipDfsChnlInP2pSearch)
10274 {
10275 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010276 }
10277 else
10278 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010279 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010280 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010281
Agarwal Ashish4f616132013-12-30 23:32:50 +053010282 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010283 }
10284 }
10285
10286 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
10287
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010288 /* acquire the wakelock to avoid the apps suspend during the scan. To
10289 * address the following issues.
10290 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
10291 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
10292 * for long time, this result in apps running at full power for long time.
10293 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
10294 * be stuck in full power because of resume BMPS
10295 */
10296 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -070010297
Nirav Shah20ac06f2013-12-12 18:14:06 +053010298 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10299 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010300 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
10301 scanRequest.requestType, scanRequest.scanType,
10302 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053010303 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
10304
Siddharth Bhal76972212014-10-15 16:22:51 +053010305 if (pHddCtx->spoofMacAddr.isEnabled)
10306 {
10307 hddLog(VOS_TRACE_LEVEL_INFO,
10308 "%s: MAC Spoofing enabled for current scan", __func__);
10309 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
10310 * to fill TxBds for probe request during current scan
10311 */
10312 WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
10313 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
10314 }
10315
Jeff Johnsone7245742012-09-05 17:12:55 -070010316 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010317 pAdapter->sessionId, &scanRequest, &scanId,
10318 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070010319
Jeff Johnson295189b2012-06-20 16:38:30 -070010320 if (eHAL_STATUS_SUCCESS != status)
10321 {
10322 hddLog(VOS_TRACE_LEVEL_ERROR,
10323 "%s: sme_ScanRequest returned error %d", __func__, status);
10324 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010325 if(eHAL_STATUS_RESOURCES == status)
10326 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010327 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
10328 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010329 status = -EBUSY;
10330 } else {
10331 status = -EIO;
10332 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010333 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -070010334 goto free_mem;
10335 }
10336
10337 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010338 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070010339 pAdapter->request = request;
10340 pScanInfo->scanId = scanId;
10341
10342 complete(&pScanInfo->scan_req_completion_event);
10343
10344free_mem:
10345 if( scanRequest.SSIDs.SSIDList )
10346 {
10347 vos_mem_free(scanRequest.SSIDs.SSIDList);
10348 }
10349
10350 if( channelList )
10351 vos_mem_free( channelList );
10352
10353 EXIT();
10354
10355 return status;
10356}
10357
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010358int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
10359#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10360 struct net_device *dev,
10361#endif
10362 struct cfg80211_scan_request *request)
10363{
10364 int ret;
10365
10366 vos_ssr_protect(__func__);
10367 ret = __wlan_hdd_cfg80211_scan(wiphy,
10368#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10369 dev,
10370#endif
10371 request);
10372 vos_ssr_unprotect(__func__);
10373
10374 return ret;
10375}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010376
10377void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
10378{
10379 v_U8_t iniDot11Mode =
10380 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
10381 eHddDot11Mode hddDot11Mode = iniDot11Mode;
10382
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010383 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
10384 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010385 switch ( iniDot11Mode )
10386 {
10387 case eHDD_DOT11_MODE_AUTO:
10388 case eHDD_DOT11_MODE_11ac:
10389 case eHDD_DOT11_MODE_11ac_ONLY:
10390#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053010391 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
10392 sme_IsFeatureSupportedByFW(DOT11AC) )
10393 hddDot11Mode = eHDD_DOT11_MODE_11ac;
10394 else
10395 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010396#else
10397 hddDot11Mode = eHDD_DOT11_MODE_11n;
10398#endif
10399 break;
10400 case eHDD_DOT11_MODE_11n:
10401 case eHDD_DOT11_MODE_11n_ONLY:
10402 hddDot11Mode = eHDD_DOT11_MODE_11n;
10403 break;
10404 default:
10405 hddDot11Mode = iniDot11Mode;
10406 break;
10407 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010408#ifdef WLAN_FEATURE_AP_HT40_24G
10409 if (operationChannel > SIR_11B_CHANNEL_END)
10410#endif
10411 {
10412 /* This call decides required channel bonding mode */
10413 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010414 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
10415 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010416 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010417}
10418
Jeff Johnson295189b2012-06-20 16:38:30 -070010419/*
10420 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010421 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010422 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010423int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010424 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010425{
10426 int status = 0;
10427 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080010428 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010429 v_U32_t roamId;
10430 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070010431 eCsrAuthType RSNAuthType;
10432
10433 ENTER();
10434
10435 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080010436 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10437
10438 status = wlan_hdd_validate_context(pHddCtx);
10439 if (status)
10440 {
10441 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10442 "%s: HDD context is not valid!", __func__);
10443 return status;
10444 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010445
Jeff Johnson295189b2012-06-20 16:38:30 -070010446 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
10447 {
10448 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
10449 return -EINVAL;
10450 }
10451
10452 pRoamProfile = &pWextState->roamProfile;
10453
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010454 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070010455 {
Jeff Johnsone7245742012-09-05 17:12:55 -070010456 hdd_station_ctx_t *pHddStaCtx;
10457 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010458
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010459 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070010460 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
10461 {
10462 /*QoS not enabled in cfg file*/
10463 pRoamProfile->uapsd_mask = 0;
10464 }
10465 else
10466 {
10467 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010468 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070010469 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
10470 }
10471
10472 pRoamProfile->SSIDs.numOfSSIDs = 1;
10473 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
10474 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010475 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070010476 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
10477 ssid, ssid_len);
10478
10479 if (bssid)
10480 {
10481 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
10482 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
10483 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010484 /* Save BSSID in seperate variable as well, as RoamProfile
10485 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070010486 case of join failure we should send valid BSSID to supplicant
10487 */
10488 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
10489 WNI_CFG_BSSID_LEN);
10490 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070010491 else
10492 {
10493 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
10494 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010495
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010496 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
10497 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010498 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
10499 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010500 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010501 /*set gen ie*/
10502 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
10503 /*set auth*/
10504 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
10505 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010506#ifdef FEATURE_WLAN_WAPI
10507 if (pAdapter->wapi_info.nWapiMode)
10508 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010509 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010510 switch (pAdapter->wapi_info.wapiAuthMode)
10511 {
10512 case WAPI_AUTH_MODE_PSK:
10513 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010514 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010515 pAdapter->wapi_info.wapiAuthMode);
10516 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
10517 break;
10518 }
10519 case WAPI_AUTH_MODE_CERT:
10520 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010521 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010522 pAdapter->wapi_info.wapiAuthMode);
10523 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
10524 break;
10525 }
10526 } // End of switch
10527 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
10528 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
10529 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010530 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010531 pRoamProfile->AuthType.numEntries = 1;
10532 pRoamProfile->EncryptionType.numEntries = 1;
10533 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10534 pRoamProfile->mcEncryptionType.numEntries = 1;
10535 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10536 }
10537 }
10538#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010539#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010540 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010541 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10542 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
10543 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010544 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
10545 sizeof (tSirGtkOffloadParams));
10546 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010547 }
10548#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010549 pRoamProfile->csrPersona = pAdapter->device_mode;
10550
Jeff Johnson32d95a32012-09-10 13:15:23 -070010551 if( operatingChannel )
10552 {
10553 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
10554 pRoamProfile->ChannelInfo.numOfChannels = 1;
10555 }
Chet Lanctot186b5732013-03-18 10:26:30 -070010556 else
10557 {
10558 pRoamProfile->ChannelInfo.ChannelList = NULL;
10559 pRoamProfile->ChannelInfo.numOfChannels = 0;
10560 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010561 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
10562 {
10563 hdd_select_cbmode(pAdapter,operatingChannel);
10564 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010565
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010566 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
10567 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010568 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010569 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010570 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
10571 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010572 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10573 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053010574 {
10575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10576 "%s: Set HDD connState to eConnectionState_Connecting",
10577 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010578 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
10579 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053010580 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010581 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010582 pAdapter->sessionId, pRoamProfile, &roamId);
10583
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010584 if ((eHAL_STATUS_SUCCESS != status) &&
10585 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10586 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010587
10588 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010589 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
10590 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
10591 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010592 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010593 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010594 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010595
10596 pRoamProfile->ChannelInfo.ChannelList = NULL;
10597 pRoamProfile->ChannelInfo.numOfChannels = 0;
10598
Jeff Johnson295189b2012-06-20 16:38:30 -070010599 }
10600 else
10601 {
10602 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
10603 return -EINVAL;
10604 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010605 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010606 return status;
10607}
10608
10609/*
10610 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
10611 * This function is used to set the authentication type (OPEN/SHARED).
10612 *
10613 */
10614static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
10615 enum nl80211_auth_type auth_type)
10616{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010617 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010618 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10619
10620 ENTER();
10621
10622 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010623 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070010624 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010625 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010626 hddLog(VOS_TRACE_LEVEL_INFO,
10627 "%s: set authentication type to AUTOSWITCH", __func__);
10628 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
10629 break;
10630
10631 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010632#ifdef WLAN_FEATURE_VOWIFI_11R
10633 case NL80211_AUTHTYPE_FT:
10634#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010635 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010636 "%s: set authentication type to OPEN", __func__);
10637 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
10638 break;
10639
10640 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010641 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010642 "%s: set authentication type to SHARED", __func__);
10643 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
10644 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010645#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010646 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010647 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010648 "%s: set authentication type to CCKM WPA", __func__);
10649 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
10650 break;
10651#endif
10652
10653
10654 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010655 hddLog(VOS_TRACE_LEVEL_ERROR,
10656 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010657 auth_type);
10658 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
10659 return -EINVAL;
10660 }
10661
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010662 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010663 pHddStaCtx->conn_info.authType;
10664 return 0;
10665}
10666
10667/*
10668 * FUNCTION: wlan_hdd_set_akm_suite
10669 * This function is used to set the key mgmt type(PSK/8021x).
10670 *
10671 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010672static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010673 u32 key_mgmt
10674 )
10675{
10676 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10677 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053010678 /* Should be in ieee802_11_defs.h */
10679#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
10680#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070010681 /*set key mgmt type*/
10682 switch(key_mgmt)
10683 {
10684 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053010685 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010686#ifdef WLAN_FEATURE_VOWIFI_11R
10687 case WLAN_AKM_SUITE_FT_PSK:
10688#endif
10689 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070010690 __func__);
10691 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
10692 break;
10693
10694 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053010695 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010696#ifdef WLAN_FEATURE_VOWIFI_11R
10697 case WLAN_AKM_SUITE_FT_8021X:
10698#endif
10699 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070010700 __func__);
10701 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10702 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010703#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010704#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
10705#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
10706 case WLAN_AKM_SUITE_CCKM:
10707 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
10708 __func__);
10709 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
10710 break;
10711#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070010712#ifndef WLAN_AKM_SUITE_OSEN
10713#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
10714 case WLAN_AKM_SUITE_OSEN:
10715 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
10716 __func__);
10717 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10718 break;
10719#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010720
10721 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010722 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010723 __func__, key_mgmt);
10724 return -EINVAL;
10725
10726 }
10727 return 0;
10728}
10729
10730/*
10731 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010732 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070010733 * (NONE/WEP40/WEP104/TKIP/CCMP).
10734 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010735static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
10736 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070010737 bool ucast
10738 )
10739{
10740 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010741 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010742 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10743
10744 ENTER();
10745
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010746 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010747 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010748 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070010749 __func__, cipher);
10750 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10751 }
10752 else
10753 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010754
Jeff Johnson295189b2012-06-20 16:38:30 -070010755 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010756 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010757 {
10758 case IW_AUTH_CIPHER_NONE:
10759 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10760 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010761
Jeff Johnson295189b2012-06-20 16:38:30 -070010762 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010763 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070010764 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010765
Jeff Johnson295189b2012-06-20 16:38:30 -070010766 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010767 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070010768 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010769
Jeff Johnson295189b2012-06-20 16:38:30 -070010770 case WLAN_CIPHER_SUITE_TKIP:
10771 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
10772 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010773
Jeff Johnson295189b2012-06-20 16:38:30 -070010774 case WLAN_CIPHER_SUITE_CCMP:
10775 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10776 break;
10777#ifdef FEATURE_WLAN_WAPI
10778 case WLAN_CIPHER_SUITE_SMS4:
10779 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
10780 break;
10781#endif
10782
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010783#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010784 case WLAN_CIPHER_SUITE_KRK:
10785 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
10786 break;
10787#endif
10788 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010789 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010790 __func__, cipher);
10791 return -EOPNOTSUPP;
10792 }
10793 }
10794
10795 if (ucast)
10796 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010797 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010798 __func__, encryptionType);
10799 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10800 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010801 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010802 encryptionType;
10803 }
10804 else
10805 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010806 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010807 __func__, encryptionType);
10808 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
10809 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
10810 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
10811 }
10812
10813 return 0;
10814}
10815
10816
10817/*
10818 * FUNCTION: wlan_hdd_cfg80211_set_ie
10819 * This function is used to parse WPA/RSN IE's.
10820 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010821int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
10822 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070010823 size_t ie_len
10824 )
10825{
10826 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10827 u8 *genie = ie;
10828 v_U16_t remLen = ie_len;
10829#ifdef FEATURE_WLAN_WAPI
10830 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
10831 u16 *tmp;
10832 v_U16_t akmsuiteCount;
10833 int *akmlist;
10834#endif
10835 ENTER();
10836
10837 /* clear previous assocAddIE */
10838 pWextState->assocAddIE.length = 0;
10839 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010840 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010841
10842 while (remLen >= 2)
10843 {
10844 v_U16_t eLen = 0;
10845 v_U8_t elementId;
10846 elementId = *genie++;
10847 eLen = *genie++;
10848 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010849
Arif Hussain6d2a3322013-11-17 19:50:10 -080010850 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070010851 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010852
10853 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070010854 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010855 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010856 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 -070010857 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010858 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010859 "%s: Invalid WPA IE", __func__);
10860 return -EINVAL;
10861 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010862 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070010863 {
10864 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010865 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010866 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010867
Jeff Johnson295189b2012-06-20 16:38:30 -070010868 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10869 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010870 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
10871 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010872 VOS_ASSERT(0);
10873 return -ENOMEM;
10874 }
10875 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10876 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10877 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010878
Jeff Johnson295189b2012-06-20 16:38:30 -070010879 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
10880 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10881 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10882 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010883 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
10884 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010885 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
10886 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10887 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
10888 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
10889 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
10890 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010891 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053010892 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010893 {
10894 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010895 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010896 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010897
Jeff Johnson295189b2012-06-20 16:38:30 -070010898 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10899 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010900 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10901 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010902 VOS_ASSERT(0);
10903 return -ENOMEM;
10904 }
10905 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10906 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10907 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010908
Jeff Johnson295189b2012-06-20 16:38:30 -070010909 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10910 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10911 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010912#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010913 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
10914 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010915 /*Consider WFD IE, only for P2P Client */
10916 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10917 {
10918 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010919 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010920 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010921
Jeff Johnson295189b2012-06-20 16:38:30 -070010922 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10923 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010924 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10925 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010926 VOS_ASSERT(0);
10927 return -ENOMEM;
10928 }
10929 // WFD IE is saved to Additional IE ; it should be accumulated to handle
10930 // WPS IE + P2P IE + WFD IE
10931 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10932 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010933
Jeff Johnson295189b2012-06-20 16:38:30 -070010934 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10935 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10936 }
10937#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010938 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010939 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010940 HS20_OUI_TYPE_SIZE)) )
10941 {
10942 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010943 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010944 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010945
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010946 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10947 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010948 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10949 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010950 VOS_ASSERT(0);
10951 return -ENOMEM;
10952 }
10953 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10954 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010955
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010956 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10957 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10958 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010959 /* Appending OSEN Information Element in Assiciation Request */
10960 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
10961 OSEN_OUI_TYPE_SIZE)) )
10962 {
10963 v_U16_t curAddIELen = pWextState->assocAddIE.length;
10964 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
10965 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010966
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010967 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10968 {
10969 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10970 "Need bigger buffer space");
10971 VOS_ASSERT(0);
10972 return -ENOMEM;
10973 }
10974 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10975 pWextState->assocAddIE.length += eLen + 2;
10976
10977 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
10978 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10979 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10980 }
10981
10982 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070010983 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
10984
10985 /* populating as ADDIE in beacon frames */
10986 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10987 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
10988 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
10989 {
10990 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10991 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10992 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10993 {
10994 hddLog(LOGE,
10995 "Coldn't pass "
10996 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
10997 }
10998 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
10999 else
11000 hddLog(LOGE,
11001 "Could not pass on "
11002 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
11003
11004 /* IBSS mode doesn't contain params->proberesp_ies still
11005 beaconIE's need to be populated in probe response frames */
11006 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
11007 {
11008 u16 rem_probe_resp_ie_len = eLen + 2;
11009 u8 probe_rsp_ie_len[3] = {0};
11010 u8 counter = 0;
11011
11012 /* Check Probe Resp Length if it is greater then 255 then
11013 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
11014 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
11015 not able Store More then 255 bytes into One Variable */
11016
11017 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
11018 {
11019 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
11020 {
11021 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
11022 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
11023 }
11024 else
11025 {
11026 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
11027 rem_probe_resp_ie_len = 0;
11028 }
11029 }
11030
11031 rem_probe_resp_ie_len = 0;
11032
11033 if (probe_rsp_ie_len[0] > 0)
11034 {
11035 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11036 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
11037 (tANI_U8*)(genie - 2),
11038 probe_rsp_ie_len[0], NULL,
11039 eANI_BOOLEAN_FALSE)
11040 == eHAL_STATUS_FAILURE)
11041 {
11042 hddLog(LOGE,
11043 "Could not pass"
11044 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
11045 }
11046 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
11047 }
11048
11049 if (probe_rsp_ie_len[1] > 0)
11050 {
11051 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11052 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
11053 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11054 probe_rsp_ie_len[1], NULL,
11055 eANI_BOOLEAN_FALSE)
11056 == eHAL_STATUS_FAILURE)
11057 {
11058 hddLog(LOGE,
11059 "Could not pass"
11060 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
11061 }
11062 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
11063 }
11064
11065 if (probe_rsp_ie_len[2] > 0)
11066 {
11067 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11068 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
11069 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11070 probe_rsp_ie_len[2], NULL,
11071 eANI_BOOLEAN_FALSE)
11072 == eHAL_STATUS_FAILURE)
11073 {
11074 hddLog(LOGE,
11075 "Could not pass"
11076 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
11077 }
11078 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
11079 }
11080
11081 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11082 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
11083 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11084 {
11085 hddLog(LOGE,
11086 "Could not pass"
11087 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
11088 }
11089 }
11090 else
11091 {
11092 // Reset WNI_CFG_PROBE_RSP Flags
11093 wlan_hdd_reset_prob_rspies(pAdapter);
11094
11095 hddLog(VOS_TRACE_LEVEL_INFO,
11096 "%s: No Probe Response IE received in set beacon",
11097 __func__);
11098 }
11099 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011100 break;
11101 case DOT11F_EID_RSN:
11102 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
11103 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11104 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
11105 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
11106 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
11107 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011108 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
11109 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011110 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011111 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011112 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011113 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011114
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011115 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11116 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011117 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11118 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011119 VOS_ASSERT(0);
11120 return -ENOMEM;
11121 }
11122 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11123 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011124
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011125 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11126 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11127 break;
11128 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011129#ifdef FEATURE_WLAN_WAPI
11130 case WLAN_EID_WAPI:
11131 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011132 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011133 pAdapter->wapi_info.nWapiMode);
11134 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011135 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070011136 akmsuiteCount = WPA_GET_LE16(tmp);
11137 tmp = tmp + 1;
11138 akmlist = (int *)(tmp);
11139 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
11140 {
11141 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
11142 }
11143 else
11144 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011145 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070011146 VOS_ASSERT(0);
11147 return -EINVAL;
11148 }
11149
11150 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
11151 {
11152 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011153 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011154 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011155 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011156 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011157 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011158 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011159 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011160 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
11161 }
11162 break;
11163#endif
11164 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011165 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011166 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011167 /* when Unknown IE is received we should break and continue
11168 * to the next IE in the buffer instead we were returning
11169 * so changing this to break */
11170 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011171 }
11172 genie += eLen;
11173 remLen -= eLen;
11174 }
11175 EXIT();
11176 return 0;
11177}
11178
11179/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053011180 * FUNCTION: hdd_isWPAIEPresent
11181 * Parse the received IE to find the WPA IE
11182 *
11183 */
11184static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
11185{
11186 v_U8_t eLen = 0;
11187 v_U16_t remLen = ie_len;
11188 v_U8_t elementId = 0;
11189
11190 while (remLen >= 2)
11191 {
11192 elementId = *ie++;
11193 eLen = *ie++;
11194 remLen -= 2;
11195 if (eLen > remLen)
11196 {
11197 hddLog(VOS_TRACE_LEVEL_ERROR,
11198 "%s: IE length is wrong %d", __func__, eLen);
11199 return FALSE;
11200 }
11201 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
11202 {
11203 /* OUI - 0x00 0X50 0XF2
11204 WPA Information Element - 0x01
11205 WPA version - 0x01*/
11206 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
11207 return TRUE;
11208 }
11209 ie += eLen;
11210 remLen -= eLen;
11211 }
11212 return FALSE;
11213}
11214
11215/*
Jeff Johnson295189b2012-06-20 16:38:30 -070011216 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011217 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011218 * parameters during connect operation.
11219 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011220int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011221 struct cfg80211_connect_params *req
11222 )
11223{
11224 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011225 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011226 ENTER();
11227
11228 /*set wpa version*/
11229 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
11230
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011231 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011232 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053011233 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011234 {
11235 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11236 }
11237 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
11238 {
11239 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11240 }
11241 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011242
11243 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011244 pWextState->wpaVersion);
11245
11246 /*set authentication type*/
11247 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
11248
11249 if (0 > status)
11250 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011251 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011252 "%s: failed to set authentication type ", __func__);
11253 return status;
11254 }
11255
11256 /*set key mgmt type*/
11257 if (req->crypto.n_akm_suites)
11258 {
11259 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
11260 if (0 > status)
11261 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011262 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070011263 __func__);
11264 return status;
11265 }
11266 }
11267
11268 /*set pairwise cipher type*/
11269 if (req->crypto.n_ciphers_pairwise)
11270 {
11271 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
11272 req->crypto.ciphers_pairwise[0], true);
11273 if (0 > status)
11274 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011275 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011276 "%s: failed to set unicast cipher type", __func__);
11277 return status;
11278 }
11279 }
11280 else
11281 {
11282 /*Reset previous cipher suite to none*/
11283 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
11284 if (0 > status)
11285 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011286 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011287 "%s: failed to set unicast cipher type", __func__);
11288 return status;
11289 }
11290 }
11291
11292 /*set group cipher type*/
11293 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
11294 false);
11295
11296 if (0 > status)
11297 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011298 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070011299 __func__);
11300 return status;
11301 }
11302
Chet Lanctot186b5732013-03-18 10:26:30 -070011303#ifdef WLAN_FEATURE_11W
11304 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
11305#endif
11306
Jeff Johnson295189b2012-06-20 16:38:30 -070011307 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
11308 if (req->ie_len)
11309 {
11310 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
11311 if ( 0 > status)
11312 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011313 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011314 __func__);
11315 return status;
11316 }
11317 }
11318
11319 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011320 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011321 {
11322 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
11323 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
11324 )
11325 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011326 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070011327 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
11328 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011329 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011330 __func__);
11331 return -EOPNOTSUPP;
11332 }
11333 else
11334 {
11335 u8 key_len = req->key_len;
11336 u8 key_idx = req->key_idx;
11337
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011338 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011339 && (CSR_MAX_NUM_KEY > key_idx)
11340 )
11341 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011342 hddLog(VOS_TRACE_LEVEL_INFO,
11343 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011344 __func__, key_idx, key_len);
11345 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011346 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011347 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011348 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011349 (u8)key_len;
11350 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
11351 }
11352 }
11353 }
11354 }
11355
11356 return status;
11357}
11358
11359/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011360 * FUNCTION: wlan_hdd_try_disconnect
11361 * This function is used to disconnect from previous
11362 * connection
11363 */
11364static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
11365{
11366 long ret = 0;
11367 hdd_station_ctx_t *pHddStaCtx;
11368 eMib_dot11DesiredBssType connectedBssType;
11369
11370 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11371
11372 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
11373
11374 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
11375 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
11376 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
11377 {
11378 /* Issue disconnect to CSR */
11379 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11380 if( eHAL_STATUS_SUCCESS ==
11381 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11382 pAdapter->sessionId,
11383 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11384 {
11385 ret = wait_for_completion_interruptible_timeout(
11386 &pAdapter->disconnect_comp_var,
11387 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11388 if (0 >= ret)
11389 {
11390 hddLog(LOGE, FL("Failed to receive disconnect event"));
11391 return -EALREADY;
11392 }
11393 }
11394 }
11395 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
11396 {
11397 ret = wait_for_completion_interruptible_timeout(
11398 &pAdapter->disconnect_comp_var,
11399 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11400 if (0 >= ret)
11401 {
11402 hddLog(LOGE, FL("Failed to receive disconnect event"));
11403 return -EALREADY;
11404 }
11405 }
11406
11407 return 0;
11408}
11409
11410/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053011411 * FUNCTION: __wlan_hdd_cfg80211_connect
11412 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011413 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011414static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011415 struct net_device *ndev,
11416 struct cfg80211_connect_params *req
11417 )
11418{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011419 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011420 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011421 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053011422 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011423
11424 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011425
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011426 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11427 TRACE_CODE_HDD_CFG80211_CONNECT,
11428 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011429 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011430 "%s: device_mode = %s (%d)", __func__,
11431 hdd_device_modetoString(pAdapter->device_mode),
11432 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011433
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011434 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011435 if (!pHddCtx)
11436 {
11437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11438 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011439 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011440 }
11441
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011442 status = wlan_hdd_validate_context(pHddCtx);
11443
11444 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011445 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11447 "%s: HDD context is not valid", __func__);
11448 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011449 }
11450
Agarwal Ashish51325b52014-06-16 16:50:49 +053011451 if (vos_max_concurrent_connections_reached()) {
11452 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11453 return -ECONNREFUSED;
11454 }
11455
Jeff Johnson295189b2012-06-20 16:38:30 -070011456#ifdef WLAN_BTAMP_FEATURE
11457 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011458 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070011459 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011460 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011461 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011462 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070011463 }
11464#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011465
11466 //If Device Mode is Station Concurrent Sessions Exit BMps
11467 //P2P Mode will be taken care in Open/close adapter
11468 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011469 (vos_concurrent_open_sessions_running())) {
11470 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
11471 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011472 }
11473
11474 /*Try disconnecting if already in connected state*/
11475 status = wlan_hdd_try_disconnect(pAdapter);
11476 if ( 0 > status)
11477 {
11478 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11479 " connection"));
11480 return -EALREADY;
11481 }
11482
Jeff Johnson295189b2012-06-20 16:38:30 -070011483 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011484 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070011485
11486 if ( 0 > status)
11487 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011488 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070011489 __func__);
11490 return status;
11491 }
Mohit Khanna765234a2012-09-11 15:08:35 -070011492 if ( req->channel )
11493 {
11494 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
11495 req->ssid_len, req->bssid,
11496 req->channel->hw_value);
11497 }
11498 else
11499 {
11500 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011501 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070011502 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011503
11504 if (0 > status)
11505 {
11506 //ReEnable BMPS if disabled
11507 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
11508 (NULL != pHddCtx))
11509 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011510 if (pHddCtx->hdd_wlan_suspended)
11511 {
11512 hdd_set_pwrparams(pHddCtx);
11513 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011514 //ReEnable Bmps and Imps back
11515 hdd_enable_bmps_imps(pHddCtx);
11516 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011517 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011518 return status;
11519 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011520 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011521 EXIT();
11522 return status;
11523}
11524
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011525static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
11526 struct net_device *ndev,
11527 struct cfg80211_connect_params *req)
11528{
11529 int ret;
11530 vos_ssr_protect(__func__);
11531 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
11532 vos_ssr_unprotect(__func__);
11533
11534 return ret;
11535}
Jeff Johnson295189b2012-06-20 16:38:30 -070011536
11537/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011538 * FUNCTION: wlan_hdd_disconnect
11539 * This function is used to issue a disconnect request to SME
11540 */
11541int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
11542{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011543 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011544 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011545 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011546 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011547
11548 status = wlan_hdd_validate_context(pHddCtx);
11549
11550 if (0 != status)
11551 {
11552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11553 "%s: HDD context is not valid", __func__);
11554 return status;
11555 }
11556
11557 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011558
Agarwal Ashish47d18112014-08-04 19:55:07 +053011559 /* Need to apply spin lock before decreasing active sessions
11560 * as there can be chance for double decrement if context switch
11561 * Calls hdd_DisConnectHandler.
11562 */
11563
11564 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011565 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11566 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011567 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11568 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053011569 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
11570 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011571
Abhishek Singhf4669da2014-05-26 15:07:49 +053011572 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053011573 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
11574
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011575 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011576
Mihir Shete182a0b22014-08-18 16:08:48 +053011577 /*
11578 * stop tx queues before deleting STA/BSS context from the firmware.
11579 * tx has to be disabled because the firmware can get busy dropping
11580 * the tx frames after BSS/STA has been deleted and will not send
11581 * back a response resulting in WDI timeout
11582 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053011583 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053011584 netif_tx_disable(pAdapter->dev);
11585 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011586
Mihir Shete182a0b22014-08-18 16:08:48 +053011587 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011588 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11589 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011590 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
11591 {
11592 hddLog(VOS_TRACE_LEVEL_INFO,
11593 FL("status = %d, already disconnected"),
11594 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011595
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011596 }
11597 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011598 {
11599 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011600 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011601 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011602 result = -EINVAL;
11603 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011604 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011605 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011606 &pAdapter->disconnect_comp_var,
11607 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011608 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011609 {
11610 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011611 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011612 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011613 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011614 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011615 {
11616 hddLog(VOS_TRACE_LEVEL_ERROR,
11617 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011618 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011619 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011620disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11622 FL("Set HDD connState to eConnectionState_NotConnected"));
11623 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
11624
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011625 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011626}
11627
11628
11629/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011630 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070011631 * This function is used to issue a disconnect request to SME
11632 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011633static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011634 struct net_device *dev,
11635 u16 reason
11636 )
11637{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011638 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011639 tCsrRoamProfile *pRoamProfile =
11640 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011641 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011642 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11643 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011644#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011645 tANI_U8 staIdx;
11646#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011647
Jeff Johnson295189b2012-06-20 16:38:30 -070011648 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011649
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011650 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11651 TRACE_CODE_HDD_CFG80211_DISCONNECT,
11652 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011653 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
11654 __func__, hdd_device_modetoString(pAdapter->device_mode),
11655 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011656
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011657 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
11658 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070011659
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011660 status = wlan_hdd_validate_context(pHddCtx);
11661
11662 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011663 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11665 "%s: HDD context is not valid", __func__);
11666 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011667 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011668
Jeff Johnson295189b2012-06-20 16:38:30 -070011669 if (NULL != pRoamProfile)
11670 {
11671 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011672 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
11673 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070011674 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011675 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070011676 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011677 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070011678 switch(reason)
11679 {
11680 case WLAN_REASON_MIC_FAILURE:
11681 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
11682 break;
11683
11684 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
11685 case WLAN_REASON_DISASSOC_AP_BUSY:
11686 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
11687 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
11688 break;
11689
11690 case WLAN_REASON_PREV_AUTH_NOT_VALID:
11691 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053011692 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070011693 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
11694 break;
11695
Jeff Johnson295189b2012-06-20 16:38:30 -070011696 default:
11697 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
11698 break;
11699 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011700 pScanInfo = &pHddCtx->scan_info;
11701 if (pScanInfo->mScanPending)
11702 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011703 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011704 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011705 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011706 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011707 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011708
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011709#ifdef FEATURE_WLAN_TDLS
11710 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011711 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011712 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011713 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
11714 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011715 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011716 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011717 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011718 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011719 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011720 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011721 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011722 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011723 pAdapter->sessionId,
11724 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011725 }
11726 }
11727#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011728 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011729 status = wlan_hdd_disconnect(pAdapter, reasonCode);
11730 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070011731 {
11732 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011733 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011734 __func__, (int)status );
11735 return -EINVAL;
11736 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011737 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011738 else
11739 {
11740 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
11741 "called while in %d state", __func__,
11742 pHddStaCtx->conn_info.connState);
11743 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011744 }
11745 else
11746 {
11747 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
11748 }
11749
11750 return status;
11751}
11752
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011753static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
11754 struct net_device *dev,
11755 u16 reason
11756 )
11757{
11758 int ret;
11759 vos_ssr_protect(__func__);
11760 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
11761 vos_ssr_unprotect(__func__);
11762
11763 return ret;
11764}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011765
Jeff Johnson295189b2012-06-20 16:38:30 -070011766/*
11767 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011768 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011769 * settings in IBSS mode.
11770 */
11771static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011772 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011773 struct cfg80211_ibss_params *params
11774 )
11775{
11776 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011777 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011778 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11779 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011780
Jeff Johnson295189b2012-06-20 16:38:30 -070011781 ENTER();
11782
11783 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070011784 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070011785
11786 if (params->ie_len && ( NULL != params->ie) )
11787 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011788 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11789 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011790 {
11791 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11792 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11793 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011794 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011795 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011796 tDot11fIEWPA dot11WPAIE;
11797 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011798 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011799
Wilson Yang00256342013-10-10 23:13:38 -070011800 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011801 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11802 params->ie_len, DOT11F_EID_WPA);
11803 if ( NULL != ie )
11804 {
11805 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11806 // Unpack the WPA IE
11807 //Skip past the EID byte and length byte - and four byte WiFi OUI
11808 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
11809 &ie[2+4],
11810 ie[1] - 4,
11811 &dot11WPAIE);
11812 /*Extract the multicast cipher, the encType for unicast
11813 cipher for wpa-none is none*/
11814 encryptionType =
11815 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
11816 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011817 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011818
Jeff Johnson295189b2012-06-20 16:38:30 -070011819 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
11820
11821 if (0 > status)
11822 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011823 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011824 __func__);
11825 return status;
11826 }
11827 }
11828
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011829 pWextState->roamProfile.AuthType.authType[0] =
11830 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011831 eCSR_AUTH_TYPE_OPEN_SYSTEM;
11832
11833 if (params->privacy)
11834 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011835 /* Security enabled IBSS, At this time there is no information available
11836 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070011837 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011838 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070011839 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011840 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070011841 *enable privacy bit in beacons */
11842
11843 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11844 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011845 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
11846 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070011847 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11848 pWextState->roamProfile.EncryptionType.numEntries = 1;
11849 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070011850 return status;
11851}
11852
11853/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011854 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011855 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011856 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011857static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011858 struct net_device *dev,
11859 struct cfg80211_ibss_params *params
11860 )
11861{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011862 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011863 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11864 tCsrRoamProfile *pRoamProfile;
11865 int status;
krunal sonie9002db2013-11-25 14:24:17 -080011866 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011867 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11868 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011869
11870 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011871
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011872 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11873 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
11874 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011875 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011876 "%s: device_mode = %s (%d)", __func__,
11877 hdd_device_modetoString(pAdapter->device_mode),
11878 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011879
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011880 status = wlan_hdd_validate_context(pHddCtx);
11881
11882 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011883 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011884 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11885 "%s: HDD context is not valid", __func__);
11886 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011887 }
11888
11889 if (NULL == pWextState)
11890 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011891 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011892 __func__);
11893 return -EIO;
11894 }
11895
Agarwal Ashish51325b52014-06-16 16:50:49 +053011896 if (vos_max_concurrent_connections_reached()) {
11897 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11898 return -ECONNREFUSED;
11899 }
11900
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011901 /*Try disconnecting if already in connected state*/
11902 status = wlan_hdd_try_disconnect(pAdapter);
11903 if ( 0 > status)
11904 {
11905 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11906 " IBSS connection"));
11907 return -EALREADY;
11908 }
11909
Jeff Johnson295189b2012-06-20 16:38:30 -070011910 pRoamProfile = &pWextState->roamProfile;
11911
11912 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
11913 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011914 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011915 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011916 return -EINVAL;
11917 }
11918
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011919 /* BSSID is provided by upper layers hence no need to AUTO generate */
11920 if (NULL != params->bssid) {
11921 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11922 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
11923 hddLog (VOS_TRACE_LEVEL_ERROR,
11924 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11925 return -EIO;
11926 }
11927 }
krunal sonie9002db2013-11-25 14:24:17 -080011928 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
11929 {
11930 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11931 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
11932 {
11933 hddLog (VOS_TRACE_LEVEL_ERROR,
11934 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11935 return -EIO;
11936 }
11937 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
11938 if (!params->bssid)
11939 {
11940 hddLog (VOS_TRACE_LEVEL_ERROR,
11941 "%s:Failed memory allocation", __func__);
11942 return -EIO;
11943 }
11944 vos_mem_copy((v_U8_t *)params->bssid,
11945 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
11946 VOS_MAC_ADDR_SIZE);
11947 alloc_bssid = VOS_TRUE;
11948 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011949
Jeff Johnson295189b2012-06-20 16:38:30 -070011950 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070011951 if (NULL !=
11952#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11953 params->chandef.chan)
11954#else
11955 params->channel)
11956#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011957 {
11958 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011959 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
11960 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
11961 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
11962 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011963
11964 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011965 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070011966 ieee80211_frequency_to_channel(
11967#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11968 params->chandef.chan->center_freq);
11969#else
11970 params->channel->center_freq);
11971#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011972
11973 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
11974 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070011975 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011976 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
11977 __func__);
11978 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070011979 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011980
11981 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011982 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011983 if (channelNum == validChan[indx])
11984 {
11985 break;
11986 }
11987 }
11988 if (indx >= numChans)
11989 {
11990 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011991 __func__, channelNum);
11992 return -EINVAL;
11993 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011994 /* Set the Operational Channel */
11995 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
11996 channelNum);
11997 pRoamProfile->ChannelInfo.numOfChannels = 1;
11998 pHddStaCtx->conn_info.operationChannel = channelNum;
11999 pRoamProfile->ChannelInfo.ChannelList =
12000 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070012001 }
12002
12003 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012004 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070012005 if (status < 0)
12006 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012007 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070012008 __func__);
12009 return status;
12010 }
12011
12012 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012013 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012014 params->ssid_len, params->bssid,
12015 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012016
12017 if (0 > status)
12018 {
12019 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
12020 return status;
12021 }
12022
krunal sonie9002db2013-11-25 14:24:17 -080012023 if (NULL != params->bssid &&
12024 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
12025 alloc_bssid == VOS_TRUE)
12026 {
12027 vos_mem_free(params->bssid);
12028 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012029 return 0;
12030}
12031
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012032static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
12033 struct net_device *dev,
12034 struct cfg80211_ibss_params *params
12035 )
12036{
12037 int ret = 0;
12038
12039 vos_ssr_protect(__func__);
12040 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
12041 vos_ssr_unprotect(__func__);
12042
12043 return ret;
12044}
12045
Jeff Johnson295189b2012-06-20 16:38:30 -070012046/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012047 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012048 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012049 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012050static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012051 struct net_device *dev
12052 )
12053{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012054 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012055 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12056 tCsrRoamProfile *pRoamProfile;
12057 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012058 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012059
12060 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012061
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012062 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12063 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
12064 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012065 status = wlan_hdd_validate_context(pHddCtx);
12066
12067 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012068 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012069 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12070 "%s: HDD context is not valid", __func__);
12071 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012072 }
12073
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012074 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
12075 hdd_device_modetoString(pAdapter->device_mode),
12076 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012077 if (NULL == pWextState)
12078 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012079 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012080 __func__);
12081 return -EIO;
12082 }
12083
12084 pRoamProfile = &pWextState->roamProfile;
12085
12086 /* Issue disconnect only if interface type is set to IBSS */
12087 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
12088 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012089 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070012090 __func__);
12091 return -EINVAL;
12092 }
12093
12094 /* Issue Disconnect request */
12095 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12096 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12097 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
12098
12099 return 0;
12100}
12101
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012102static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
12103 struct net_device *dev
12104 )
12105{
12106 int ret = 0;
12107
12108 vos_ssr_protect(__func__);
12109 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
12110 vos_ssr_unprotect(__func__);
12111
12112 return ret;
12113}
12114
Jeff Johnson295189b2012-06-20 16:38:30 -070012115/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012116 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070012117 * This function is used to set the phy parameters
12118 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
12119 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012120static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012121 u32 changed)
12122{
12123 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
12124 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012125 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012126
12127 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012128 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12129 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
12130 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012131 status = wlan_hdd_validate_context(pHddCtx);
12132
12133 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012134 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12136 "%s: HDD context is not valid", __func__);
12137 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012138 }
12139
Jeff Johnson295189b2012-06-20 16:38:30 -070012140 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
12141 {
12142 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
12143 WNI_CFG_RTS_THRESHOLD_STAMAX :
12144 wiphy->rts_threshold;
12145
12146 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012147 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070012148 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012149 hddLog(VOS_TRACE_LEVEL_ERROR,
12150 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012151 __func__, rts_threshold);
12152 return -EINVAL;
12153 }
12154
12155 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
12156 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012157 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012158 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012159 hddLog(VOS_TRACE_LEVEL_ERROR,
12160 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012161 __func__, rts_threshold);
12162 return -EIO;
12163 }
12164
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012165 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012166 rts_threshold);
12167 }
12168
12169 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
12170 {
12171 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
12172 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
12173 wiphy->frag_threshold;
12174
12175 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012176 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012177 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012178 hddLog(VOS_TRACE_LEVEL_ERROR,
12179 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012180 frag_threshold);
12181 return -EINVAL;
12182 }
12183
12184 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
12185 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012186 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012187 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012188 hddLog(VOS_TRACE_LEVEL_ERROR,
12189 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012190 __func__, frag_threshold);
12191 return -EIO;
12192 }
12193
12194 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
12195 frag_threshold);
12196 }
12197
12198 if ((changed & WIPHY_PARAM_RETRY_SHORT)
12199 || (changed & WIPHY_PARAM_RETRY_LONG))
12200 {
12201 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
12202 wiphy->retry_short :
12203 wiphy->retry_long;
12204
12205 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
12206 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
12207 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012208 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012209 __func__, retry_value);
12210 return -EINVAL;
12211 }
12212
12213 if (changed & WIPHY_PARAM_RETRY_SHORT)
12214 {
12215 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
12216 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012217 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012218 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012219 hddLog(VOS_TRACE_LEVEL_ERROR,
12220 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012221 __func__, retry_value);
12222 return -EIO;
12223 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012224 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012225 __func__, retry_value);
12226 }
12227 else if (changed & WIPHY_PARAM_RETRY_SHORT)
12228 {
12229 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
12230 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012231 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012232 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012233 hddLog(VOS_TRACE_LEVEL_ERROR,
12234 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012235 __func__, retry_value);
12236 return -EIO;
12237 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012238 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012239 __func__, retry_value);
12240 }
12241 }
12242
12243 return 0;
12244}
12245
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012246static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
12247 u32 changed)
12248{
12249 int ret;
12250
12251 vos_ssr_protect(__func__);
12252 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
12253 vos_ssr_unprotect(__func__);
12254
12255 return ret;
12256}
12257
Jeff Johnson295189b2012-06-20 16:38:30 -070012258/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012259 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012260 * This function is used to set the txpower
12261 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012262static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012263#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12264 struct wireless_dev *wdev,
12265#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012266#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012267 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012268#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012269 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012270#endif
12271 int dbm)
12272{
12273 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012274 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012275 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12276 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012277 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012278
12279 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012280 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12281 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
12282 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012283 status = wlan_hdd_validate_context(pHddCtx);
12284
12285 if (0 != status)
12286 {
12287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12288 "%s: HDD context is not valid", __func__);
12289 return status;
12290 }
12291
12292 hHal = pHddCtx->hHal;
12293
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012294 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
12295 dbm, ccmCfgSetCallback,
12296 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012297 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012298 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012299 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
12300 return -EIO;
12301 }
12302
12303 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
12304 dbm);
12305
12306 switch(type)
12307 {
12308 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
12309 /* Fall through */
12310 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
12311 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
12312 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012313 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
12314 __func__);
12315 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012316 }
12317 break;
12318 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012319 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012320 __func__);
12321 return -EOPNOTSUPP;
12322 break;
12323 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012324 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
12325 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070012326 return -EIO;
12327 }
12328
12329 return 0;
12330}
12331
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012332static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
12333#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12334 struct wireless_dev *wdev,
12335#endif
12336#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12337 enum tx_power_setting type,
12338#else
12339 enum nl80211_tx_power_setting type,
12340#endif
12341 int dbm)
12342{
12343 int ret;
12344 vos_ssr_protect(__func__);
12345 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
12346#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12347 wdev,
12348#endif
12349#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12350 type,
12351#else
12352 type,
12353#endif
12354 dbm);
12355 vos_ssr_unprotect(__func__);
12356
12357 return ret;
12358}
12359
Jeff Johnson295189b2012-06-20 16:38:30 -070012360/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012361 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012362 * This function is used to read the txpower
12363 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012364static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012365#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12366 struct wireless_dev *wdev,
12367#endif
12368 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070012369{
12370
12371 hdd_adapter_t *pAdapter;
12372 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012373 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012374
Jeff Johnsone7245742012-09-05 17:12:55 -070012375 ENTER();
12376
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012377 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012378
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012379 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012380 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012381 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12382 "%s: HDD context is not valid", __func__);
12383 *dbm = 0;
12384 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012385 }
12386
Jeff Johnson295189b2012-06-20 16:38:30 -070012387 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
12388 if (NULL == pAdapter)
12389 {
12390 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
12391 return -ENOENT;
12392 }
12393
12394 wlan_hdd_get_classAstats(pAdapter);
12395 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
12396
Jeff Johnsone7245742012-09-05 17:12:55 -070012397 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012398 return 0;
12399}
12400
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012401static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
12402#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12403 struct wireless_dev *wdev,
12404#endif
12405 int *dbm)
12406{
12407 int ret;
12408
12409 vos_ssr_protect(__func__);
12410 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
12411#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12412 wdev,
12413#endif
12414 dbm);
12415 vos_ssr_unprotect(__func__);
12416
12417 return ret;
12418}
12419
12420
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012421static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070012422 u8* mac, struct station_info *sinfo)
12423{
12424 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12425 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12426 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053012427 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070012428
12429 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
12430 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012431
12432 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
12433 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
12434 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
12435 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
12436 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
12437 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
12438 tANI_U16 maxRate = 0;
12439 tANI_U16 myRate;
12440 tANI_U16 currentRate = 0;
12441 tANI_U8 maxSpeedMCS = 0;
12442 tANI_U8 maxMCSIdx = 0;
12443 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053012444 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012445 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012446 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012447
Leo Chang6f8870f2013-03-26 18:11:36 -070012448#ifdef WLAN_FEATURE_11AC
12449 tANI_U32 vht_mcs_map;
12450 eDataRate11ACMaxMcs vhtMaxMcs;
12451#endif /* WLAN_FEATURE_11AC */
12452
Jeff Johnsone7245742012-09-05 17:12:55 -070012453 ENTER();
12454
Jeff Johnson295189b2012-06-20 16:38:30 -070012455 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
12456 (0 == ssidlen))
12457 {
12458 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
12459 " Invalid ssidlen, %d", __func__, ssidlen);
12460 /*To keep GUI happy*/
12461 return 0;
12462 }
12463
Mukul Sharma811205f2014-07-09 21:07:30 +053012464 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
12465 {
12466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12467 "%s: Roaming in progress, so unable to proceed this request", __func__);
12468 return 0;
12469 }
12470
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012471 status = wlan_hdd_validate_context(pHddCtx);
12472
12473 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012474 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12476 "%s: HDD context is not valid", __func__);
12477 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012478 }
12479
Jeff Johnson295189b2012-06-20 16:38:30 -070012480
Kiet Lam3b17fc82013-09-27 05:24:08 +053012481 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
12482 sinfo->filled |= STATION_INFO_SIGNAL;
12483
c_hpothu09f19542014-05-30 21:53:31 +053012484 wlan_hdd_get_station_stats(pAdapter);
12485 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
12486
12487 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053012488 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
12489 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053012490 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053012491 {
12492 rate_flags = pAdapter->maxRateFlags;
12493 }
c_hpothu44ff4e02014-05-08 00:13:57 +053012494
Jeff Johnson295189b2012-06-20 16:38:30 -070012495 //convert to the UI units of 100kbps
12496 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
12497
12498#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070012499 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 -070012500 sinfo->signal,
12501 pCfg->reportMaxLinkSpeed,
12502 myRate,
12503 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012504 (int) pCfg->linkSpeedRssiMid,
12505 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070012506 (int) rate_flags,
12507 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012508#endif //LINKSPEED_DEBUG_ENABLED
12509
12510 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
12511 {
12512 // we do not want to necessarily report the current speed
12513 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
12514 {
12515 // report the max possible speed
12516 rssidx = 0;
12517 }
12518 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
12519 {
12520 // report the max possible speed with RSSI scaling
12521 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
12522 {
12523 // report the max possible speed
12524 rssidx = 0;
12525 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012526 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070012527 {
12528 // report middle speed
12529 rssidx = 1;
12530 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012531 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
12532 {
12533 // report middle speed
12534 rssidx = 2;
12535 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012536 else
12537 {
12538 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012539 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070012540 }
12541 }
12542 else
12543 {
12544 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
12545 hddLog(VOS_TRACE_LEVEL_ERROR,
12546 "%s: Invalid value for reportMaxLinkSpeed: %u",
12547 __func__, pCfg->reportMaxLinkSpeed);
12548 rssidx = 0;
12549 }
12550
12551 maxRate = 0;
12552
12553 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012554 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
12555 OperationalRates, &ORLeng))
12556 {
12557 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12558 /*To keep GUI happy*/
12559 return 0;
12560 }
12561
Jeff Johnson295189b2012-06-20 16:38:30 -070012562 for (i = 0; i < ORLeng; i++)
12563 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012564 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012565 {
12566 /* Validate Rate Set */
12567 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
12568 {
12569 currentRate = supported_data_rate[j].supported_rate[rssidx];
12570 break;
12571 }
12572 }
12573 /* Update MAX rate */
12574 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12575 }
12576
12577 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012578 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
12579 ExtendedRates, &ERLeng))
12580 {
12581 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12582 /*To keep GUI happy*/
12583 return 0;
12584 }
12585
Jeff Johnson295189b2012-06-20 16:38:30 -070012586 for (i = 0; i < ERLeng; i++)
12587 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012588 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012589 {
12590 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
12591 {
12592 currentRate = supported_data_rate[j].supported_rate[rssidx];
12593 break;
12594 }
12595 }
12596 /* Update MAX rate */
12597 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12598 }
c_hpothu79aab322014-07-14 21:11:01 +053012599
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012600 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053012601 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012602 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053012603 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070012604 {
c_hpothu79aab322014-07-14 21:11:01 +053012605 if (rate_flags & eHAL_TX_RATE_VHT80)
12606 mode = 2;
12607 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
12608 mode = 1;
12609 else
12610 mode = 0;
12611
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012612 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
12613 MCSRates, &MCSLeng))
12614 {
12615 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12616 /*To keep GUI happy*/
12617 return 0;
12618 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012619 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070012620#ifdef WLAN_FEATURE_11AC
12621 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012622 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070012623 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012624 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012625 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070012626 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070012627 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012628 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070012629 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012630 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070012631 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012632 maxMCSIdx = 7;
12633 }
12634 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
12635 {
12636 maxMCSIdx = 8;
12637 }
12638 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
12639 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012640 //VHT20 is supporting 0~8
12641 if (rate_flags & eHAL_TX_RATE_VHT20)
12642 maxMCSIdx = 8;
12643 else
12644 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070012645 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012646
c_hpothu79aab322014-07-14 21:11:01 +053012647 if (0 != rssidx)/*check for scaled */
12648 {
12649 //get middle rate MCS index if rssi=1/2
12650 for (i=0; i <= maxMCSIdx; i++)
12651 {
12652 if (sinfo->signal <= rssiMcsTbl[mode][i])
12653 {
12654 maxMCSIdx = i;
12655 break;
12656 }
12657 }
12658 }
12659
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012660 if (rate_flags & eHAL_TX_RATE_VHT80)
12661 {
12662 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
12663 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
12664 }
12665 else if (rate_flags & eHAL_TX_RATE_VHT40)
12666 {
12667 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
12668 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
12669 }
12670 else if (rate_flags & eHAL_TX_RATE_VHT20)
12671 {
12672 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
12673 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
12674 }
12675
Leo Chang6f8870f2013-03-26 18:11:36 -070012676 maxSpeedMCS = 1;
12677 if (currentRate > maxRate)
12678 {
12679 maxRate = currentRate;
12680 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012681
Leo Chang6f8870f2013-03-26 18:11:36 -070012682 }
12683 else
12684#endif /* WLAN_FEATURE_11AC */
12685 {
12686 if (rate_flags & eHAL_TX_RATE_HT40)
12687 {
12688 rateFlag |= 1;
12689 }
12690 if (rate_flags & eHAL_TX_RATE_SGI)
12691 {
12692 rateFlag |= 2;
12693 }
12694
Girish Gowli01abcee2014-07-31 20:18:55 +053012695 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053012696 if (rssidx == 1 || rssidx == 2)
12697 {
12698 //get middle rate MCS index if rssi=1/2
12699 for (i=0; i <= 7; i++)
12700 {
12701 if (sinfo->signal <= rssiMcsTbl[mode][i])
12702 {
12703 temp = i+1;
12704 break;
12705 }
12706 }
12707 }
c_hpothu79aab322014-07-14 21:11:01 +053012708
12709 for (i = 0; i < MCSLeng; i++)
12710 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012711 for (j = 0; j < temp; j++)
12712 {
12713 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
12714 {
12715 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
12716 break;
12717 }
12718 }
12719 if ((j < temp) && (currentRate > maxRate))
12720 {
12721 maxRate = currentRate;
12722 maxSpeedMCS = 1;
12723 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
12724 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012725 }
12726 }
12727 }
12728
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012729 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
12730 {
12731 maxRate = myRate;
12732 maxSpeedMCS = 1;
12733 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12734 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012735 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053012736 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070012737 {
12738 maxRate = myRate;
12739 if (rate_flags & eHAL_TX_RATE_LEGACY)
12740 {
12741 maxSpeedMCS = 0;
12742 }
12743 else
12744 {
12745 maxSpeedMCS = 1;
12746 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12747 }
12748 }
12749
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012750 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070012751 {
12752 sinfo->txrate.legacy = maxRate;
12753#ifdef LINKSPEED_DEBUG_ENABLED
12754 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
12755#endif //LINKSPEED_DEBUG_ENABLED
12756 }
12757 else
12758 {
12759 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070012760#ifdef WLAN_FEATURE_11AC
12761 sinfo->txrate.nss = 1;
12762 if (rate_flags & eHAL_TX_RATE_VHT80)
12763 {
12764 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012765 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070012766 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012767 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070012768 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012769 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12770 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12771 }
12772 else if (rate_flags & eHAL_TX_RATE_VHT20)
12773 {
12774 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12775 }
12776#endif /* WLAN_FEATURE_11AC */
12777 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
12778 {
12779 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12780 if (rate_flags & eHAL_TX_RATE_HT40)
12781 {
12782 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12783 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012784 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012785 if (rate_flags & eHAL_TX_RATE_SGI)
12786 {
12787 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12788 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012789
Jeff Johnson295189b2012-06-20 16:38:30 -070012790#ifdef LINKSPEED_DEBUG_ENABLED
12791 pr_info("Reporting MCS rate %d flags %x\n",
12792 sinfo->txrate.mcs,
12793 sinfo->txrate.flags );
12794#endif //LINKSPEED_DEBUG_ENABLED
12795 }
12796 }
12797 else
12798 {
12799 // report current rate instead of max rate
12800
12801 if (rate_flags & eHAL_TX_RATE_LEGACY)
12802 {
12803 //provide to the UI in units of 100kbps
12804 sinfo->txrate.legacy = myRate;
12805#ifdef LINKSPEED_DEBUG_ENABLED
12806 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
12807#endif //LINKSPEED_DEBUG_ENABLED
12808 }
12809 else
12810 {
12811 //must be MCS
12812 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070012813#ifdef WLAN_FEATURE_11AC
12814 sinfo->txrate.nss = 1;
12815 if (rate_flags & eHAL_TX_RATE_VHT80)
12816 {
12817 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12818 }
12819 else
12820#endif /* WLAN_FEATURE_11AC */
12821 {
12822 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12823 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012824 if (rate_flags & eHAL_TX_RATE_SGI)
12825 {
12826 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12827 }
12828 if (rate_flags & eHAL_TX_RATE_HT40)
12829 {
12830 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12831 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012832#ifdef WLAN_FEATURE_11AC
12833 else if (rate_flags & eHAL_TX_RATE_VHT80)
12834 {
12835 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
12836 }
12837#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070012838#ifdef LINKSPEED_DEBUG_ENABLED
12839 pr_info("Reporting actual MCS rate %d flags %x\n",
12840 sinfo->txrate.mcs,
12841 sinfo->txrate.flags );
12842#endif //LINKSPEED_DEBUG_ENABLED
12843 }
12844 }
12845 sinfo->filled |= STATION_INFO_TX_BITRATE;
12846
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012847 sinfo->tx_packets =
12848 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
12849 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
12850 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
12851 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
12852
12853 sinfo->tx_retries =
12854 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
12855 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
12856 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
12857 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
12858
12859 sinfo->tx_failed =
12860 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
12861 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
12862 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
12863 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
12864
12865 sinfo->filled |=
12866 STATION_INFO_TX_PACKETS |
12867 STATION_INFO_TX_RETRIES |
12868 STATION_INFO_TX_FAILED;
12869
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012870 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12871 TRACE_CODE_HDD_CFG80211_GET_STA,
12872 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012873 EXIT();
12874 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012875}
12876
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012877static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
12878 u8* mac, struct station_info *sinfo)
12879{
12880 int ret;
12881
12882 vos_ssr_protect(__func__);
12883 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
12884 vos_ssr_unprotect(__func__);
12885
12886 return ret;
12887}
12888
12889static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070012890 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070012891{
12892 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012893 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012894 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012895 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012896
Jeff Johnsone7245742012-09-05 17:12:55 -070012897 ENTER();
12898
Jeff Johnson295189b2012-06-20 16:38:30 -070012899 if (NULL == pAdapter)
12900 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012901 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012902 return -ENODEV;
12903 }
12904
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012905 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12906 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
12907 pAdapter->sessionId, timeout));
12908
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012909 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012910 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012911
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012912 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012913 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12915 "%s: HDD context is not valid", __func__);
12916 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012917 }
12918
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012919 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
12920 (TRUE == pHddCtx->hdd_wlan_suspended) &&
12921 (pHddCtx->cfg_ini->fhostArpOffload) &&
12922 (eConnectionState_Associated ==
12923 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12924 {
Amar Singhald53568e2013-09-26 11:03:45 -070012925
12926 hddLog(VOS_TRACE_LEVEL_INFO,
12927 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053012928 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012929 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12930 {
12931 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012932 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012933 __func__, vos_status);
12934 }
12935 }
12936
Jeff Johnson295189b2012-06-20 16:38:30 -070012937 /**The get power cmd from the supplicant gets updated by the nl only
12938 *on successful execution of the function call
12939 *we are oppositely mapped w.r.t mode in the driver
12940 **/
12941 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
12942
Jeff Johnsone7245742012-09-05 17:12:55 -070012943 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012944 if (VOS_STATUS_E_FAILURE == vos_status)
12945 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012946 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12947 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012948 return -EINVAL;
12949 }
12950 return 0;
12951}
12952
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012953static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
12954 struct net_device *dev, bool mode, int timeout)
12955{
12956 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012957
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012958 vos_ssr_protect(__func__);
12959 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
12960 vos_ssr_unprotect(__func__);
12961
12962 return ret;
12963}
Jeff Johnson295189b2012-06-20 16:38:30 -070012964#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012965static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
12966 struct net_device *netdev,
12967 u8 key_index)
12968{
12969 ENTER();
12970 return 0;
12971}
12972
Jeff Johnson295189b2012-06-20 16:38:30 -070012973static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012974 struct net_device *netdev,
12975 u8 key_index)
12976{
12977 int ret;
12978 vos_ssr_protect(__func__);
12979 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
12980 vos_ssr_unprotect(__func__);
12981 return ret;
12982}
12983#endif //LINUX_VERSION_CODE
12984
12985#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
12986static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
12987 struct net_device *dev,
12988 struct ieee80211_txq_params *params)
12989{
12990 ENTER();
12991 return 0;
12992}
12993#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12994static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
12995 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070012996{
Jeff Johnsone7245742012-09-05 17:12:55 -070012997 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012998 return 0;
12999}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013000#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070013001
13002#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13003static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013004 struct net_device *dev,
13005 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013006{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013007 int ret;
13008
13009 vos_ssr_protect(__func__);
13010 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
13011 vos_ssr_unprotect(__func__);
13012 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013013}
13014#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13015static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
13016 struct ieee80211_txq_params *params)
13017{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013018 int ret;
13019
13020 vos_ssr_protect(__func__);
13021 ret = __wlan_hdd_set_txq_params(wiphy, params);
13022 vos_ssr_unprotect(__func__);
13023 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013024}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013025#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013026
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013027static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013028 struct net_device *dev,
13029 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070013030{
13031 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013032 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013033 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013034 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013035 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013036 v_CONTEXT_t pVosContext = NULL;
13037 ptSapContext pSapCtx = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070013038 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013039
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013040 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070013041 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013042 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013043 return -EINVAL;
13044 }
13045
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013046 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13047 TRACE_CODE_HDD_CFG80211_DEL_STA,
13048 pAdapter->sessionId, pAdapter->device_mode));
13049
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013050 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13051 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070013052
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013053 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013054 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013055 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13056 "%s: HDD context is not valid", __func__);
13057 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013058 }
13059
Jeff Johnson295189b2012-06-20 16:38:30 -070013060 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013061 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013062 )
13063 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013064 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13065 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13066 if(pSapCtx == NULL){
13067 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13068 FL("psapCtx is NULL"));
13069 return -ENOENT;
13070 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013071 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013072 {
13073 v_U16_t i;
13074 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13075 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013076 if ((pSapCtx->aStaInfo[i].isUsed) &&
13077 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070013078 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013079 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013080 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013081 ETHER_ADDR_LEN);
13082
Jeff Johnson295189b2012-06-20 16:38:30 -070013083 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013084 "%s: Delete STA with MAC::"
13085 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013086 __func__,
13087 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
13088 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013089 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013090 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013091 }
13092 }
13093 }
13094 else
13095 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013096
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013097 vos_status = hdd_softap_GetStaId(pAdapter,
13098 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013099 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13100 {
13101 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013102 "%s: Skip this DEL STA as this is not used::"
13103 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013104 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013105 return -ENOENT;
13106 }
13107
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013108 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013109 {
13110 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013111 "%s: Skip this DEL STA as deauth is in progress::"
13112 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013113 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013114 return -ENOENT;
13115 }
13116
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013117 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013118
Jeff Johnson295189b2012-06-20 16:38:30 -070013119 hddLog(VOS_TRACE_LEVEL_INFO,
13120 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013121 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013122 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013123 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013124
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013125 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013126 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13127 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013128 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013129 hddLog(VOS_TRACE_LEVEL_INFO,
13130 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013131 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013132 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013133 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013134 return -ENOENT;
13135 }
13136
Jeff Johnson295189b2012-06-20 16:38:30 -070013137 }
13138 }
13139
13140 EXIT();
13141
13142 return 0;
13143}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013144
13145#ifdef CFG80211_DEL_STA_V2
13146static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13147 struct net_device *dev,
13148 struct station_del_parameters *param)
13149#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013150static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13151 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013152#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013153{
13154 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013155 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070013156
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013157 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013158
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013159#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013160 if (NULL == param) {
13161 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013162 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013163 return -EINVAL;
13164 }
13165
13166 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
13167 param->subtype, &delStaParams);
13168
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013169#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053013170 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013171 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013172#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013173 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
13174
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013175 vos_ssr_unprotect(__func__);
13176
13177 return ret;
13178}
13179
13180static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013181 struct net_device *dev, u8 *mac, struct station_parameters *params)
13182{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013183 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013184 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013185#ifdef FEATURE_WLAN_TDLS
13186 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013187 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013188
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013189 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13190 TRACE_CODE_HDD_CFG80211_ADD_STA,
13191 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013192 mask = params->sta_flags_mask;
13193
13194 set = params->sta_flags_set;
13195
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013196#ifdef WLAN_FEATURE_TDLS_DEBUG
13197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13198 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
13199 __func__, mask, set, MAC_ADDR_ARRAY(mac));
13200#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013201
13202 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13203 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013204 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013205 }
13206 }
13207#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013208 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013209}
13210
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013211static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
13212 struct net_device *dev, u8 *mac, struct station_parameters *params)
13213{
13214 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013215
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013216 vos_ssr_protect(__func__);
13217 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
13218 vos_ssr_unprotect(__func__);
13219
13220 return ret;
13221}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013222#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070013223
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013224static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070013225 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013226{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013227 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13228 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013229 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013230 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013231 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013232 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070013233
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013234 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013235 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013236 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013237 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013238 return -EINVAL;
13239 }
13240
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013241 if (!pmksa) {
13242 hddLog(LOGE, FL("pmksa is NULL"));
13243 return -EINVAL;
13244 }
13245
13246 if (!pmksa->bssid || !pmksa->pmkid) {
13247 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
13248 pmksa->bssid, pmksa->pmkid);
13249 return -EINVAL;
13250 }
13251
13252 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
13253 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13254
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013255 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13256 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013257
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013258 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013259 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13261 "%s: HDD context is not valid", __func__);
13262 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013263 }
13264
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013265 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013266 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13267
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013268 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
13269 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013270
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013271 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013272 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013273 &pmk_id, 1, FALSE);
13274
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013275 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13276 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
13277 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013278
13279 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013280}
13281
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013282static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
13283 struct cfg80211_pmksa *pmksa)
13284{
13285 int ret;
13286
13287 vos_ssr_protect(__func__);
13288 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
13289 vos_ssr_unprotect(__func__);
13290
13291 return ret;
13292}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013293
Wilson Yang6507c4e2013-10-01 20:11:19 -070013294
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013295static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070013296 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013297{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013298 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13299 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013300 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013301 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013302
Wilson Yang6507c4e2013-10-01 20:11:19 -070013303 /* Validate pAdapter */
13304 if (NULL == pAdapter)
13305 {
13306 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
13307 return -EINVAL;
13308 }
13309
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013310 if (!pmksa) {
13311 hddLog(LOGE, FL("pmksa is NULL"));
13312 return -EINVAL;
13313 }
13314
13315 if (!pmksa->bssid) {
13316 hddLog(LOGE, FL("pmksa->bssid is NULL"));
13317 return -EINVAL;
13318 }
13319
Kiet Lam98c46a12014-10-31 15:34:57 -070013320 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
13321 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13322
Wilson Yang6507c4e2013-10-01 20:11:19 -070013323 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13324 status = wlan_hdd_validate_context(pHddCtx);
13325
13326 if (0 != status)
13327 {
13328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13329 "%s: HDD context is not valid", __func__);
13330 return status;
13331 }
13332
13333 /*Retrieve halHandle*/
13334 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13335
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013336 /* Delete the PMKID CSR cache */
13337 if (eHAL_STATUS_SUCCESS !=
13338 sme_RoamDelPMKIDfromCache(halHandle,
13339 pAdapter->sessionId, pmksa->bssid, FALSE)) {
13340 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
13341 MAC_ADDR_ARRAY(pmksa->bssid));
13342 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013343 }
13344
Wilson Yangef657d32014-01-15 19:19:23 -080013345 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013346}
13347
Wilson Yang6507c4e2013-10-01 20:11:19 -070013348
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013349static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
13350 struct cfg80211_pmksa *pmksa)
13351{
13352 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013353
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013354 vos_ssr_protect(__func__);
13355 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
13356 vos_ssr_unprotect(__func__);
13357
13358 return ret;
13359
13360}
13361
13362static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013363{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013364 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13365 tHalHandle halHandle;
13366 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013367 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013368
13369 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
13370
13371 /* Validate pAdapter */
13372 if (NULL == pAdapter)
13373 {
13374 hddLog(VOS_TRACE_LEVEL_ERROR,
13375 "%s: Invalid Adapter" ,__func__);
13376 return -EINVAL;
13377 }
13378
13379 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13380 status = wlan_hdd_validate_context(pHddCtx);
13381
13382 if (0 != status)
13383 {
13384 hddLog(VOS_TRACE_LEVEL_ERROR,
13385 "%s: HDD context is not valid", __func__);
13386 return status;
13387 }
13388
13389 /*Retrieve halHandle*/
13390 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13391
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013392 /* Flush the PMKID cache in CSR */
13393 if (eHAL_STATUS_SUCCESS !=
13394 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
13395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
13396 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013397 }
13398
Wilson Yangef657d32014-01-15 19:19:23 -080013399 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013400}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013401
13402static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
13403{
13404 int ret;
13405
13406 vos_ssr_protect(__func__);
13407 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
13408 vos_ssr_unprotect(__func__);
13409
13410 return ret;
13411}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013412#endif
13413
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013414#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013415static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13416 struct net_device *dev,
13417 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013418{
13419 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13420 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013421 hdd_context_t *pHddCtx;
13422 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013423
13424 if (NULL == pAdapter)
13425 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013426 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013427 return -ENODEV;
13428 }
13429
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013430 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13431 ret = wlan_hdd_validate_context(pHddCtx);
13432 if (0 != ret)
13433 {
13434 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13435 "%s: HDD context is not valid", __func__);
13436 return ret;
13437 }
13438
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013439 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13440
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013441 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13442 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
13443 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013444 // Added for debug on reception of Re-assoc Req.
13445 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
13446 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013447 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013448 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080013449 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013450 }
13451
13452#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080013453 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013454 ftie->ie_len);
13455#endif
13456
13457 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013458 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13459 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013460 ftie->ie_len);
13461 return 0;
13462}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013463
13464static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13465 struct net_device *dev,
13466 struct cfg80211_update_ft_ies_params *ftie)
13467{
13468 int ret;
13469
13470 vos_ssr_protect(__func__);
13471 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
13472 vos_ssr_unprotect(__func__);
13473
13474 return ret;
13475}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013476#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013477
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013478#ifdef FEATURE_WLAN_SCAN_PNO
13479
13480void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
13481 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
13482{
13483 int ret;
13484 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
13485 hdd_context_t *pHddCtx;
13486
Nirav Shah80830bf2013-12-31 16:35:12 +053013487 ENTER();
13488
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013489 if (NULL == pAdapter)
13490 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013491 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013492 "%s: HDD adapter is Null", __func__);
13493 return ;
13494 }
13495
13496 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13497 if (NULL == pHddCtx)
13498 {
13499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13500 "%s: HDD context is Null!!!", __func__);
13501 return ;
13502 }
13503
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013504 spin_lock(&pHddCtx->schedScan_lock);
13505 if (TRUE == pHddCtx->isWiphySuspended)
13506 {
13507 pHddCtx->isSchedScanUpdatePending = TRUE;
13508 spin_unlock(&pHddCtx->schedScan_lock);
13509 hddLog(VOS_TRACE_LEVEL_INFO,
13510 "%s: Update cfg80211 scan database after it resume", __func__);
13511 return ;
13512 }
13513 spin_unlock(&pHddCtx->schedScan_lock);
13514
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013515 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
13516
13517 if (0 > ret)
13518 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
13519
13520 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13522 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013523}
13524
13525/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013526 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013527 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013528 */
13529static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
13530{
13531 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13532 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013533 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013534 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13535 int status = 0;
13536 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13537
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013538 /* The current firmware design does not allow PNO during any
13539 * active sessions. Hence, determine the active sessions
13540 * and return a failure.
13541 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013542 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
13543 {
13544 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013545 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013546
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013547 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
13548 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
13549 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
13550 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
13551 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053013552 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013553 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013554 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013555 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013556 }
13557 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13558 pAdapterNode = pNext;
13559 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013560 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013561}
13562
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013563void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
13564{
13565 hdd_adapter_t *pAdapter = callbackContext;
13566 hdd_context_t *pHddCtx;
13567
13568 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
13569 {
13570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13571 FL("Invalid adapter or adapter has invalid magic"));
13572 return;
13573 }
13574
13575 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13576 if (0 != wlan_hdd_validate_context(pHddCtx))
13577 {
13578 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13579 FL("HDD context is not valid"));
13580 return;
13581 }
13582
c_hpothub53c45d2014-08-18 16:53:14 +053013583 if (VOS_STATUS_SUCCESS != status)
13584 {
13585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013586 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053013587 pHddCtx->isPnoEnable = FALSE;
13588 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013589
13590 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
13591 complete(&pAdapter->pno_comp_var);
13592}
13593
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013594/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013595 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
13596 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013597 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013598static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013599 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13600{
13601 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13602 tpSirPNOScanReq pPnoRequest = NULL;
13603 hdd_context_t *pHddCtx;
13604 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013605 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053013606 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
13607 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013608 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13609 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013610 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013611 hdd_config_t *pConfig = NULL;
13612 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013613
13614 if (NULL == pAdapter)
13615 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013617 "%s: HDD adapter is Null", __func__);
13618 return -ENODEV;
13619 }
13620
13621 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013622 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013623
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013624 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013625 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13627 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013628 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013629 }
13630
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013631 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013632 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13633 if (NULL == hHal)
13634 {
13635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13636 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013637 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013638 }
Sushant Kaushik2fe89932014-09-03 10:58:09 +053013639 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013640 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053013641 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013642 {
13643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13644 "%s: aborting the existing scan is unsuccessfull", __func__);
13645 return -EBUSY;
13646 }
13647
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013648 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013649 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013650 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013651 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013652 return -EBUSY;
13653 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013654
c_hpothu37f21312014-04-09 21:49:54 +053013655 if (TRUE == pHddCtx->isPnoEnable)
13656 {
13657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13658 FL("already PNO is enabled"));
13659 return -EBUSY;
13660 }
c_hpothu225aa7c2014-10-22 17:45:13 +053013661
13662 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
13663 {
13664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13665 "%s: abort ROC failed ", __func__);
13666 return -EBUSY;
13667 }
13668
c_hpothu37f21312014-04-09 21:49:54 +053013669 pHddCtx->isPnoEnable = TRUE;
13670
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013671 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13672 if (NULL == pPnoRequest)
13673 {
13674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13675 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053013676 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013677 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013678 }
13679
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053013680 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013681 pPnoRequest->enable = 1; /*Enable PNO */
13682 pPnoRequest->ucNetworksCount = request->n_match_sets;
13683
13684 if (( !pPnoRequest->ucNetworksCount ) ||
13685 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
13686 {
13687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013688 "%s: Network input is not correct %d Max Network supported is %d",
13689 __func__, pPnoRequest->ucNetworksCount,
13690 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013691 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013692 goto error;
13693 }
13694
13695 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
13696 {
13697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013698 "%s: Incorrect number of channels %d",
13699 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013700 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013701 goto error;
13702 }
13703
13704 /* Framework provides one set of channels(all)
13705 * common for all saved profile */
13706 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13707 channels_allowed, &num_channels_allowed))
13708 {
13709 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13710 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013711 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013712 goto error;
13713 }
13714 /* Checking each channel against allowed channel list */
13715 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053013716 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013717 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013718 char chList [(request->n_channels*5)+1];
13719 int len;
13720 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013721 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013722 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013723 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013724 if (request->channels[i]->hw_value == channels_allowed[indx])
13725 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013726 if ((!pConfig->enableDFSPnoChnlScan) &&
13727 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
13728 {
13729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13730 "%s : Dropping DFS channel : %d",
13731 __func__,channels_allowed[indx]);
13732 num_ignore_dfs_ch++;
13733 break;
13734 }
13735
Nirav Shah80830bf2013-12-31 16:35:12 +053013736 valid_ch[num_ch++] = request->channels[i]->hw_value;
13737 len += snprintf(chList+len, 5, "%d ",
13738 request->channels[i]->hw_value);
13739 break ;
13740 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013741 }
13742 }
Nirav Shah80830bf2013-12-31 16:35:12 +053013743 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013744
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013745 /*If all channels are DFS and dropped, then ignore the PNO request*/
13746 if (num_ignore_dfs_ch == request->n_channels)
13747 {
13748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13749 "%s : All requested channels are DFS channels", __func__);
13750 ret = -EINVAL;
13751 goto error;
13752 }
13753 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013754 /* Filling per profile params */
13755 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
13756 {
13757 pPnoRequest->aNetworks[i].ssId.length =
13758 request->match_sets[i].ssid.ssid_len;
13759
13760 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
13761 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
13762 {
13763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013764 "%s: SSID Len %d is not correct for network %d",
13765 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013766 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013767 goto error;
13768 }
13769
13770 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
13771 request->match_sets[i].ssid.ssid,
13772 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13774 "%s: SSID of network %d is %s ", __func__,
13775 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013776 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
13777 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
13778 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
13779
13780 /*Copying list of valid channel into request */
13781 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
13782 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
13783
13784 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
13785 }
13786
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013787 for (i = 0; i < request->n_ssids; i++)
13788 {
13789 j = 0;
13790 while (j < pPnoRequest->ucNetworksCount)
13791 {
13792 if ((pPnoRequest->aNetworks[j].ssId.length ==
13793 request->ssids[i].ssid_len) &&
13794 (0 == memcmp(pPnoRequest->aNetworks[j].ssId.ssId,
13795 request->ssids[i].ssid,
13796 pPnoRequest->aNetworks[j].ssId.length)))
13797 {
13798 pPnoRequest->aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
13799 break;
13800 }
13801 j++;
13802 }
13803 }
13804 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13805 "Number of hidden networks being Configured = %d",
13806 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080013808 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013809 if ((0 < request->ie_len) && (NULL != request->ie))
13810 {
13811 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
13812 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
13813 pPnoRequest->us24GProbeTemplateLen);
13814
13815 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
13816 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
13817 pPnoRequest->us5GProbeTemplateLen);
13818 }
13819
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053013820 /* Driver gets only one time interval which is hardcoded in
13821 * supplicant for 10000ms. Taking power consumption into account 6 timers
13822 * will be used, Timervalue is increased exponentially i.e 10,20,40,
13823 * 80,160,320 secs. And number of scan cycle for each timer
13824 * is configurable through INI param gPNOScanTimerRepeatValue.
13825 * If it is set to 0 only one timer will be used and PNO scan cycle
13826 * will be repeated after each interval specified by supplicant
13827 * till PNO is disabled.
13828 */
13829 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
13830 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
13831 else
13832 pPnoRequest->scanTimers.ucScanTimersCount =
13833 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
13834
13835 tempInterval = (request->interval)/1000;
13836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13837 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
13838 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
13839 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
13840 {
13841 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
13842 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
13843 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
13844 tempInterval *= 2;
13845 }
13846 //Repeat last timer until pno disabled.
13847 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
13848
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053013849 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013850
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013851 INIT_COMPLETION(pAdapter->pno_comp_var);
13852 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
13853 pPnoRequest->callbackContext = pAdapter;
13854 pAdapter->pno_req_status = 0;
13855
Nirav Shah80830bf2013-12-31 16:35:12 +053013856 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13857 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
13858 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
13859 pPnoRequest->scanTimers.ucScanTimersCount);
13860
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013861 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
13862 pPnoRequest, pAdapter->sessionId,
13863 hdd_cfg80211_sched_scan_done_callback, pAdapter);
13864 if (eHAL_STATUS_SUCCESS != status)
13865 {
13866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013867 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013868 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013869 goto error;
13870 }
13871
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013872 ret = wait_for_completion_timeout(
13873 &pAdapter->pno_comp_var,
13874 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
13875 if (0 >= ret)
13876 {
13877 // Did not receive the response for PNO enable in time.
13878 // Assuming the PNO enable was success.
13879 // Returning error from here, because we timeout, results
13880 // in side effect of Wifi (Wifi Setting) not to work.
13881 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13882 FL("Timed out waiting for PNO to be Enabled"));
13883 ret = 0;
13884 goto error;
13885 }
13886
c_hpothu3c986b22014-07-09 14:45:09 +053013887 vos_mem_free(pPnoRequest);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013888 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053013889 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013890
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013891error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013892 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13893 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013894 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053013895 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013896 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013897}
13898
13899/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013900 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
13901 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013902 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013903static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
13904 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13905{
13906 int ret;
13907
13908 vos_ssr_protect(__func__);
13909 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
13910 vos_ssr_unprotect(__func__);
13911
13912 return ret;
13913}
13914
13915/*
13916 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
13917 * Function to disable PNO
13918 */
13919static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013920 struct net_device *dev)
13921{
13922 eHalStatus status = eHAL_STATUS_FAILURE;
13923 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13924 hdd_context_t *pHddCtx;
13925 tHalHandle hHal;
13926 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013927 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013928
13929 ENTER();
13930
13931 if (NULL == pAdapter)
13932 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013933 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013934 "%s: HDD adapter is Null", __func__);
13935 return -ENODEV;
13936 }
13937
13938 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013939
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013940 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013941 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013942 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013943 "%s: HDD context is Null", __func__);
13944 return -ENODEV;
13945 }
13946
13947 /* The return 0 is intentional when isLogpInProgress and
13948 * isLoadUnloadInProgress. We did observe a crash due to a return of
13949 * failure in sched_scan_stop , especially for a case where the unload
13950 * of the happens at the same time. The function __cfg80211_stop_sched_scan
13951 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
13952 * success. If it returns a failure , then its next invocation due to the
13953 * clean up of the second interface will have the dev pointer corresponding
13954 * to the first one leading to a crash.
13955 */
13956 if (pHddCtx->isLogpInProgress)
13957 {
13958 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13959 "%s: LOGP in Progress. Ignore!!!", __func__);
13960 return ret;
13961 }
13962
Mihir Shete18156292014-03-11 15:38:30 +053013963 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013964 {
13965 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13966 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13967 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013968 }
13969
13970 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13971 if (NULL == hHal)
13972 {
13973 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13974 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013975 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013976 }
13977
13978 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13979 if (NULL == pPnoRequest)
13980 {
13981 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13982 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013983 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013984 }
13985
13986 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
13987 pPnoRequest->enable = 0; /* Disable PNO */
13988 pPnoRequest->ucNetworksCount = 0;
13989
13990 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
13991 pAdapter->sessionId,
13992 NULL, pAdapter);
13993 if (eHAL_STATUS_SUCCESS != status)
13994 {
13995 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13996 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013997 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013998 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013999 }
c_hpothu37f21312014-04-09 21:49:54 +053014000 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014001
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014002error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014004 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014005 vos_mem_free(pPnoRequest);
14006
14007 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014008 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014009}
14010
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014011/*
14012 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
14013 * NL interface to disable PNO
14014 */
14015static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
14016 struct net_device *dev)
14017{
14018 int ret;
14019
14020 vos_ssr_protect(__func__);
14021 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
14022 vos_ssr_unprotect(__func__);
14023
14024 return ret;
14025}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014026#endif /*FEATURE_WLAN_SCAN_PNO*/
14027
14028
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014029#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014030#if TDLS_MGMT_VERSION2
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014031static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014032 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014033 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
14034#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014035static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014036 u8 *peer, u8 action_code, u8 dialog_token,
14037 u16 status_code, const u8 *buf, size_t len)
14038#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014039{
14040
14041 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14042 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014043 u8 peerMac[6];
14044 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070014045 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080014046 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070014047 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014048 int ret;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014049#if !(TDLS_MGMT_VERSION2)
14050 u32 peer_capability = 0;
14051#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014052 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014053
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014054 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14055 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
14056 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014057 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014058 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014059 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014060 "Invalid arguments");
14061 return -EINVAL;
14062 }
14063
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014064 if (pHddCtx->isLogpInProgress)
14065 {
14066 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14067 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053014068 wlan_hdd_tdls_set_link_status(pAdapter,
14069 peer,
14070 eTDLS_LINK_IDLE,
14071 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014072 return -EBUSY;
14073 }
14074
Hoonki Lee27511902013-03-14 18:19:06 -070014075 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014076 {
Hoonki Lee27511902013-03-14 18:19:06 -070014077 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
14078 "%s: TDLS mode is disabled OR not enabled in FW."
14079 MAC_ADDRESS_STR " action %d declined.",
14080 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014081 return -ENOTSUPP;
14082 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014083
Hoonki Lee27511902013-03-14 18:19:06 -070014084 /* other than teardown frame, other mgmt frames are not sent if disabled */
14085 if (SIR_MAC_TDLS_TEARDOWN != action_code)
14086 {
14087 /* if tdls_mode is disabled to respond to peer's request */
14088 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
14089 {
14090 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
14091 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014092 " TDLS mode is disabled. action %d declined.",
14093 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070014094
14095 return -ENOTSUPP;
14096 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014097
14098 if (vos_max_concurrent_connections_reached())
14099 {
14100 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14101 return -EINVAL;
14102 }
Hoonki Lee27511902013-03-14 18:19:06 -070014103 }
14104
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014105 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
14106 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014107 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014108 {
14109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014110 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014111 " TDLS setup is ongoing. action %d declined.",
14112 __func__, MAC_ADDR_ARRAY(peer), action_code);
14113 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014114 }
14115 }
14116
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014117 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
14118 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080014119 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014120 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14121 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014122 {
14123 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
14124 we return error code at 'add_station()'. Hence we have this
14125 check again in addtion to add_station().
14126 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014127 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014128 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14130 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014131 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
14132 __func__, MAC_ADDR_ARRAY(peer), action_code,
14133 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053014134 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080014135 }
14136 else
14137 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014138 /* maximum reached. tweak to send error code to peer and return
14139 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014140 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14142 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014143 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
14144 __func__, MAC_ADDR_ARRAY(peer), status_code,
14145 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070014146 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014147 /* fall through to send setup resp with failure status
14148 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014149 }
14150 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014151 else
14152 {
14153 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014154 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014155 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014156 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014157 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014158 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
14159 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014160 return -EPERM;
14161 }
14162 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014163 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014164 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014165
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014166#ifdef WLAN_FEATURE_TDLS_DEBUG
14167 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014168 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014169 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
14170 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014171#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014172
Hoonki Leea34dd892013-02-05 22:56:02 -080014173 /*Except teardown responder will not be used so just make 0*/
14174 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014175 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080014176 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014177
14178 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014179 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014180
14181 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
14182 responder = pTdlsPeer->is_responder;
14183 else
Hoonki Leea34dd892013-02-05 22:56:02 -080014184 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014185 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014186 "%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 -070014187 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
14188 dialog_token, status_code, len);
14189 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080014190 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014191 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014192
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014193 /* For explicit trigger of DIS_REQ come out of BMPS for
14194 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070014195 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014196 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
14197 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070014198 {
14199 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
14200 {
14201 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014202 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070014203 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
14204 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014205 if (SIR_MAC_TDLS_DIS_REQ != action_code)
14206 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070014207 }
14208
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014209 /* make sure doesn't call send_mgmt() while it is pending */
14210 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
14211 {
14212 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014213 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014214 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014215 ret = -EBUSY;
14216 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014217 }
14218
14219 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014220 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
14221
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014222 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053014223 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014224
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014225 if (VOS_STATUS_SUCCESS != status)
14226 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014227 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14228 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014229 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014230 ret = -EINVAL;
14231 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014232 }
14233
Hoonki Leed37cbb32013-04-20 00:31:14 -070014234 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
14235 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
14236
14237 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014238 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070014239 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014240 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070014241 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014242 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080014243
14244 if (pHddCtx->isLogpInProgress)
14245 {
14246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14247 "%s: LOGP in Progress. Ignore!!!", __func__);
14248 return -EAGAIN;
14249 }
14250
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014251 ret = -EINVAL;
14252 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014253 }
14254
Gopichand Nakkala05922802013-03-14 12:23:19 -070014255 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070014256 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014257 ret = max_sta_failed;
14258 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070014259 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014260
Hoonki Leea34dd892013-02-05 22:56:02 -080014261 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
14262 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014263 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080014264 }
14265 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
14266 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014267 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080014268 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014269
14270 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014271
14272tx_failed:
14273 /* add_station will be called before sending TDLS_SETUP_REQ and
14274 * TDLS_SETUP_RSP and as part of add_station driver will enable
14275 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
14276 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
14277 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
14278 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
14279 */
14280
14281 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
14282 (SIR_MAC_TDLS_SETUP_RSP == action_code))
14283 wlan_hdd_tdls_check_bmps(pAdapter);
14284 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014285}
14286
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014287#if TDLS_MGMT_VERSION2
14288static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14289 u8 *peer, u8 action_code, u8 dialog_token,
14290 u16 status_code, u32 peer_capability,
14291 const u8 *buf, size_t len)
14292#else
14293static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14294 u8 *peer, u8 action_code, u8 dialog_token,
14295 u16 status_code, const u8 *buf, size_t len)
14296#endif
14297{
14298 int ret;
14299
14300 vos_ssr_protect(__func__);
14301#if TDLS_MGMT_VERSION2
14302 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14303 status_code, peer_capability, buf, len);
14304#else
14305 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14306 status_code, buf, len);
14307#endif
14308 vos_ssr_unprotect(__func__);
14309
14310 return ret;
14311}
Atul Mittal115287b2014-07-08 13:26:33 +053014312
14313int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
14314 u8 *peer,
14315 cfg80211_exttdls_callback callback)
14316{
14317
14318 hddTdlsPeer_t *pTdlsPeer;
14319 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14321 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
14322 __func__, MAC_ADDR_ARRAY(peer));
14323
14324 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14325 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14326
14327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14328 " %s TDLS External control and Implicit Trigger not enabled ",
14329 __func__);
14330 return -ENOTSUPP;
14331 }
14332
14333 /* To cater the requirement of establishing the TDLS link
14334 * irrespective of the data traffic , get an entry of TDLS peer.
14335 */
14336 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
14337 if (pTdlsPeer == NULL) {
14338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14339 "%s: peer " MAC_ADDRESS_STR " not existing",
14340 __func__, MAC_ADDR_ARRAY(peer));
14341 return -EINVAL;
14342 }
14343
14344 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
14345
14346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14347 " %s TDLS Add Force Peer Failed",
14348 __func__);
14349 return -EINVAL;
14350 }
14351 /*EXT TDLS*/
14352
14353 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
14354 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14355 " %s TDLS set callback Failed",
14356 __func__);
14357 return -EINVAL;
14358 }
14359
14360 return(0);
14361
14362}
14363
14364int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
14365{
14366
14367 hddTdlsPeer_t *pTdlsPeer;
14368 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14370 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
14371 __func__, MAC_ADDR_ARRAY(peer));
14372
14373 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14374 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14375
14376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14377 " %s TDLS External control and Implicit Trigger not enabled ",
14378 __func__);
14379 return -ENOTSUPP;
14380 }
14381
14382
14383 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
14384
14385 if ( NULL == pTdlsPeer ) {
14386 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
14387 " peer not exsting",
14388 __func__, MAC_ADDR_ARRAY(peer));
14389 return -EINVAL;
14390 }
14391 else {
14392 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
14393 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
14394 }
14395
14396 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
14397 return -EINVAL;
14398
14399 /*EXT TDLS*/
14400
14401 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
14402
14403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14404 " %s TDLS set callback Failed",
14405 __func__);
14406 return -EINVAL;
14407 }
14408 return(0);
14409
14410}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014411static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014412 u8 *peer, enum nl80211_tdls_operation oper)
14413{
14414 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14415 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014416 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014417 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014418
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014419 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14420 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
14421 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014422 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014423 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014424 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014425 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014426 return -EINVAL;
14427 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014428
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014429 status = wlan_hdd_validate_context(pHddCtx);
14430
14431 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014432 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014433 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14434 "%s: HDD context is not valid", __func__);
14435 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014436 }
14437
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014438
14439 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014440 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014441 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014443 "TDLS Disabled in INI OR not enabled in FW. "
14444 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014445 return -ENOTSUPP;
14446 }
14447
14448 switch (oper) {
14449 case NL80211_TDLS_ENABLE_LINK:
14450 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014451 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014452 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014453 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053014454 WLAN_STADescType staDesc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014455
Sunil Dutt41de4e22013-11-14 18:09:02 +053014456 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053014457 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053014458 if ( NULL == pTdlsPeer ) {
14459 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
14460 " (oper %d) not exsting. ignored",
14461 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
14462 return -EINVAL;
14463 }
14464
14465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14466 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
14467 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
14468 "NL80211_TDLS_ENABLE_LINK");
14469
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070014470 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
14471 {
14472 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
14473 MAC_ADDRESS_STR " failed",
14474 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
14475 return -EINVAL;
14476 }
14477
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014478 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014479 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014480 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053014481
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014482 if (0 != wlan_hdd_tdls_get_link_establish_params(
14483 pAdapter, peer,&tdlsLinkEstablishParams)) {
14484 return -EINVAL;
14485 }
14486 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014487
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014488 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
14489 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
14490 /* Send TDLS peer UAPSD capabilities to the firmware and
14491 * register with the TL on after the response for this operation
14492 * is received .
14493 */
14494 ret = wait_for_completion_interruptible_timeout(
14495 &pAdapter->tdls_link_establish_req_comp,
14496 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
14497 if (ret <= 0)
14498 {
14499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14500 "%s: Link Establish Request Faled Status %ld",
14501 __func__, ret);
14502 return -EINVAL;
14503 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014504 }
Atul Mittal115287b2014-07-08 13:26:33 +053014505 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
14506 eTDLS_LINK_CONNECTED,
14507 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053014508 staDesc.ucSTAId = pTdlsPeer->staId;
14509 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
14510 WLANTL_UpdateTdlsSTAClient(pHddCtx->pvosContext,
14511 &staDesc);
14512
14513
Gopichand Nakkala471708b2013-06-04 20:03:01 +053014514 /* Mark TDLS client Authenticated .*/
14515 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
14516 pTdlsPeer->staId,
14517 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014518 if (VOS_STATUS_SUCCESS == status)
14519 {
Hoonki Lee14621352013-04-16 17:51:19 -070014520 if (pTdlsPeer->is_responder == 0)
14521 {
14522 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
14523
14524 wlan_hdd_tdls_timer_restart(pAdapter,
14525 &pTdlsPeer->initiatorWaitTimeoutTimer,
14526 WAIT_TIME_TDLS_INITIATOR);
14527 /* suspend initiator TX until it receives direct packet from the
14528 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
14529 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
14530 &staId, NULL);
14531 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014532 wlan_hdd_tdls_increment_peer_count(pAdapter);
14533 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014534 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014535
14536 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053014537 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
14538 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014539 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053014540 int ac;
14541 uint8 ucAc[4] = { WLANTL_AC_VO,
14542 WLANTL_AC_VI,
14543 WLANTL_AC_BK,
14544 WLANTL_AC_BE };
14545 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
14546 for(ac=0; ac < 4; ac++)
14547 {
14548 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
14549 pTdlsPeer->staId, ucAc[ac],
14550 tlTid[ac], tlTid[ac], 0, 0,
14551 WLANTL_BI_DIR );
14552 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014553 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014554 }
14555
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014556 }
14557 break;
14558 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080014559 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053014560 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
14561
14562 if ( NULL == pTdlsPeer ) {
14563 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
14564 " (oper %d) not exsting. ignored",
14565 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
14566 return -EINVAL;
14567 }
14568
14569 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14570 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
14571 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
14572 "NL80211_TDLS_DISABLE_LINK");
14573
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014574 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080014575 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014576 long status;
14577
Atul Mittal271a7652014-09-12 13:18:22 +053014578
14579 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
14580 eTDLS_LINK_TEARING,
14581 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
14582 eTDLS_LINK_UNSPECIFIED:
14583 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014584 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
14585
Lee Hoonkic1262f22013-01-24 21:59:00 -080014586 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
14587 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014588
14589 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
14590 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053014591 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053014592 eTDLS_LINK_IDLE,
14593 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014594 if (status <= 0)
14595 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14597 "%s: Del station failed status %ld",
14598 __func__, status);
14599 return -EPERM;
14600 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014601 }
14602 else
14603 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14605 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080014606 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014607 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014608 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014609 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053014610 {
Atul Mittal115287b2014-07-08 13:26:33 +053014611 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053014612
Atul Mittal115287b2014-07-08 13:26:33 +053014613 if (0 != status)
14614 {
14615 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14616 "%s: Error in TDLS Teardown", __func__);
14617 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053014618 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053014619 break;
14620 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014621 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053014622 {
Atul Mittal115287b2014-07-08 13:26:33 +053014623 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
14624 peer,
14625 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053014626
Atul Mittal115287b2014-07-08 13:26:33 +053014627 if (0 != status)
14628 {
14629 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14630 "%s: Error in TDLS Setup", __func__);
14631 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053014632 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053014633 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053014634 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014635 case NL80211_TDLS_DISCOVERY_REQ:
14636 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014637 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14638 "%s: We don't support in-driver setup/teardown/discovery "
14639 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014640 return -ENOTSUPP;
14641 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014642 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14643 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014644 return -ENOTSUPP;
14645 }
14646 return 0;
14647}
Chilam NG571c65a2013-01-19 12:27:36 +053014648
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014649static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
14650 u8 *peer, enum nl80211_tdls_operation oper)
14651{
14652 int ret;
14653
14654 vos_ssr_protect(__func__);
14655 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
14656 vos_ssr_unprotect(__func__);
14657
14658 return ret;
14659}
14660
Chilam NG571c65a2013-01-19 12:27:36 +053014661int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
14662 struct net_device *dev, u8 *peer)
14663{
Arif Hussaina7c8e412013-11-20 11:06:42 -080014664 hddLog(VOS_TRACE_LEVEL_INFO,
14665 "tdls send discover req: "MAC_ADDRESS_STR,
14666 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053014667
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014668#if TDLS_MGMT_VERSION2
14669 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14670 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
14671#else
Chilam NG571c65a2013-01-19 12:27:36 +053014672 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14673 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014674#endif
Chilam NG571c65a2013-01-19 12:27:36 +053014675}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014676#endif
14677
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014678#ifdef WLAN_FEATURE_GTK_OFFLOAD
14679/*
14680 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
14681 * Callback rountine called upon receiving response for
14682 * get offload info
14683 */
14684void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
14685 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
14686{
14687
14688 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014689 tANI_U8 tempReplayCounter[8];
14690 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014691
14692 ENTER();
14693
14694 if (NULL == pAdapter)
14695 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014697 "%s: HDD adapter is Null", __func__);
14698 return ;
14699 }
14700
14701 if (NULL == pGtkOffloadGetInfoRsp)
14702 {
14703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14704 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
14705 return ;
14706 }
14707
14708 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
14709 {
14710 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14711 "%s: wlan Failed to get replay counter value",
14712 __func__);
14713 return ;
14714 }
14715
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014716 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14717 /* Update replay counter */
14718 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
14719 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14720
14721 {
14722 /* changing from little to big endian since supplicant
14723 * works on big endian format
14724 */
14725 int i;
14726 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14727
14728 for (i = 0; i < 8; i++)
14729 {
14730 tempReplayCounter[7-i] = (tANI_U8)p[i];
14731 }
14732 }
14733
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014734 /* Update replay counter to NL */
14735 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014736 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014737}
14738
14739/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014740 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014741 * This function is used to offload GTK rekeying job to the firmware.
14742 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014743int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014744 struct cfg80211_gtk_rekey_data *data)
14745{
14746 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14747 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14748 hdd_station_ctx_t *pHddStaCtx;
14749 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014750 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014751 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014752 eHalStatus status = eHAL_STATUS_FAILURE;
14753
14754 ENTER();
14755
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014756
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014757 if (NULL == pAdapter)
14758 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014760 "%s: HDD adapter is Null", __func__);
14761 return -ENODEV;
14762 }
14763
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014764 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14765 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
14766 pAdapter->sessionId, pAdapter->device_mode));
14767
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014768 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014769
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014770 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014771 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014772 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14773 "%s: HDD context is not valid", __func__);
14774 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014775 }
14776
14777 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14778 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14779 if (NULL == hHal)
14780 {
14781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14782 "%s: HAL context is Null!!!", __func__);
14783 return -EAGAIN;
14784 }
14785
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014786 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
14787 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
14788 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
14789 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014790 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014791 {
14792 /* changing from big to little endian since driver
14793 * works on little endian format
14794 */
14795 tANI_U8 *p =
14796 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
14797 int i;
14798
14799 for (i = 0; i < 8; i++)
14800 {
14801 p[7-i] = data->replay_ctr[i];
14802 }
14803 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014804
14805 if (TRUE == pHddCtx->hdd_wlan_suspended)
14806 {
14807 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014808 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
14809 sizeof (tSirGtkOffloadParams));
14810 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014811 pAdapter->sessionId);
14812
14813 if (eHAL_STATUS_SUCCESS != status)
14814 {
14815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14816 "%s: sme_SetGTKOffload failed, returned %d",
14817 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053014818
14819 /* Need to clear any trace of key value in the memory.
14820 * Thus zero out the memory even though it is local
14821 * variable.
14822 */
14823 vos_mem_zero(&hddGtkOffloadReqParams,
14824 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014825 return status;
14826 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14828 "%s: sme_SetGTKOffload successfull", __func__);
14829 }
14830 else
14831 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014832 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14833 "%s: wlan not suspended GTKOffload request is stored",
14834 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014835 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014836
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053014837 /* Need to clear any trace of key value in the memory.
14838 * Thus zero out the memory even though it is local
14839 * variable.
14840 */
14841 vos_mem_zero(&hddGtkOffloadReqParams,
14842 sizeof(hddGtkOffloadReqParams));
14843
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014844 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014845}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014846
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014847int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
14848 struct cfg80211_gtk_rekey_data *data)
14849{
14850 int ret;
14851
14852 vos_ssr_protect(__func__);
14853 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
14854 vos_ssr_unprotect(__func__);
14855
14856 return ret;
14857}
14858#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014859/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014860 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014861 * This function is used to set access control policy
14862 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014863static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
14864 struct net_device *dev,
14865 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014866{
14867 int i;
14868 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14869 hdd_hostapd_state_t *pHostapdState;
14870 tsap_Config_t *pConfig;
14871 v_CONTEXT_t pVosContext = NULL;
14872 hdd_context_t *pHddCtx;
14873 int status;
14874
14875 ENTER();
14876
14877 if (NULL == pAdapter)
14878 {
14879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14880 "%s: HDD adapter is Null", __func__);
14881 return -ENODEV;
14882 }
14883
14884 if (NULL == params)
14885 {
14886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14887 "%s: params is Null", __func__);
14888 return -EINVAL;
14889 }
14890
14891 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14892 status = wlan_hdd_validate_context(pHddCtx);
14893
14894 if (0 != status)
14895 {
14896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14897 "%s: HDD context is not valid", __func__);
14898 return status;
14899 }
14900
14901 pVosContext = pHddCtx->pvosContext;
14902 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
14903
14904 if (NULL == pHostapdState)
14905 {
14906 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14907 "%s: pHostapdState is Null", __func__);
14908 return -EINVAL;
14909 }
14910
14911 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
14912 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
14913
14914 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
14915 {
14916 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
14917
14918 /* default value */
14919 pConfig->num_accept_mac = 0;
14920 pConfig->num_deny_mac = 0;
14921
14922 /**
14923 * access control policy
14924 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
14925 * listed in hostapd.deny file.
14926 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
14927 * listed in hostapd.accept file.
14928 */
14929 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
14930 {
14931 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
14932 }
14933 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
14934 {
14935 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
14936 }
14937 else
14938 {
14939 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14940 "%s:Acl Policy : %d is not supported",
14941 __func__, params->acl_policy);
14942 return -ENOTSUPP;
14943 }
14944
14945 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
14946 {
14947 pConfig->num_accept_mac = params->n_acl_entries;
14948 for (i = 0; i < params->n_acl_entries; i++)
14949 {
14950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14951 "** Add ACL MAC entry %i in WhiletList :"
14952 MAC_ADDRESS_STR, i,
14953 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14954
14955 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
14956 sizeof(qcmacaddr));
14957 }
14958 }
14959 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
14960 {
14961 pConfig->num_deny_mac = params->n_acl_entries;
14962 for (i = 0; i < params->n_acl_entries; i++)
14963 {
14964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14965 "** Add ACL MAC entry %i in BlackList :"
14966 MAC_ADDRESS_STR, i,
14967 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14968
14969 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
14970 sizeof(qcmacaddr));
14971 }
14972 }
14973
14974 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
14975 {
14976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14977 "%s: SAP Set Mac Acl fail", __func__);
14978 return -EINVAL;
14979 }
14980 }
14981 else
14982 {
14983 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014984 "%s: Invalid device_mode = %s (%d)",
14985 __func__, hdd_device_modetoString(pAdapter->device_mode),
14986 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014987 return -EINVAL;
14988 }
14989
14990 return 0;
14991}
14992
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014993static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
14994 struct net_device *dev,
14995 const struct cfg80211_acl_data *params)
14996{
14997 int ret;
14998 vos_ssr_protect(__func__);
14999 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
15000 vos_ssr_unprotect(__func__);
15001
15002 return ret;
15003}
15004
Leo Chang9056f462013-08-01 19:21:11 -070015005#ifdef WLAN_NL80211_TESTMODE
15006#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070015007void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070015008(
15009 void *pAdapter,
15010 void *indCont
15011)
15012{
Leo Changd9df8aa2013-09-26 13:32:26 -070015013 tSirLPHBInd *lphbInd;
15014 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053015015 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070015016
15017 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070015018 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070015019
c_hpothu73f35e62014-04-18 13:40:08 +053015020 if (pAdapter == NULL)
15021 {
15022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15023 "%s: pAdapter is NULL\n",__func__);
15024 return;
15025 }
15026
Leo Chang9056f462013-08-01 19:21:11 -070015027 if (NULL == indCont)
15028 {
15029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070015030 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070015031 return;
15032 }
15033
c_hpothu73f35e62014-04-18 13:40:08 +053015034 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070015035 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070015036 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053015037 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070015038 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070015039 GFP_ATOMIC);
15040 if (!skb)
15041 {
15042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15043 "LPHB timeout, NL buffer alloc fail");
15044 return;
15045 }
15046
Leo Changac3ba772013-10-07 09:47:04 -070015047 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070015048 {
15049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15050 "WLAN_HDD_TM_ATTR_CMD put fail");
15051 goto nla_put_failure;
15052 }
Leo Changac3ba772013-10-07 09:47:04 -070015053 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070015054 {
15055 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15056 "WLAN_HDD_TM_ATTR_TYPE put fail");
15057 goto nla_put_failure;
15058 }
Leo Changac3ba772013-10-07 09:47:04 -070015059 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070015060 sizeof(tSirLPHBInd), lphbInd))
15061 {
15062 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15063 "WLAN_HDD_TM_ATTR_DATA put fail");
15064 goto nla_put_failure;
15065 }
Leo Chang9056f462013-08-01 19:21:11 -070015066 cfg80211_testmode_event(skb, GFP_ATOMIC);
15067 return;
15068
15069nla_put_failure:
15070 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15071 "NLA Put fail");
15072 kfree_skb(skb);
15073
15074 return;
15075}
15076#endif /* FEATURE_WLAN_LPHB */
15077
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015078static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070015079{
15080 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
15081 int err = 0;
15082#ifdef FEATURE_WLAN_LPHB
15083 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070015084 eHalStatus smeStatus;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015085 err = wlan_hdd_validate_context(pHddCtx);
15086 if (0 != err)
15087 {
15088 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15089 "%s: HDD context is not valid", __func__);
15090 return err;
15091 }
Leo Chang9056f462013-08-01 19:21:11 -070015092#endif /* FEATURE_WLAN_LPHB */
15093
15094 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
15095 if (err)
15096 {
15097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15098 "%s Testmode INV ATTR", __func__);
15099 return err;
15100 }
15101
15102 if (!tb[WLAN_HDD_TM_ATTR_CMD])
15103 {
15104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15105 "%s Testmode INV CMD", __func__);
15106 return -EINVAL;
15107 }
15108
15109 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
15110 {
15111#ifdef FEATURE_WLAN_LPHB
15112 /* Low Power Heartbeat configuration request */
15113 case WLAN_HDD_TM_CMD_WLAN_HB:
15114 {
15115 int buf_len;
15116 void *buf;
15117 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080015118 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070015119
15120 if (!tb[WLAN_HDD_TM_ATTR_DATA])
15121 {
15122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15123 "%s Testmode INV DATA", __func__);
15124 return -EINVAL;
15125 }
15126
15127 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
15128 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080015129
15130 hb_params_temp =(tSirLPHBReq *)buf;
15131 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
15132 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
15133 return -EINVAL;
15134
Leo Chang9056f462013-08-01 19:21:11 -070015135 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
15136 if (NULL == hb_params)
15137 {
15138 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15139 "%s Request Buffer Alloc Fail", __func__);
15140 return -EINVAL;
15141 }
15142
15143 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070015144 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
15145 hb_params,
15146 wlan_hdd_cfg80211_lphb_ind_handler);
15147 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070015148 {
Leo Changd9df8aa2013-09-26 13:32:26 -070015149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15150 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070015151 vos_mem_free(hb_params);
15152 }
Leo Chang9056f462013-08-01 19:21:11 -070015153 return 0;
15154 }
15155#endif /* FEATURE_WLAN_LPHB */
15156 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015157 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15158 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070015159 return -EOPNOTSUPP;
15160 }
15161
15162 return err;
15163}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015164
15165static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
15166{
15167 int ret;
15168
15169 vos_ssr_protect(__func__);
15170 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
15171 vos_ssr_unprotect(__func__);
15172
15173 return ret;
15174}
Leo Chang9056f462013-08-01 19:21:11 -070015175#endif /* CONFIG_NL80211_TESTMODE */
15176
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015177static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015178 struct net_device *dev,
15179 int idx, struct survey_info *survey)
15180{
15181 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15182 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053015183 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015184 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053015185 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015186 v_S7_t snr,rssi;
15187 int status, i, j, filled = 0;
15188
15189 ENTER();
15190
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015191 if (NULL == pAdapter)
15192 {
15193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15194 "%s: HDD adapter is Null", __func__);
15195 return -ENODEV;
15196 }
15197
15198 if (NULL == wiphy)
15199 {
15200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15201 "%s: wiphy is Null", __func__);
15202 return -ENODEV;
15203 }
15204
15205 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15206 status = wlan_hdd_validate_context(pHddCtx);
15207
15208 if (0 != status)
15209 {
15210 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15211 "%s: HDD context is not valid", __func__);
15212 return status;
15213 }
15214
Mihir Sheted9072e02013-08-21 17:02:29 +053015215 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15216
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015217 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053015218 0 != pAdapter->survey_idx ||
15219 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015220 {
15221 /* The survey dump ops when implemented completely is expected to
15222 * return a survey of all channels and the ops is called by the
15223 * kernel with incremental values of the argument 'idx' till it
15224 * returns -ENONET. But we can only support the survey for the
15225 * operating channel for now. survey_idx is used to track
15226 * that the ops is called only once and then return -ENONET for
15227 * the next iteration
15228 */
15229 pAdapter->survey_idx = 0;
15230 return -ENONET;
15231 }
15232
15233 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15234
15235 wlan_hdd_get_snr(pAdapter, &snr);
15236 wlan_hdd_get_rssi(pAdapter, &rssi);
15237
15238 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
15239 hdd_wlan_get_freq(channel, &freq);
15240
15241
15242 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
15243 {
15244 if (NULL == wiphy->bands[i])
15245 {
15246 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
15247 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
15248 continue;
15249 }
15250
15251 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
15252 {
15253 struct ieee80211_supported_band *band = wiphy->bands[i];
15254
15255 if (band->channels[j].center_freq == (v_U16_t)freq)
15256 {
15257 survey->channel = &band->channels[j];
15258 /* The Rx BDs contain SNR values in dB for the received frames
15259 * while the supplicant expects noise. So we calculate and
15260 * return the value of noise (dBm)
15261 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
15262 */
15263 survey->noise = rssi - snr;
15264 survey->filled = SURVEY_INFO_NOISE_DBM;
15265 filled = 1;
15266 }
15267 }
15268 }
15269
15270 if (filled)
15271 pAdapter->survey_idx = 1;
15272 else
15273 {
15274 pAdapter->survey_idx = 0;
15275 return -ENONET;
15276 }
15277
15278 return 0;
15279}
15280
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015281static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
15282 struct net_device *dev,
15283 int idx, struct survey_info *survey)
15284{
15285 int ret;
15286
15287 vos_ssr_protect(__func__);
15288 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
15289 vos_ssr_unprotect(__func__);
15290
15291 return ret;
15292}
15293
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015294/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015295 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015296 * this is called when cfg80211 driver resume
15297 * driver updates latest sched_scan scan result(if any) to cfg80211 database
15298 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015299int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015300{
15301 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15302 hdd_adapter_t *pAdapter;
15303 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15304 VOS_STATUS status = VOS_STATUS_SUCCESS;
15305
15306 ENTER();
15307
15308 if ( NULL == pHddCtx )
15309 {
15310 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15311 "%s: HddCtx validation failed", __func__);
15312 return 0;
15313 }
15314
15315 if (pHddCtx->isLogpInProgress)
15316 {
15317 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15318 "%s: LOGP in Progress. Ignore!!!", __func__);
15319 return 0;
15320 }
15321
Mihir Shete18156292014-03-11 15:38:30 +053015322 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015323 {
15324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15325 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15326 return 0;
15327 }
15328
15329 spin_lock(&pHddCtx->schedScan_lock);
15330 pHddCtx->isWiphySuspended = FALSE;
15331 if (TRUE != pHddCtx->isSchedScanUpdatePending)
15332 {
15333 spin_unlock(&pHddCtx->schedScan_lock);
15334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15335 "%s: Return resume is not due to PNO indication", __func__);
15336 return 0;
15337 }
15338 // Reset flag to avoid updatating cfg80211 data old results again
15339 pHddCtx->isSchedScanUpdatePending = FALSE;
15340 spin_unlock(&pHddCtx->schedScan_lock);
15341
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015342
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015343 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15344
15345 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15346 {
15347 pAdapter = pAdapterNode->pAdapter;
15348 if ( (NULL != pAdapter) &&
15349 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
15350 {
15351 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015352 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15354 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015355 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015356 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015357 {
15358 /* Acquire wakelock to handle the case where APP's tries to
15359 * suspend immediately after updating the scan results. Whis
15360 * results in app's is in suspended state and not able to
15361 * process the connect request to AP
15362 */
15363 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015364 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015365 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015366
15367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15368 "%s : cfg80211 scan result database updated", __func__);
15369
15370 return 0;
15371
15372 }
15373 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15374 pAdapterNode = pNext;
15375 }
15376
15377 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15378 "%s: Failed to find Adapter", __func__);
15379 return 0;
15380}
15381
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015382int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
15383{
15384 int ret;
15385
15386 vos_ssr_protect(__func__);
15387 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
15388 vos_ssr_unprotect(__func__);
15389
15390 return ret;
15391}
15392
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015393/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015394 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015395 * this is called when cfg80211 driver suspends
15396 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015397int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015398 struct cfg80211_wowlan *wow)
15399{
15400 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015401 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015402
15403 ENTER();
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015404 ret = wlan_hdd_validate_context(pHddCtx);
15405 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015406 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015407 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15408 "%s: HDD context is not valid", __func__);
15409 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015410 }
15411
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015412
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015413 pHddCtx->isWiphySuspended = TRUE;
15414
15415 EXIT();
15416
15417 return 0;
15418}
15419
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015420int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
15421 struct cfg80211_wowlan *wow)
15422{
15423 int ret;
15424
15425 vos_ssr_protect(__func__);
15426 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
15427 vos_ssr_unprotect(__func__);
15428
15429 return ret;
15430}
Jeff Johnson295189b2012-06-20 16:38:30 -070015431/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015432static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070015433{
15434 .add_virtual_intf = wlan_hdd_add_virtual_intf,
15435 .del_virtual_intf = wlan_hdd_del_virtual_intf,
15436 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
15437 .change_station = wlan_hdd_change_station,
15438#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
15439 .add_beacon = wlan_hdd_cfg80211_add_beacon,
15440 .del_beacon = wlan_hdd_cfg80211_del_beacon,
15441 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015442#else
15443 .start_ap = wlan_hdd_cfg80211_start_ap,
15444 .change_beacon = wlan_hdd_cfg80211_change_beacon,
15445 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070015446#endif
15447 .change_bss = wlan_hdd_cfg80211_change_bss,
15448 .add_key = wlan_hdd_cfg80211_add_key,
15449 .get_key = wlan_hdd_cfg80211_get_key,
15450 .del_key = wlan_hdd_cfg80211_del_key,
15451 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015452#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070015453 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015454#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015455 .scan = wlan_hdd_cfg80211_scan,
15456 .connect = wlan_hdd_cfg80211_connect,
15457 .disconnect = wlan_hdd_cfg80211_disconnect,
15458 .join_ibss = wlan_hdd_cfg80211_join_ibss,
15459 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
15460 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
15461 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
15462 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070015463 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
15464 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053015465 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070015466#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15467 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
15468 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
15469 .set_txq_params = wlan_hdd_set_txq_params,
15470#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015471 .get_station = wlan_hdd_cfg80211_get_station,
15472 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
15473 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015474 .add_station = wlan_hdd_cfg80211_add_station,
15475#ifdef FEATURE_WLAN_LFR
15476 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
15477 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
15478 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
15479#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015480#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
15481 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
15482#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015483#ifdef FEATURE_WLAN_TDLS
15484 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
15485 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
15486#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015487#ifdef WLAN_FEATURE_GTK_OFFLOAD
15488 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
15489#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015490#ifdef FEATURE_WLAN_SCAN_PNO
15491 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
15492 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
15493#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015494 .resume = wlan_hdd_cfg80211_resume_wlan,
15495 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015496 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070015497#ifdef WLAN_NL80211_TESTMODE
15498 .testmode_cmd = wlan_hdd_cfg80211_testmode,
15499#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015500 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070015501};
15502