blob: ac4083d787a6e113babbea97a0c5a0671411b2f2 [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);
715 for (i = 0; i < stats->numRate; i++)
716 {
717 struct nlattr *rates;
718 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
719 stats->rateStats +
720 (i * sizeof(tSirWifiRateStat)));
721 rates = nla_nest_start(vendor_event, i);
722
723 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
724 {
725 hddLog(VOS_TRACE_LEVEL_ERROR,
726 FL("QCA_WLAN_VENDOR_ATTR put fail"));
727 return FALSE;
728 }
729 nla_nest_end(vendor_event, rates);
730 }
731 nla_nest_end(vendor_event, rateInfo);
732
733 return TRUE;
734error:
735 return FALSE;
736}
737
738static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
739 struct sk_buff *vendor_event)
740{
741 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
742 stats->ac ) ||
743 nla_put_u32(vendor_event,
744 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
745 stats->txMpdu ) ||
746 nla_put_u32(vendor_event,
747 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
748 stats->rxMpdu ) ||
749 nla_put_u32(vendor_event,
750 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
751 stats->txMcast ) ||
752 nla_put_u32(vendor_event,
753 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
754 stats->rxMcast ) ||
755 nla_put_u32(vendor_event,
756 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
757 stats->rxAmpdu ) ||
758 nla_put_u32(vendor_event,
759 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
760 stats->txAmpdu ) ||
761 nla_put_u32(vendor_event,
762 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
763 stats->mpduLost )||
764 nla_put_u32(vendor_event,
765 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
766 stats->retries ) ||
767 nla_put_u32(vendor_event,
768 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
769 stats->retriesShort ) ||
770 nla_put_u32(vendor_event,
771 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
772 stats->retriesLong ) ||
773 nla_put_u32(vendor_event,
774 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
775 stats->contentionTimeMin ) ||
776 nla_put_u32(vendor_event,
777 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
778 stats->contentionTimeMax ) ||
779 nla_put_u32(vendor_event,
780 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
781 stats->contentionTimeAvg ) ||
782 nla_put_u32(vendor_event,
783 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
784 stats->contentionNumSamples ))
785 {
786 hddLog(VOS_TRACE_LEVEL_ERROR,
787 FL("QCA_WLAN_VENDOR_ATTR put fail") );
788 return FALSE;
789 }
790 return TRUE;
791}
792
793static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
794 struct sk_buff *vendor_event)
795{
Dino Myclec8f3f332014-07-21 16:48:27 +0530796 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530797 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
798 nla_put(vendor_event,
799 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
800 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
801 nla_put_u32(vendor_event,
802 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
803 stats->state ) ||
804 nla_put_u32(vendor_event,
805 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
806 stats->roaming ) ||
807 nla_put_u32(vendor_event,
808 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
809 stats->capabilities ) ||
810 nla_put(vendor_event,
811 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
812 strlen(stats->ssid), stats->ssid) ||
813 nla_put(vendor_event,
814 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
815 WNI_CFG_BSSID_LEN, stats->bssid) ||
816 nla_put(vendor_event,
817 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
818 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
819 nla_put(vendor_event,
820 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
821 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
822 )
823 {
824 hddLog(VOS_TRACE_LEVEL_ERROR,
825 FL("QCA_WLAN_VENDOR_ATTR put fail") );
826 return FALSE;
827 }
828 return TRUE;
829}
830
Dino Mycle3b9536d2014-07-09 22:05:24 +0530831static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
832 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530833 struct sk_buff *vendor_event)
834{
835 int i = 0;
836 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530837 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
838 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530839 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530840
Sunil Duttc69bccb2014-05-26 21:30:20 +0530841 if (FALSE == put_wifi_interface_info(
842 &pWifiIfaceStat->info,
843 vendor_event))
844 {
845 hddLog(VOS_TRACE_LEVEL_ERROR,
846 FL("QCA_WLAN_VENDOR_ATTR put fail") );
847 return FALSE;
848
849 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530850 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
851 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
852 if (NULL == pWifiIfaceStatTL)
853 {
854 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
855 return FALSE;
856 }
857
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530858 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
859 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
860 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
861 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
862
863 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
864 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
865 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
866 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530867
868 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
869 {
870 if (VOS_STATUS_SUCCESS ==
871 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
872 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
873 {
874 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
875 * obtained from TL structure
876 */
877
878 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
879 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530880 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
881
Srinivas Dasari98947432014-11-07 19:41:24 +0530882 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
883 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
884 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
885 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
886 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
887 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
888 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
889 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530890
Srinivas Dasari98947432014-11-07 19:41:24 +0530891 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
892 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
893 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
894 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
895 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
896 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
897 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
898 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530899
Srinivas Dasari98947432014-11-07 19:41:24 +0530900 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
901 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
902 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
903 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
904 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
905 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
906 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
907 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530908 }
909 else
910 {
911 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
912 }
913
Dino Mycle3b9536d2014-07-09 22:05:24 +0530914 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
915 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
916 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
917 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
918 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
919 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
920 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
921 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
922 }
923 else
924 {
925 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
926 }
927
928
Sunil Duttc69bccb2014-05-26 21:30:20 +0530929
930 if (nla_put_u32(vendor_event,
931 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
932 pWifiIfaceStat->beaconRx) ||
933 nla_put_u32(vendor_event,
934 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
935 pWifiIfaceStat->mgmtRx) ||
936 nla_put_u32(vendor_event,
937 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
938 pWifiIfaceStat->mgmtActionRx) ||
939 nla_put_u32(vendor_event,
940 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
941 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530942 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530943 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
944 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530945 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530946 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
947 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530948 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530949 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
950 pWifiIfaceStat->rssiAck))
951 {
952 hddLog(VOS_TRACE_LEVEL_ERROR,
953 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530954 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530955 return FALSE;
956 }
957
958 wmmInfo = nla_nest_start(vendor_event,
959 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
960 for (i = 0; i < WIFI_AC_MAX; i++)
961 {
962 struct nlattr *wmmStats;
963 wmmStats = nla_nest_start(vendor_event, i);
964 if (FALSE == put_wifi_wmm_ac_stat(
965 &pWifiIfaceStat->AccessclassStats[i],
966 vendor_event))
967 {
968 hddLog(VOS_TRACE_LEVEL_ERROR,
969 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530970 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530971 return FALSE;
972 }
973
974 nla_nest_end(vendor_event, wmmStats);
975 }
976 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +0530977 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530978 return TRUE;
979}
980
981static tSirWifiInterfaceMode
982 hdd_map_device_to_ll_iface_mode ( int deviceMode )
983{
984 switch (deviceMode)
985 {
986 case WLAN_HDD_INFRA_STATION:
987 return WIFI_INTERFACE_STA;
988 case WLAN_HDD_SOFTAP:
989 return WIFI_INTERFACE_SOFTAP;
990 case WLAN_HDD_P2P_CLIENT:
991 return WIFI_INTERFACE_P2P_CLIENT;
992 case WLAN_HDD_P2P_GO:
993 return WIFI_INTERFACE_P2P_GO;
994 case WLAN_HDD_IBSS:
995 return WIFI_INTERFACE_IBSS;
996 default:
Dino Myclec8f3f332014-07-21 16:48:27 +0530997 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530998 }
999}
1000
1001static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1002 tpSirWifiInterfaceInfo pInfo)
1003{
1004 v_U8_t *staMac = NULL;
1005 hdd_station_ctx_t *pHddStaCtx;
1006 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1007 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1008
1009 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1010
1011 vos_mem_copy(pInfo->macAddr,
1012 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1013
1014 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1015 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1016 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1017 {
1018 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1019 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1020 {
1021 pInfo->state = WIFI_DISCONNECTED;
1022 }
1023 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1024 {
1025 hddLog(VOS_TRACE_LEVEL_ERROR,
1026 "%s: Session ID %d, Connection is in progress", __func__,
1027 pAdapter->sessionId);
1028 pInfo->state = WIFI_ASSOCIATING;
1029 }
1030 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1031 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1032 {
1033 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1034 hddLog(VOS_TRACE_LEVEL_ERROR,
1035 "%s: client " MAC_ADDRESS_STR
1036 " is in the middle of WPS/EAPOL exchange.", __func__,
1037 MAC_ADDR_ARRAY(staMac));
1038 pInfo->state = WIFI_AUTHENTICATING;
1039 }
1040 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1041 {
1042 pInfo->state = WIFI_ASSOCIATED;
1043 vos_mem_copy(pInfo->bssid,
1044 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1045 vos_mem_copy(pInfo->ssid,
1046 pHddStaCtx->conn_info.SSID.SSID.ssId,
1047 pHddStaCtx->conn_info.SSID.SSID.length);
1048 //NULL Terminate the string.
1049 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1050 }
1051 }
1052 vos_mem_copy(pInfo->countryStr,
1053 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1054
1055 vos_mem_copy(pInfo->apCountryStr,
1056 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1057
1058 return TRUE;
1059}
1060
1061/*
1062 * hdd_link_layer_process_peer_stats () - This function is called after
1063 * receiving Link Layer Peer statistics from FW.This function converts
1064 * the firmware data to the NL data and sends the same to the kernel/upper
1065 * layers.
1066 */
1067static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1068 v_VOID_t *pData)
1069{
1070 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1071 tpSirWifiRateStat pWifiRateStat;
1072 tpSirWifiPeerStat pWifiPeerStat;
1073 tpSirWifiPeerInfo pWifiPeerInfo;
1074 struct nlattr *peerInfo;
1075 struct sk_buff *vendor_event;
1076 int status, i;
1077
1078 status = wlan_hdd_validate_context(pHddCtx);
1079 if (0 != status)
1080 {
1081 hddLog(VOS_TRACE_LEVEL_ERROR,
1082 FL("HDD context is not valid") );
1083 return;
1084 }
1085
1086 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1087
1088 hddLog(VOS_TRACE_LEVEL_INFO,
1089 "LL_STATS_PEER_ALL : numPeers %u",
1090 pWifiPeerStat->numPeers);
1091 {
1092 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1093 {
1094 pWifiPeerInfo = (tpSirWifiPeerInfo)
1095 ((uint8 *)pWifiPeerStat->peerInfo +
1096 ( i * sizeof(tSirWifiPeerInfo)));
1097
Dasari Srinivas1be0c4e2014-10-19 13:03:41 +05301098 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) {
1099 pWifiPeerInfo->type = WIFI_PEER_AP;
1100 }
1101 if (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) {
1102 pWifiPeerInfo->type = WIFI_PEER_P2P_GO;
1103 }
1104
Sunil Duttc69bccb2014-05-26 21:30:20 +05301105 hddLog(VOS_TRACE_LEVEL_INFO,
1106 " %d) LL_STATS Channel Stats "
1107 " Peer Type %u "
1108 " peerMacAddress %pM "
1109 " capabilities 0x%x "
1110 " numRate %u ",
1111 i,
1112 pWifiPeerInfo->type,
1113 pWifiPeerInfo->peerMacAddress,
1114 pWifiPeerInfo->capabilities,
1115 pWifiPeerInfo->numRate);
1116 {
1117 int j;
1118 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1119 {
1120 pWifiRateStat = (tpSirWifiRateStat)
1121 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1122 ( j * sizeof(tSirWifiRateStat)));
1123
1124 hddLog(VOS_TRACE_LEVEL_INFO,
1125 " peer Rate Stats "
1126 " preamble %u "
1127 " nss %u "
1128 " bw %u "
1129 " rateMcsIdx %u "
1130 " reserved %u "
1131 " bitrate %u "
1132 " txMpdu %u "
1133 " rxMpdu %u "
1134 " mpduLost %u "
1135 " retries %u "
1136 " retriesShort %u "
1137 " retriesLong %u",
1138 pWifiRateStat->rate.preamble,
1139 pWifiRateStat->rate.nss,
1140 pWifiRateStat->rate.bw,
1141 pWifiRateStat->rate.rateMcsIdx,
1142 pWifiRateStat->rate.reserved,
1143 pWifiRateStat->rate.bitrate,
1144 pWifiRateStat->txMpdu,
1145 pWifiRateStat->rxMpdu,
1146 pWifiRateStat->mpduLost,
1147 pWifiRateStat->retries,
1148 pWifiRateStat->retriesShort,
1149 pWifiRateStat->retriesLong);
1150 }
1151 }
1152 }
1153 }
1154
1155 /*
1156 * Allocate a size of 4096 for the peer stats comprising
1157 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1158 * sizeof (tSirWifiRateStat).Each field is put with an
1159 * NL attribute.The size of 4096 is considered assuming
1160 * that number of rates shall not exceed beyond 50 with
1161 * the sizeof (tSirWifiRateStat) being 32.
1162 */
1163 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1164 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1165 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1166 GFP_KERNEL);
1167 if (!vendor_event)
1168 {
1169 hddLog(VOS_TRACE_LEVEL_ERROR,
1170 "%s: cfg80211_vendor_event_alloc failed",
1171 __func__);
1172 return;
1173 }
1174 if (nla_put_u32(vendor_event,
1175 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1176 pWifiPeerStat->numPeers))
1177 {
1178 hddLog(VOS_TRACE_LEVEL_ERROR,
1179 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1180 kfree_skb(vendor_event);
1181 return;
1182 }
1183
1184 peerInfo = nla_nest_start(vendor_event,
1185 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
1186
1187 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1188 pWifiPeerStat->peerInfo);
1189
1190 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1191 {
1192 struct nlattr *peers = nla_nest_start(vendor_event, i);
1193 int numRate = pWifiPeerInfo->numRate;
1194
1195 if (FALSE == put_wifi_peer_info(
1196 pWifiPeerInfo, vendor_event))
1197 {
1198 hddLog(VOS_TRACE_LEVEL_ERROR,
1199 "%s: put_wifi_peer_info put fail", __func__);
1200 kfree_skb(vendor_event);
1201 return;
1202 }
1203
1204 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1205 pWifiPeerStat->peerInfo +
1206 (i * sizeof(tSirWifiPeerInfo)) +
1207 (numRate * sizeof (tSirWifiRateStat)));
1208 nla_nest_end(vendor_event, peers);
1209 }
1210 nla_nest_end(vendor_event, peerInfo);
1211 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1212}
1213
1214/*
1215 * hdd_link_layer_process_iface_stats () - This function is called after
1216 * receiving Link Layer Interface statistics from FW.This function converts
1217 * the firmware data to the NL data and sends the same to the kernel/upper
1218 * layers.
1219 */
1220static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1221 v_VOID_t *pData)
1222{
1223 tpSirWifiIfaceStat pWifiIfaceStat;
1224 struct sk_buff *vendor_event;
1225 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1226 int status;
1227
1228 status = wlan_hdd_validate_context(pHddCtx);
1229 if (0 != status)
1230 {
1231 hddLog(VOS_TRACE_LEVEL_ERROR,
1232 FL("HDD context is not valid") );
1233 return;
1234 }
1235 /*
1236 * Allocate a size of 4096 for the interface stats comprising
1237 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1238 * assuming that all these fit with in the limit.Please take
1239 * a call on the limit based on the data requirements on
1240 * interface statistics.
1241 */
1242 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1243 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1244 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1245 GFP_KERNEL);
1246 if (!vendor_event)
1247 {
1248 hddLog(VOS_TRACE_LEVEL_ERROR,
1249 FL("cfg80211_vendor_event_alloc failed") );
1250 return;
1251 }
1252
1253 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1254
Dino Mycle3b9536d2014-07-09 22:05:24 +05301255
1256 if (FALSE == hdd_get_interface_info( pAdapter,
1257 &pWifiIfaceStat->info))
1258 {
1259 hddLog(VOS_TRACE_LEVEL_ERROR,
1260 FL("hdd_get_interface_info get fail") );
1261 kfree_skb(vendor_event);
1262 return;
1263 }
1264
1265 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1266 vendor_event))
1267 {
1268 hddLog(VOS_TRACE_LEVEL_ERROR,
1269 FL("put_wifi_iface_stats fail") );
1270 kfree_skb(vendor_event);
1271 return;
1272 }
1273
Sunil Duttc69bccb2014-05-26 21:30:20 +05301274 hddLog(VOS_TRACE_LEVEL_INFO,
1275 "WMI_LINK_STATS_IFACE Data");
1276
1277 hddLog(VOS_TRACE_LEVEL_INFO,
1278 "LL_STATS_IFACE: "
1279 " Mode %u "
1280 " MAC %pM "
1281 " State %u "
1282 " Roaming %u "
1283 " capabilities 0x%x "
1284 " SSID %s "
1285 " BSSID %pM",
1286 pWifiIfaceStat->info.mode,
1287 pWifiIfaceStat->info.macAddr,
1288 pWifiIfaceStat->info.state,
1289 pWifiIfaceStat->info.roaming,
1290 pWifiIfaceStat->info.capabilities,
1291 pWifiIfaceStat->info.ssid,
1292 pWifiIfaceStat->info.bssid);
1293
1294 hddLog(VOS_TRACE_LEVEL_INFO,
1295 " AP country str: %c%c%c",
1296 pWifiIfaceStat->info.apCountryStr[0],
1297 pWifiIfaceStat->info.apCountryStr[1],
1298 pWifiIfaceStat->info.apCountryStr[2]);
1299
1300
1301 hddLog(VOS_TRACE_LEVEL_INFO,
1302 " Country Str Association: %c%c%c",
1303 pWifiIfaceStat->info.countryStr[0],
1304 pWifiIfaceStat->info.countryStr[1],
1305 pWifiIfaceStat->info.countryStr[2]);
1306
1307 hddLog(VOS_TRACE_LEVEL_INFO,
1308 " beaconRx %u "
1309 " mgmtRx %u "
1310 " mgmtActionRx %u "
1311 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301312 " rssiMgmt %d "
1313 " rssiData %d "
1314 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301315 pWifiIfaceStat->beaconRx,
1316 pWifiIfaceStat->mgmtRx,
1317 pWifiIfaceStat->mgmtActionRx,
1318 pWifiIfaceStat->mgmtActionTx,
1319 pWifiIfaceStat->rssiMgmt,
1320 pWifiIfaceStat->rssiData,
1321 pWifiIfaceStat->rssiAck );
1322
1323
1324 {
1325 int i;
1326 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1327 {
1328 hddLog(VOS_TRACE_LEVEL_INFO,
1329
1330 " %d) LL_STATS IFACE: "
1331 " ac: %u txMpdu: %u "
1332 " rxMpdu: %u txMcast: %u "
1333 " rxMcast: %u rxAmpdu: %u "
1334 " txAmpdu: %u mpduLost: %u "
1335 " retries: %u retriesShort: %u "
1336 " retriesLong: %u contentionTimeMin: %u "
1337 " contentionTimeMax: %u contentionTimeAvg: %u "
1338 " contentionNumSamples: %u",
1339 i,
1340 pWifiIfaceStat->AccessclassStats[i].ac,
1341 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1342 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1343 pWifiIfaceStat->AccessclassStats[i].txMcast,
1344 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1345 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1346 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1347 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1348 pWifiIfaceStat->AccessclassStats[i].retries,
1349 pWifiIfaceStat->
1350 AccessclassStats[i].retriesShort,
1351 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1352 pWifiIfaceStat->
1353 AccessclassStats[i].contentionTimeMin,
1354 pWifiIfaceStat->
1355 AccessclassStats[i].contentionTimeMax,
1356 pWifiIfaceStat->
1357 AccessclassStats[i].contentionTimeAvg,
1358 pWifiIfaceStat->
1359 AccessclassStats[i].contentionNumSamples);
1360
1361 }
1362 }
1363
Sunil Duttc69bccb2014-05-26 21:30:20 +05301364 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1365}
1366
1367/*
1368 * hdd_link_layer_process_radio_stats () - This function is called after
1369 * receiving Link Layer Radio statistics from FW.This function converts
1370 * the firmware data to the NL data and sends the same to the kernel/upper
1371 * layers.
1372 */
1373static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1374 v_VOID_t *pData)
1375{
1376 int status, i;
1377 tpSirWifiRadioStat pWifiRadioStat;
1378 tpSirWifiChannelStats pWifiChannelStats;
1379 struct sk_buff *vendor_event;
1380 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1381 struct nlattr *chList;
1382
1383 status = wlan_hdd_validate_context(pHddCtx);
1384 if (0 != status)
1385 {
1386 hddLog(VOS_TRACE_LEVEL_ERROR,
1387 FL("HDD context is not valid") );
1388 return;
1389 }
1390 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1391
1392 hddLog(VOS_TRACE_LEVEL_INFO,
1393 "LL_STATS_RADIO"
1394 " radio is %d onTime is %u "
1395 " txTime is %u rxTime is %u "
1396 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301397 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301398 " onTimePnoScan is %u onTimeHs20 is %u "
1399 " numChannels is %u",
1400 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1401 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1402 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301403 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301404 pWifiRadioStat->onTimeRoamScan,
1405 pWifiRadioStat->onTimePnoScan,
1406 pWifiRadioStat->onTimeHs20,
1407 pWifiRadioStat->numChannels);
1408 /*
1409 * Allocate a size of 4096 for the Radio stats comprising
1410 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1411 * (tSirWifiChannelStats).Each channel data is put with an
1412 * NL attribute.The size of 4096 is considered assuming that
1413 * number of channels shall not exceed beyond 60 with the
1414 * sizeof (tSirWifiChannelStats) being 24 bytes.
1415 */
1416
1417 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1418 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1419 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1420 GFP_KERNEL);
1421
1422 if (!vendor_event)
1423 {
1424 hddLog(VOS_TRACE_LEVEL_ERROR,
1425 FL("cfg80211_vendor_event_alloc failed") );
1426 return;
1427 }
1428
1429 if (nla_put_u32(vendor_event,
1430 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1431 pWifiRadioStat->radio) ||
1432 nla_put_u32(vendor_event,
1433 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1434 pWifiRadioStat->onTime) ||
1435 nla_put_u32(vendor_event,
1436 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1437 pWifiRadioStat->txTime) ||
1438 nla_put_u32(vendor_event,
1439 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1440 pWifiRadioStat->rxTime) ||
1441 nla_put_u32(vendor_event,
1442 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1443 pWifiRadioStat->onTimeScan) ||
1444 nla_put_u32(vendor_event,
1445 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1446 pWifiRadioStat->onTimeNbd) ||
1447 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301448 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1449 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301450 nla_put_u32(vendor_event,
1451 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1452 pWifiRadioStat->onTimeRoamScan) ||
1453 nla_put_u32(vendor_event,
1454 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1455 pWifiRadioStat->onTimePnoScan) ||
1456 nla_put_u32(vendor_event,
1457 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1458 pWifiRadioStat->onTimeHs20) ||
1459 nla_put_u32(vendor_event,
1460 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1461 pWifiRadioStat->numChannels))
1462 {
1463 hddLog(VOS_TRACE_LEVEL_ERROR,
1464 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1465 kfree_skb(vendor_event);
1466 return ;
1467 }
1468
1469 chList = nla_nest_start(vendor_event,
1470 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
1471 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1472 {
1473 struct nlattr *chInfo;
1474
1475 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1476 pWifiRadioStat->channels +
1477 (i * sizeof(tSirWifiChannelStats)));
1478
1479 hddLog(VOS_TRACE_LEVEL_INFO,
1480 " %d) Channel Info"
1481 " width is %u "
1482 " CenterFreq %u "
1483 " CenterFreq0 %u "
1484 " CenterFreq1 %u "
1485 " onTime %u "
1486 " ccaBusyTime %u",
1487 i,
1488 pWifiChannelStats->channel.width,
1489 pWifiChannelStats->channel.centerFreq,
1490 pWifiChannelStats->channel.centerFreq0,
1491 pWifiChannelStats->channel.centerFreq1,
1492 pWifiChannelStats->onTime,
1493 pWifiChannelStats->ccaBusyTime);
1494
1495
1496 chInfo = nla_nest_start(vendor_event, i);
1497
1498 if (nla_put_u32(vendor_event,
1499 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1500 pWifiChannelStats->channel.width) ||
1501 nla_put_u32(vendor_event,
1502 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1503 pWifiChannelStats->channel.centerFreq) ||
1504 nla_put_u32(vendor_event,
1505 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1506 pWifiChannelStats->channel.centerFreq0) ||
1507 nla_put_u32(vendor_event,
1508 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1509 pWifiChannelStats->channel.centerFreq1) ||
1510 nla_put_u32(vendor_event,
1511 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1512 pWifiChannelStats->onTime) ||
1513 nla_put_u32(vendor_event,
1514 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1515 pWifiChannelStats->ccaBusyTime))
1516 {
1517 hddLog(VOS_TRACE_LEVEL_ERROR,
1518 FL("cfg80211_vendor_event_alloc failed") );
1519 kfree_skb(vendor_event);
1520 return ;
1521 }
1522 nla_nest_end(vendor_event, chInfo);
1523 }
1524 nla_nest_end(vendor_event, chList);
1525
1526 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1527 return;
1528}
1529
1530/*
1531 * hdd_link_layer_stats_ind_callback () - This function is called after
1532 * receiving Link Layer indications from FW.This callback converts the firmware
1533 * data to the NL data and send the same to the kernel/upper layers.
1534 */
1535static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1536 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301537 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301538{
Dino Mycled3d50022014-07-07 12:58:25 +05301539 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1540 hdd_adapter_t *pAdapter = NULL;
1541 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301542 int status;
1543
1544 status = wlan_hdd_validate_context(pHddCtx);
1545
1546 if (0 != status)
1547 {
1548 hddLog(VOS_TRACE_LEVEL_ERROR,
1549 FL("HDD context is not valid"));
1550 return;
1551 }
1552
Dino Mycled3d50022014-07-07 12:58:25 +05301553
1554
1555 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1556 if (NULL == pAdapter)
1557 {
1558 hddLog(VOS_TRACE_LEVEL_ERROR,
1559 FL(" MAC address %pM does not exist with host"),
1560 macAddr);
1561 return;
1562 }
1563
Sunil Duttc69bccb2014-05-26 21:30:20 +05301564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301565 "%s: Interface: %s LLStats indType: %d", __func__,
1566 pAdapter->dev->name, indType);
1567
Sunil Duttc69bccb2014-05-26 21:30:20 +05301568 switch (indType)
1569 {
1570 case SIR_HAL_LL_STATS_RESULTS_RSP:
1571 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301572 hddLog(VOS_TRACE_LEVEL_INFO,
1573 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1574 hddLog(VOS_TRACE_LEVEL_INFO,
1575 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1576 linkLayerStatsResults->paramId);
1577 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301578 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1579 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301580 hddLog(VOS_TRACE_LEVEL_INFO,
1581 "LL_STATS RESULTS RESPONSE respId = %u",
1582 linkLayerStatsResults->respId);
1583 hddLog(VOS_TRACE_LEVEL_INFO,
1584 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1585 linkLayerStatsResults->moreResultToFollow);
1586 hddLog(VOS_TRACE_LEVEL_INFO,
1587 "LL_STATS RESULTS RESPONSE result = %p",
1588 linkLayerStatsResults->result);
1589 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1590 {
1591 hdd_link_layer_process_radio_stats(pAdapter,
1592 (v_VOID_t *)linkLayerStatsResults->result);
1593 }
1594 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1595 {
1596 hdd_link_layer_process_iface_stats(pAdapter,
1597 (v_VOID_t *)linkLayerStatsResults->result);
1598 }
1599 else if ( linkLayerStatsResults->paramId &
1600 WMI_LINK_STATS_ALL_PEER )
1601 {
1602 hdd_link_layer_process_peer_stats(pAdapter,
1603 (v_VOID_t *)linkLayerStatsResults->result);
1604 } /* WMI_LINK_STATS_ALL_PEER */
1605 else
1606 {
1607 hddLog(VOS_TRACE_LEVEL_ERROR,
1608 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1609 }
1610
1611 break;
1612 }
1613 default:
1614 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1615 break;
1616 }
1617 return;
1618}
1619
1620const struct
1621nla_policy
1622qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1623{
1624 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1625 { .type = NLA_U32 },
1626 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1627 { .type = NLA_U32 },
1628};
1629
1630static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1631 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05301632 const void *data,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301633 int data_len)
1634{
1635 int status;
1636 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301637 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301638 struct net_device *dev = wdev->netdev;
1639 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1640 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Srinivas Dasari98947432014-11-07 19:41:24 +05301641 hdd_station_ctx_t *pHddStaCtx;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301642
1643 status = wlan_hdd_validate_context(pHddCtx);
1644 if (0 != status)
1645 {
1646 hddLog(VOS_TRACE_LEVEL_ERROR,
1647 FL("HDD context is not valid"));
1648 return -EINVAL;
1649 }
1650
1651 if (NULL == pAdapter)
1652 {
1653 hddLog(VOS_TRACE_LEVEL_ERROR,
1654 FL("HDD adapter is Null"));
1655 return -ENODEV;
1656 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301657 /* check the LLStats Capability */
1658 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1659 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1660 {
1661 hddLog(VOS_TRACE_LEVEL_ERROR,
1662 FL("Link Layer Statistics not supported by Firmware"));
1663 return -EINVAL;
1664 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301665
1666 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1667 (struct nlattr *)data,
1668 data_len, qca_wlan_vendor_ll_set_policy))
1669 {
1670 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1671 return -EINVAL;
1672 }
1673 if (!tb_vendor
1674 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1675 {
1676 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1677 return -EINVAL;
1678 }
1679 if (!tb_vendor[
1680 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1681 {
1682 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1683 return -EINVAL;
1684 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301685 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301686 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301687
Dino Mycledf0a5d92014-07-04 09:41:55 +05301688 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301689 nla_get_u32(
1690 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1691
Dino Mycledf0a5d92014-07-04 09:41:55 +05301692 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301693 nla_get_u32(
1694 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1695
Dino Mycled3d50022014-07-07 12:58:25 +05301696 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1697 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301698
1699
1700 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301701 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301702 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301703 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301704 hddLog(VOS_TRACE_LEVEL_INFO,
1705 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301706 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301707 hddLog(VOS_TRACE_LEVEL_INFO,
1708 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301709 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301710
1711 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1712 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301713 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301714 {
1715 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1716 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301717 return -EINVAL;
1718
1719 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301720
1721 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1722 if (VOS_STATUS_SUCCESS !=
1723 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1724 pHddStaCtx->conn_info.staId[0], WIFI_STATS_IFACE))
1725 {
1726 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1727 "WLANTL_ClearInterfaceStats Failed", __func__);
1728 return -EINVAL;
1729 }
1730
1731 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
1732 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
1733 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
1734 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
1735
Sunil Duttc69bccb2014-05-26 21:30:20 +05301736 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301737 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301738 {
1739 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1740 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301741 return -EINVAL;
1742 }
1743
1744 pAdapter->isLinkLayerStatsSet = 1;
1745
1746 return 0;
1747}
1748
1749const struct
1750nla_policy
1751qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1752{
1753 /* Unsigned 32bit value provided by the caller issuing the GET stats
1754 * command. When reporting
1755 * the stats results, the driver uses the same value to indicate
1756 * which GET request the results
1757 * correspond to.
1758 */
1759 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1760
1761 /* Unsigned 32bit value . bit mask to identify what statistics are
1762 requested for retrieval */
1763 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1764};
1765
1766static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1767 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05301768 const void *data,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301769 int data_len)
1770{
1771 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1772 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301773 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301774 struct net_device *dev = wdev->netdev;
1775 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1776 int status;
1777
1778 status = wlan_hdd_validate_context(pHddCtx);
1779 if (0 != status)
1780 {
1781 hddLog(VOS_TRACE_LEVEL_ERROR,
1782 FL("HDD context is not valid"));
1783 return -EINVAL ;
1784 }
1785
1786 if (NULL == pAdapter)
1787 {
1788 hddLog(VOS_TRACE_LEVEL_FATAL,
1789 "%s: HDD adapter is Null", __func__);
1790 return -ENODEV;
1791 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301792 /* check the LLStats Capability */
1793 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1794 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1795 {
1796 hddLog(VOS_TRACE_LEVEL_ERROR,
1797 FL("Link Layer Statistics not supported by Firmware"));
1798 return -EINVAL;
1799 }
1800
Sunil Duttc69bccb2014-05-26 21:30:20 +05301801
1802 if (!pAdapter->isLinkLayerStatsSet)
1803 {
1804 hddLog(VOS_TRACE_LEVEL_FATAL,
1805 "%s: isLinkLayerStatsSet : %d",
1806 __func__, pAdapter->isLinkLayerStatsSet);
1807 return -EINVAL;
1808 }
1809
1810 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1811 (struct nlattr *)data,
1812 data_len, qca_wlan_vendor_ll_get_policy))
1813 {
1814 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1815 return -EINVAL;
1816 }
1817
1818 if (!tb_vendor
1819 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1820 {
1821 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1822 return -EINVAL;
1823 }
1824
1825 if (!tb_vendor
1826 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1827 {
1828 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1829 return -EINVAL;
1830 }
1831
Sunil Duttc69bccb2014-05-26 21:30:20 +05301832
Dino Mycledf0a5d92014-07-04 09:41:55 +05301833 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301834 nla_get_u32( tb_vendor[
1835 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301836 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301837 nla_get_u32( tb_vendor[
1838 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1839
Dino Mycled3d50022014-07-07 12:58:25 +05301840 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1841 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301842
1843 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301844 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301845 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301846 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301847 hddLog(VOS_TRACE_LEVEL_INFO,
1848 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301849 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301850
1851 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301852 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301853 {
1854 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1855 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301856 return -EINVAL;
1857 }
1858 return 0;
1859}
1860
1861const struct
1862nla_policy
1863qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1864{
1865 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1866 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1867 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1868 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1869};
1870
1871static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1872 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05301873 const void *data,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301874 int data_len)
1875{
1876 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1877 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301878 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301879 struct net_device *dev = wdev->netdev;
1880 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1881 u32 statsClearReqMask;
1882 u8 stopReq;
1883 int status;
1884
1885 status = wlan_hdd_validate_context(pHddCtx);
1886 if (0 != status)
1887 {
1888 hddLog(VOS_TRACE_LEVEL_ERROR,
1889 FL("HDD context is not valid"));
1890 return -EINVAL;
1891 }
1892
1893 if (NULL == pAdapter)
1894 {
1895 hddLog(VOS_TRACE_LEVEL_FATAL,
1896 "%s: HDD adapter is Null", __func__);
1897 return -ENODEV;
1898 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301899 /* check the LLStats Capability */
1900 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1901 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1902 {
1903 hddLog(VOS_TRACE_LEVEL_ERROR,
1904 FL("Enable LLStats Capability"));
1905 return -EINVAL;
1906 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301907
1908 if (!pAdapter->isLinkLayerStatsSet)
1909 {
1910 hddLog(VOS_TRACE_LEVEL_FATAL,
1911 "%s: isLinkLayerStatsSet : %d",
1912 __func__, pAdapter->isLinkLayerStatsSet);
1913 return -EINVAL;
1914 }
1915
1916 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1917 (struct nlattr *)data,
1918 data_len, qca_wlan_vendor_ll_clr_policy))
1919 {
1920 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1921 return -EINVAL;
1922 }
1923
1924 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
1925
1926 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
1927 {
1928 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
1929 return -EINVAL;
1930
1931 }
1932
Sunil Duttc69bccb2014-05-26 21:30:20 +05301933
Dino Mycledf0a5d92014-07-04 09:41:55 +05301934 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301935 nla_get_u32(
1936 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
1937
Dino Mycledf0a5d92014-07-04 09:41:55 +05301938 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301939 nla_get_u8(
1940 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
1941
1942 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301943 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301944
Dino Mycled3d50022014-07-07 12:58:25 +05301945 vos_mem_copy(linkLayerStatsClearReq.macAddr,
1946 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301947
1948 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301949 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301950 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301951 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301952 hddLog(VOS_TRACE_LEVEL_INFO,
1953 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301954 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301955 hddLog(VOS_TRACE_LEVEL_INFO,
1956 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301957 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301958
1959 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301960 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301961 {
1962 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05301963 hdd_station_ctx_t *pHddStaCtx;
1964
1965 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1966 if (VOS_STATUS_SUCCESS !=
1967 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1968 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
1969 {
1970 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1971 "WLANTL_ClearInterfaceStats Failed", __func__);
1972 return -EINVAL;
1973 }
1974 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
1975 (statsClearReqMask & WIFI_STATS_IFACE)) {
1976 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
1977 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
1978 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
1979 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
1980 }
1981
Sunil Duttc69bccb2014-05-26 21:30:20 +05301982 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
1983 2 * sizeof(u32) +
1984 NLMSG_HDRLEN);
1985
1986 if (temp_skbuff != NULL)
1987 {
1988
1989 if (nla_put_u32(temp_skbuff,
1990 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
1991 statsClearReqMask) ||
1992 nla_put_u32(temp_skbuff,
1993 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
1994 stopReq))
1995 {
1996 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
1997 kfree_skb(temp_skbuff);
1998 return -EINVAL;
1999 }
2000 /* If the ask is to stop the stats collection as part of clear
2001 * (stopReq = 1) , ensure that no further requests of get
2002 * go to the firmware by having isLinkLayerStatsSet set to 0.
2003 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302004 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302005 * case the firmware is just asked to clear the statistics.
2006 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302007 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302008 pAdapter->isLinkLayerStatsSet = 0;
2009 return cfg80211_vendor_cmd_reply(temp_skbuff);
2010 }
2011 return -ENOMEM;
2012 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302013 return -EINVAL;
2014}
2015#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2016
Dino Mycle6fb96c12014-06-10 11:52:40 +05302017#ifdef WLAN_FEATURE_EXTSCAN
2018static const struct nla_policy
2019wlan_hdd_extscan_config_policy
2020 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2021{
2022 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2023 { .type = NLA_U32 },
2024 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2025 { .type = NLA_U32 },
2026 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2027 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2028 { .type = NLA_U32 },
2029 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2030 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2031
2032 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2033 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2034 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2035 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2036 { .type = NLA_U8 },
2037 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2038 { .type = NLA_U32 },
2039 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2040 { .type = NLA_U32 },
2041 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2042 { .type = NLA_U32 },
2043 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
2044 { .type = NLA_U8 },
2045 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2046 { .type = NLA_U8 },
2047 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2048 { .type = NLA_U8 },
2049
2050 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2051 { .type = NLA_U32 },
2052 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2053 { .type = NLA_UNSPEC },
2054 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2055 { .type = NLA_S32 },
2056 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2057 { .type = NLA_S32 },
2058 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2059 { .type = NLA_U32 },
2060 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2061 { .type = NLA_U32 },
2062 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2063 { .type = NLA_U32 },
2064 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2065 = { .type = NLA_U32 },
2066 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2067 { .type = NLA_U32 },
2068 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2069 NLA_U32 },
2070};
2071
2072static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
2073{
2074 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2075 struct sk_buff *skb = NULL;
2076 tpSirEXTScanCapabilitiesEvent pData =
2077 (tpSirEXTScanCapabilitiesEvent) pMsg;
2078
2079 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2080 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2081 "or pData(%p) is null"), pData);
2082 return;
2083 }
2084
2085 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2086 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2087 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
2088 GFP_KERNEL);
2089
2090 if (!skb) {
2091 hddLog(VOS_TRACE_LEVEL_ERROR,
2092 FL("cfg80211_vendor_event_alloc failed"));
2093 return;
2094 }
2095
2096 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2097 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
2098 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
2099 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
2100 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
2101 pData->maxRssiSampleSize);
2102 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
2103 pData->maxScanReportingThreshold);
2104 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
2105 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
2106 pData->maxSignificantWifiChangeAPs);
2107 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
2108 pData->maxBsidHistoryEntries);
2109
2110 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2111 pData->requestId) ||
2112 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
2113 nla_put_u32(skb,
2114 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
2115 pData->scanCacheSize) ||
2116 nla_put_u32(skb,
2117 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
2118 pData->scanBuckets) ||
2119 nla_put_u32(skb,
2120 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
2121 pData->maxApPerScan) ||
2122 nla_put_u32(skb,
2123 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
2124 pData->maxRssiSampleSize) ||
2125 nla_put_u32(skb,
2126 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
2127 pData->maxScanReportingThreshold) ||
2128 nla_put_u32(skb,
2129 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
2130 pData->maxHotlistAPs) ||
2131 nla_put_u32(skb,
2132 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
2133 pData->maxSignificantWifiChangeAPs) ||
2134 nla_put_u32(skb,
2135 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2136 pData->maxBsidHistoryEntries)) {
2137 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2138 goto nla_put_failure;
2139 }
2140
2141 cfg80211_vendor_event(skb, GFP_KERNEL);
2142 return;
2143
2144nla_put_failure:
2145 kfree_skb(skb);
2146 return;
2147}
2148
2149
2150static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2151{
2152 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2153 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2154 struct sk_buff *skb = NULL;
2155 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2156
2157
2158 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2159 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2160 "or pData(%p) is null"), pData);
2161 return;
2162 }
2163
2164 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2165 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2166 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2167 GFP_KERNEL);
2168
2169 if (!skb) {
2170 hddLog(VOS_TRACE_LEVEL_ERROR,
2171 FL("cfg80211_vendor_event_alloc failed"));
2172 return;
2173 }
2174 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2175 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2176 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2177
2178 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2179 pData->requestId) ||
2180 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2181 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2182 goto nla_put_failure;
2183 }
2184
2185 /*
2186 * Store the Request ID for comparing with the requestID obtained
2187 * in other requests.HDD shall return a failure is the extscan_stop
2188 * request is issued with a different requestId as that of the
2189 * extscan_start request. Also, This requestId shall be used while
2190 * indicating the full scan results to the upper layers.
2191 * The requestId is stored with the assumption that the firmware
2192 * shall return the ext scan start request's requestId in ext scan
2193 * start response.
2194 */
2195 if (pData->status == 0)
2196 pMac->sme.extScanStartReqId = pData->requestId;
2197
2198
2199 cfg80211_vendor_event(skb, GFP_KERNEL);
2200 return;
2201
2202nla_put_failure:
2203 kfree_skb(skb);
2204 return;
2205}
2206
2207
2208static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2209{
2210 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2211 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2212 struct sk_buff *skb = NULL;
2213
2214 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2215 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2216 "or pData(%p) is null"), pData);
2217 return;
2218 }
2219
2220 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2221 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2222 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2223 GFP_KERNEL);
2224
2225 if (!skb) {
2226 hddLog(VOS_TRACE_LEVEL_ERROR,
2227 FL("cfg80211_vendor_event_alloc failed"));
2228 return;
2229 }
2230 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2231 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2232
2233 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2234 pData->requestId) ||
2235 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2237 goto nla_put_failure;
2238 }
2239
2240 cfg80211_vendor_event(skb, GFP_KERNEL);
2241 return;
2242
2243nla_put_failure:
2244 kfree_skb(skb);
2245 return;
2246}
2247
2248
2249static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2250 void *pMsg)
2251{
2252 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2253 struct sk_buff *skb = NULL;
2254 tpSirEXTScanSetBssidHotListRspParams pData =
2255 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2256
2257 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2258 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2259 "or pData(%p) is null"), pData);
2260 return;
2261 }
2262 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2263 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2264 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2265 GFP_KERNEL);
2266
2267 if (!skb) {
2268 hddLog(VOS_TRACE_LEVEL_ERROR,
2269 FL("cfg80211_vendor_event_alloc failed"));
2270 return;
2271 }
2272 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2273 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2274 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2275
2276 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2277 pData->requestId) ||
2278 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2279 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2280 goto nla_put_failure;
2281 }
2282
2283 cfg80211_vendor_event(skb, GFP_KERNEL);
2284 return;
2285
2286nla_put_failure:
2287 kfree_skb(skb);
2288 return;
2289}
2290
2291static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2292 void *pMsg)
2293{
2294 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2295 struct sk_buff *skb = NULL;
2296 tpSirEXTScanResetBssidHotlistRspParams pData =
2297 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2298
2299 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2300 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2301 "or pData(%p) is null"), pData);
2302 return;
2303 }
2304
2305 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2306 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2307 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2308 GFP_KERNEL);
2309
2310 if (!skb) {
2311 hddLog(VOS_TRACE_LEVEL_ERROR,
2312 FL("cfg80211_vendor_event_alloc failed"));
2313 return;
2314 }
2315 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2316 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2317
2318 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2319 pData->requestId) ||
2320 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2321 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2322 goto nla_put_failure;
2323 }
2324
2325 cfg80211_vendor_event(skb, GFP_KERNEL);
2326 return;
2327
2328nla_put_failure:
2329 kfree_skb(skb);
2330 return;
2331}
2332
2333
2334static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2335 void *pMsg)
2336{
2337 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2338 struct sk_buff *skb = NULL;
2339 tpSirEXTScanSetSignificantChangeRspParams pData =
2340 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2341
2342 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2343 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2344 "or pData(%p) is null"), pData);
2345 return;
2346 }
2347
2348 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2349 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2350 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2351 GFP_KERNEL);
2352
2353 if (!skb) {
2354 hddLog(VOS_TRACE_LEVEL_ERROR,
2355 FL("cfg80211_vendor_event_alloc failed"));
2356 return;
2357 }
2358 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2359 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2360 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2361
2362 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2363 pData->requestId) ||
2364 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2365 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2366 goto nla_put_failure;
2367 }
2368
2369 cfg80211_vendor_event(skb, GFP_KERNEL);
2370 return;
2371
2372nla_put_failure:
2373 kfree_skb(skb);
2374 return;
2375}
2376
2377
2378static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2379 void *pMsg)
2380{
2381 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2382 struct sk_buff *skb = NULL;
2383 tpSirEXTScanResetSignificantChangeRspParams pData =
2384 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2385
2386 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2387 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2388 "or pData(%p) is null"), pData);
2389 return;
2390 }
2391
2392 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2393 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2394 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2395 GFP_KERNEL);
2396
2397 if (!skb) {
2398 hddLog(VOS_TRACE_LEVEL_ERROR,
2399 FL("cfg80211_vendor_event_alloc failed"));
2400 return;
2401 }
2402 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2403 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2404 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2405
2406 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2407 pData->requestId) ||
2408 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2409 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2410 goto nla_put_failure;
2411 }
2412
2413 cfg80211_vendor_event(skb, GFP_KERNEL);
2414 return;
2415
2416nla_put_failure:
2417 kfree_skb(skb);
2418 return;
2419}
2420
2421static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2422 void *pMsg)
2423{
2424 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2425 struct sk_buff *skb = NULL;
2426 tANI_U32 i = 0, j, resultsPerEvent;
2427 tANI_S32 totalResults;
2428 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2429 tpSirWifiScanResult pSirWifiScanResult;
2430
2431 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2432 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2433 "or pData(%p) is null"), pData);
2434 return;
2435 }
2436 totalResults = pData->numOfAps;
2437 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2438 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2439 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2440
2441 do{
2442 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2443 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2444 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2445
2446 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2447 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2448 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2449 GFP_KERNEL);
2450
2451 if (!skb) {
2452 hddLog(VOS_TRACE_LEVEL_ERROR,
2453 FL("cfg80211_vendor_event_alloc failed"));
2454 return;
2455 }
2456
2457 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2458
2459 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2460 pData->requestId) ||
2461 nla_put_u32(skb,
2462 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2463 resultsPerEvent)) {
2464 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2465 goto fail;
2466 }
2467 if (nla_put_u8(skb,
2468 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2469 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2470 {
2471 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2472 goto fail;
2473 }
2474
2475 if (resultsPerEvent) {
2476 struct nlattr *aps;
2477
2478 aps = nla_nest_start(skb,
2479 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2480 if (!aps)
2481 {
2482 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2483 goto fail;
2484 }
2485
2486 for (j = 0; j < resultsPerEvent; j++, i++) {
2487 struct nlattr *ap;
2488 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2489 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2490
2491 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2492 "Ssid (%s)"
2493 "Bssid: %pM "
2494 "Channel (%u)"
2495 "Rssi (%d)"
2496 "RTT (%u)"
2497 "RTT_SD (%u)",
2498 i,
2499 pSirWifiScanResult->ts,
2500 pSirWifiScanResult->ssid,
2501 pSirWifiScanResult->bssid,
2502 pSirWifiScanResult->channel,
2503 pSirWifiScanResult->rssi,
2504 pSirWifiScanResult->rtt,
2505 pSirWifiScanResult->rtt_sd);
2506
2507 ap = nla_nest_start(skb, j + 1);
2508 if (!ap)
2509 {
2510 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2511 goto fail;
2512 }
2513
2514 if (nla_put_u64(skb,
2515 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2516 pSirWifiScanResult->ts) )
2517 {
2518 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2519 goto fail;
2520 }
2521 if (nla_put(skb,
2522 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2523 sizeof(pSirWifiScanResult->ssid),
2524 pSirWifiScanResult->ssid) )
2525 {
2526 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2527 goto fail;
2528 }
2529 if (nla_put(skb,
2530 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2531 sizeof(pSirWifiScanResult->bssid),
2532 pSirWifiScanResult->bssid) )
2533 {
2534 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2535 goto fail;
2536 }
2537 if (nla_put_u32(skb,
2538 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2539 pSirWifiScanResult->channel) )
2540 {
2541 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2542 goto fail;
2543 }
Dasari Srinivas90747d72014-10-08 12:16:15 +05302544 if (nla_put_s32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302545 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2546 pSirWifiScanResult->rssi) )
2547 {
2548 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2549 goto fail;
2550 }
2551 if (nla_put_u32(skb,
2552 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2553 pSirWifiScanResult->rtt) )
2554 {
2555 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2556 goto fail;
2557 }
2558 if (nla_put_u32(skb,
2559 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2560 pSirWifiScanResult->rtt_sd))
2561 {
2562 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2563 goto fail;
2564 }
2565
2566 nla_nest_end(skb, ap);
2567 }
2568 nla_nest_end(skb, aps);
2569
2570 }
2571 cfg80211_vendor_event(skb, GFP_KERNEL);
2572 } while (totalResults > 0);
2573
2574 return;
2575fail:
2576 kfree_skb(skb);
2577 return;
2578}
2579
2580static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2581 void *pMsg)
2582{
2583 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2584 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2585 struct sk_buff *skb = NULL;
2586 tANI_U32 i;
2587
2588 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2589 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2590 "or pData(%p) is null"), pData);
2591 return;
2592 }
2593
2594 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2595 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2596 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2597 GFP_KERNEL);
2598
2599 if (!skb) {
2600 hddLog(VOS_TRACE_LEVEL_ERROR,
2601 FL("cfg80211_vendor_event_alloc failed"));
2602 return;
2603 }
2604 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2605 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2606 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2607 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2608
2609 for (i = 0; i < pData->numOfAps; i++) {
2610 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2611 "Ssid (%s) "
2612 "Bssid (" MAC_ADDRESS_STR ") "
2613 "Channel (%u) "
2614 "Rssi (%d) "
2615 "RTT (%u) "
2616 "RTT_SD (%u) ",
2617 i,
2618 pData->ap[i].ts,
2619 pData->ap[i].ssid,
2620 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2621 pData->ap[i].channel,
2622 pData->ap[i].rssi,
2623 pData->ap[i].rtt,
2624 pData->ap[i].rtt_sd);
2625 }
2626
2627 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2628 pData->requestId) ||
2629 nla_put_u32(skb,
2630 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2631 pData->numOfAps)) {
2632 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2633 goto fail;
2634 }
2635 if (pData->numOfAps) {
2636 struct nlattr *aps;
2637
2638 aps = nla_nest_start(skb,
2639 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2640 if (!aps)
2641 goto fail;
2642
2643 for (i = 0; i < pData->numOfAps; i++) {
2644 struct nlattr *ap;
2645
2646 ap = nla_nest_start(skb, i + 1);
2647 if (!ap)
2648 goto fail;
2649
2650 if (nla_put_u64(skb,
2651 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2652 pData->ap[i].ts) ||
2653 nla_put(skb,
2654 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2655 sizeof(pData->ap[i].ssid),
2656 pData->ap[i].ssid) ||
2657 nla_put(skb,
2658 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2659 sizeof(pData->ap[i].bssid),
2660 pData->ap[i].bssid) ||
2661 nla_put_u32(skb,
2662 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2663 pData->ap[i].channel) ||
2664 nla_put_s32(skb,
2665 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2666 pData->ap[i].rssi) ||
2667 nla_put_u32(skb,
2668 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2669 pData->ap[i].rtt) ||
2670 nla_put_u32(skb,
2671 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2672 pData->ap[i].rtt_sd))
2673 goto fail;
2674
2675 nla_nest_end(skb, ap);
2676 }
2677 nla_nest_end(skb, aps);
2678
2679 if (nla_put_u8(skb,
2680 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2681 pData->moreData))
2682 goto fail;
2683 }
2684
2685 cfg80211_vendor_event(skb, GFP_KERNEL);
2686 return;
2687
2688fail:
2689 kfree_skb(skb);
2690 return;
2691
2692}
2693static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2694 void *pMsg)
2695{
2696 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2697 struct sk_buff *skb = NULL;
2698 tANI_U32 i, j;
2699 tpSirWifiSignificantChangeEvent pData =
2700 (tpSirWifiSignificantChangeEvent) pMsg;
2701
2702 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2703 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2704 "or pData(%p) is null"), pData);
2705 return;
2706 }
2707 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2708 EXTSCAN_EVENT_BUF_SIZE,
2709 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2710 GFP_KERNEL);
2711
2712 if (!skb) {
2713 hddLog(VOS_TRACE_LEVEL_ERROR,
2714 FL("cfg80211_vendor_event_alloc failed"));
2715 return;
2716 }
2717 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2718 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2719 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2720 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2721 pData->numSigRssiBss);
2722 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2723
2724 for (i = 0; i < pData->numSigRssiBss; i++) {
2725 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2726 " num RSSI %u ",
2727 i, pData->sigRssiResult[i].bssid,
2728 pData->sigRssiResult[i].channel,
2729 pData->sigRssiResult[i].numRssi);
2730
2731 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2732
2733 hddLog(VOS_TRACE_LEVEL_INFO,
2734 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05302735 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302736
2737 }
2738 }
2739
2740
2741 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2742 pData->requestId) ||
2743 nla_put_u32(skb,
2744 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2745 pData->numSigRssiBss)) {
2746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2747 goto fail;
2748 }
2749
2750 if (pData->numSigRssiBss) {
2751 struct nlattr *aps;
2752 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2753 if (!aps)
2754 goto fail;
2755 for (i = 0; i < pData->numSigRssiBss; i++) {
2756 struct nlattr *ap;
2757
2758 ap = nla_nest_start(skb, i);
2759 if (!ap)
2760 goto fail;
2761 if (nla_put(skb,
2762 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2763 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2764 nla_put_u32(skb,
2765 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2766 pData->sigRssiResult[i].channel) ||
2767 nla_put_u32(skb,
2768 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2769 pData->sigRssiResult[i].numRssi) ||
2770 nla_put(skb,
2771 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2772 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2773 pData->sigRssiResult[i].rssi))
2774 goto fail;
2775 nla_nest_end(skb, ap);
2776 }
2777 nla_nest_end(skb, aps);
2778 if (nla_put_u8(skb,
2779 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2780 pData->moreData))
2781 goto fail;
2782 }
2783 cfg80211_vendor_event(skb, GFP_KERNEL);
2784 return;
2785fail:
2786 kfree_skb(skb);
2787 return;
2788}
2789
2790static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2791 void *pMsg)
2792{
2793 struct sk_buff *skb;
2794 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2795 tpSirWifiFullScanResultEvent pData =
2796 (tpSirWifiFullScanResultEvent) (pMsg);
2797
2798 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2799 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2800 "or pData(%p) is null"), pData);
2801 return;
2802 }
2803
2804 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2805 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2806 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2807 GFP_KERNEL);
2808
2809 if (!skb) {
2810 hddLog(VOS_TRACE_LEVEL_ERROR,
2811 FL("cfg80211_vendor_event_alloc failed"));
2812 return;
2813 }
2814
2815 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2816 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2817 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2818 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2819 "Ssid (%s)"
2820 "Bssid (" MAC_ADDRESS_STR ")"
2821 "Channel (%u)"
2822 "Rssi (%d)"
2823 "RTT (%u)"
2824 "RTT_SD (%u)"),
2825 pData->ap.ts,
2826 pData->ap.ssid,
2827 MAC_ADDR_ARRAY(pData->ap.bssid),
2828 pData->ap.channel,
2829 pData->ap.rssi,
2830 pData->ap.rtt,
2831 pData->ap.rtt_sd);
2832 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2833 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2834 pData->requestId) ||
2835 nla_put_u64(skb,
2836 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2837 pData->ap.ts) ||
2838 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2839 sizeof(pData->ap.ssid),
2840 pData->ap.ssid) ||
2841 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2842 WNI_CFG_BSSID_LEN,
2843 pData->ap.bssid) ||
2844 nla_put_u32(skb,
2845 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2846 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05302847 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302848 pData->ap.rssi) ||
2849 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2850 pData->ap.rtt) ||
2851 nla_put_u32(skb,
2852 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2853 pData->ap.rtt_sd) ||
2854 nla_put_u16(skb,
2855 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2856 pData->ap.beaconPeriod) ||
2857 nla_put_u16(skb,
2858 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2859 pData->ap.capability) ||
2860 nla_put_u32(skb,
2861 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2862 pData->ieLength))
2863 {
2864 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2865 goto nla_put_failure;
2866 }
2867 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2868 pData->ieLength,
2869 pData->ie))
2870 {
2871 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2872 goto nla_put_failure;
2873 }
2874
2875 cfg80211_vendor_event(skb, GFP_KERNEL);
2876 return;
2877
2878nla_put_failure:
2879 kfree_skb(skb);
2880 return;
2881}
2882
2883static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
2884 void *pMsg)
2885{
2886 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2887 struct sk_buff *skb = NULL;
2888 tpSirEXTScanResultsAvailableIndParams pData =
2889 (tpSirEXTScanResultsAvailableIndParams) pMsg;
2890
2891 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2892 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2893 "or pData(%p) is null"), pData);
2894 return;
2895 }
2896
2897 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2898 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2899 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
2900 GFP_KERNEL);
2901
2902 if (!skb) {
2903 hddLog(VOS_TRACE_LEVEL_ERROR,
2904 FL("cfg80211_vendor_event_alloc failed"));
2905 return;
2906 }
2907
2908 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2909 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2910 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
2911 pData->numResultsAvailable);
2912 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2913 pData->requestId) ||
2914 nla_put_u32(skb,
2915 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2916 pData->numResultsAvailable)) {
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_progress_event(void *ctx, void *pMsg)
2930{
2931 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2932 struct sk_buff *skb = NULL;
2933 tpSirEXTScanProgressIndParams pData =
2934 (tpSirEXTScanProgressIndParams) pMsg;
2935
2936 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2937 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2938 "or pData(%p) is null"), pData);
2939 return;
2940 }
2941
2942 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2943 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2944 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
2945 GFP_KERNEL);
2946
2947 if (!skb) {
2948 hddLog(VOS_TRACE_LEVEL_ERROR,
2949 FL("cfg80211_vendor_event_alloc failed"));
2950 return;
2951 }
2952 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2953 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
2954 pData->extScanEventType);
2955 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
2956 pData->status);
2957
2958 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
2959 pData->extScanEventType) ||
2960 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05302961 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2962 pData->requestId) ||
2963 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302964 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
2965 pData->status)) {
2966 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2967 goto nla_put_failure;
2968 }
2969
2970 cfg80211_vendor_event(skb, GFP_KERNEL);
2971 return;
2972
2973nla_put_failure:
2974 kfree_skb(skb);
2975 return;
2976}
2977
2978void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
2979 void *pMsg)
2980{
2981 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2982
2983 if (wlan_hdd_validate_context(pHddCtx)) {
Dasari Srinivasb46ed1d2014-10-08 13:03:08 +05302984 hddLog(VOS_TRACE_LEVEL_INFO, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302985 return;
2986 }
2987
2988 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
2989
2990
2991 switch(evType) {
2992 case SIR_HAL_EXTSCAN_START_RSP:
2993 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
2994 break;
2995
2996 case SIR_HAL_EXTSCAN_STOP_RSP:
2997 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
2998 break;
2999 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3000 /* There is no need to send this response to upper layer
3001 Just log the message */
3002 hddLog(VOS_TRACE_LEVEL_INFO,
3003 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3004 break;
3005 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3006 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3007 break;
3008
3009 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3010 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3011 break;
3012
3013 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
3014 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
3015 break;
3016
3017 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
3018 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
3019 break;
3020 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
3021 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
3022 break;
3023 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3024 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3025 break;
3026 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3027 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3028 break;
3029 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3030 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3031 break;
3032 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3033 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3034 break;
3035 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
3036 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
3037 break;
3038 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3039 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3040 break;
3041 default:
3042 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3043 break;
3044 }
3045}
3046
3047static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3048 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303049 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303050{
Dino Myclee8843b32014-07-04 14:21:45 +05303051 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303052 struct net_device *dev = wdev->netdev;
3053 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3054 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3055 struct nlattr
3056 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3057 eHalStatus status;
3058
3059 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3060 status = wlan_hdd_validate_context(pHddCtx);
3061 if (0 != status)
3062 {
3063 hddLog(VOS_TRACE_LEVEL_ERROR,
3064 FL("HDD context is not valid"));
3065 return -EINVAL;
3066 }
Dino Myclee8843b32014-07-04 14:21:45 +05303067 /* check the EXTScan Capability */
3068 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3069 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3070 {
3071 hddLog(VOS_TRACE_LEVEL_ERROR,
3072 FL("EXTScan not enabled/supported by Firmware"));
3073 return -EINVAL;
3074 }
3075
Dino Mycle6fb96c12014-06-10 11:52:40 +05303076 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3077 data, dataLen,
3078 wlan_hdd_extscan_config_policy)) {
3079 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3080 return -EINVAL;
3081 }
3082
3083 /* Parse and fetch request Id */
3084 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3086 return -EINVAL;
3087 }
3088
Dino Mycle6fb96c12014-06-10 11:52:40 +05303089
Dino Myclee8843b32014-07-04 14:21:45 +05303090 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303091 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303092 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303093
Dino Myclee8843b32014-07-04 14:21:45 +05303094 reqMsg.sessionId = pAdapter->sessionId;
3095 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303096
Dino Myclee8843b32014-07-04 14:21:45 +05303097 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303098 if (!HAL_STATUS_SUCCESS(status)) {
3099 hddLog(VOS_TRACE_LEVEL_ERROR,
3100 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303101 return -EINVAL;
3102 }
3103
3104 return 0;
3105}
3106
3107
3108static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3109 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303110 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303111{
Dino Myclee8843b32014-07-04 14:21:45 +05303112 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303113 struct net_device *dev = wdev->netdev;
3114 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3115 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3116 struct nlattr
3117 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3118 eHalStatus status;
3119
3120 status = wlan_hdd_validate_context(pHddCtx);
3121 if (0 != status)
3122 {
3123 hddLog(VOS_TRACE_LEVEL_ERROR,
3124 FL("HDD context is not valid"));
3125 return -EINVAL;
3126 }
Dino Myclee8843b32014-07-04 14:21:45 +05303127 /* check the EXTScan Capability */
3128 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3129 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3130 {
3131 hddLog(VOS_TRACE_LEVEL_ERROR,
3132 FL("EXTScan not enabled/supported by Firmware"));
3133 return -EINVAL;
3134 }
3135
Dino Mycle6fb96c12014-06-10 11:52:40 +05303136 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3137 data, dataLen,
3138 wlan_hdd_extscan_config_policy)) {
3139 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3140 return -EINVAL;
3141 }
3142 /* Parse and fetch request Id */
3143 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3144 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3145 return -EINVAL;
3146 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303147
Dino Myclee8843b32014-07-04 14:21:45 +05303148 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303149 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3150
Dino Myclee8843b32014-07-04 14:21:45 +05303151 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303152
Dino Myclee8843b32014-07-04 14:21:45 +05303153 reqMsg.sessionId = pAdapter->sessionId;
3154 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303155
3156 /* Parse and fetch flush parameter */
3157 if (!tb
3158 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3159 {
3160 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3161 goto failed;
3162 }
Dino Myclee8843b32014-07-04 14:21:45 +05303163 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303164 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3165
Dino Myclee8843b32014-07-04 14:21:45 +05303166 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303167
Dino Myclee8843b32014-07-04 14:21:45 +05303168 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303169 if (!HAL_STATUS_SUCCESS(status)) {
3170 hddLog(VOS_TRACE_LEVEL_ERROR,
3171 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303172 return -EINVAL;
3173 }
3174 return 0;
3175
3176failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303177 return -EINVAL;
3178}
3179
3180static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3181 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303182 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303183{
3184 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3185 struct net_device *dev = wdev->netdev;
3186 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3187 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3188 struct nlattr
3189 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3190 struct nlattr
3191 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3192 struct nlattr *apTh;
3193 eHalStatus status;
3194 tANI_U8 i = 0;
3195 int rem;
3196
3197 status = wlan_hdd_validate_context(pHddCtx);
3198 if (0 != status)
3199 {
3200 hddLog(VOS_TRACE_LEVEL_ERROR,
3201 FL("HDD context is not valid"));
3202 return -EINVAL;
3203 }
Dino Myclee8843b32014-07-04 14:21:45 +05303204 /* check the EXTScan Capability */
3205 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3206 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3207 {
3208 hddLog(VOS_TRACE_LEVEL_ERROR,
3209 FL("EXTScan not enabled/supported by Firmware"));
3210 return -EINVAL;
3211 }
3212
Dino Mycle6fb96c12014-06-10 11:52:40 +05303213 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3214 data, dataLen,
3215 wlan_hdd_extscan_config_policy)) {
3216 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3217 return -EINVAL;
3218 }
3219
3220 /* Parse and fetch request Id */
3221 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3222 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3223 return -EINVAL;
3224 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303225 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3226 vos_mem_malloc(sizeof(*pReqMsg));
3227 if (!pReqMsg) {
3228 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3229 return -ENOMEM;
3230 }
3231
Dino Myclee8843b32014-07-04 14:21:45 +05303232
Dino Mycle6fb96c12014-06-10 11:52:40 +05303233 pReqMsg->requestId = nla_get_u32(
3234 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3235 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3236
3237 /* Parse and fetch number of APs */
3238 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3240 goto fail;
3241 }
3242
3243 pReqMsg->sessionId = pAdapter->sessionId;
3244 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3245
3246 pReqMsg->numAp = nla_get_u32(
3247 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3248 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3249
3250 nla_for_each_nested(apTh,
3251 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3252 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3253 nla_data(apTh), nla_len(apTh),
3254 NULL)) {
3255 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3256 goto fail;
3257 }
3258
3259 /* Parse and fetch MAC address */
3260 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3262 goto fail;
3263 }
3264 memcpy(pReqMsg->ap[i].bssid, nla_data(
3265 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3266 sizeof(tSirMacAddr));
3267 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3268
3269 /* Parse and fetch low RSSI */
3270 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3272 goto fail;
3273 }
3274 pReqMsg->ap[i].low = nla_get_s32(
3275 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3276 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3277
3278 /* Parse and fetch high RSSI */
3279 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3280 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3281 goto fail;
3282 }
3283 pReqMsg->ap[i].high = nla_get_s32(
3284 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3285 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3286 pReqMsg->ap[i].high);
3287
3288 /* Parse and fetch channel */
3289 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3290 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3291 goto fail;
3292 }
3293 pReqMsg->ap[i].channel = nla_get_u32(
3294 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3295 hddLog(VOS_TRACE_LEVEL_INFO,
3296 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3297 i++;
3298 }
3299 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3300 if (!HAL_STATUS_SUCCESS(status)) {
3301 hddLog(VOS_TRACE_LEVEL_ERROR,
3302 FL("sme_SetBssHotlist failed(err=%d)"), status);
3303 vos_mem_free(pReqMsg);
3304 return -EINVAL;
3305 }
3306
Dino Myclee8843b32014-07-04 14:21:45 +05303307 vos_mem_free(pReqMsg);
3308
Dino Mycle6fb96c12014-06-10 11:52:40 +05303309 return 0;
3310
3311fail:
3312 vos_mem_free(pReqMsg);
3313 return -EINVAL;
3314}
3315
3316static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3317 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303318 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303319{
3320 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3321 struct net_device *dev = wdev->netdev;
3322 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3323 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3324 struct nlattr
3325 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3326 struct nlattr
3327 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3328 struct nlattr *apTh;
3329 eHalStatus status;
3330 int i = 0;
3331 int rem;
3332
3333 status = wlan_hdd_validate_context(pHddCtx);
3334 if (0 != status)
3335 {
3336 hddLog(VOS_TRACE_LEVEL_ERROR,
3337 FL("HDD context is not valid"));
3338 return -EINVAL;
3339 }
Dino Myclee8843b32014-07-04 14:21:45 +05303340 /* check the EXTScan Capability */
3341 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3342 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3343 {
3344 hddLog(VOS_TRACE_LEVEL_ERROR,
3345 FL("EXTScan not enabled/supported by Firmware"));
3346 return -EINVAL;
3347 }
3348
Dino Mycle6fb96c12014-06-10 11:52:40 +05303349 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3350 data, dataLen,
3351 wlan_hdd_extscan_config_policy)) {
3352 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3353 return -EINVAL;
3354 }
3355
3356 /* Parse and fetch request Id */
3357 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3358 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3359 return -EINVAL;
3360 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303361 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303362 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303363 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303364 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3365 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303366 }
3367
Dino Myclee8843b32014-07-04 14:21:45 +05303368
3369
Dino Mycle6fb96c12014-06-10 11:52:40 +05303370 pReqMsg->requestId = nla_get_u32(
3371 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3372 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3373
3374 /* Parse and fetch RSSI sample size */
3375 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3376 {
3377 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3378 goto fail;
3379 }
3380 pReqMsg->rssiSampleSize = nla_get_u32(
3381 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3382 hddLog(VOS_TRACE_LEVEL_INFO,
3383 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3384
3385 /* Parse and fetch lost AP sample size */
3386 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3387 {
3388 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3389 goto fail;
3390 }
3391 pReqMsg->lostApSampleSize = nla_get_u32(
3392 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3393 hddLog(VOS_TRACE_LEVEL_INFO,
3394 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3395 /* Parse and fetch minimum Breaching */
3396 if (!tb
3397 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3398 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3399 goto fail;
3400 }
3401 pReqMsg->minBreaching = nla_get_u32(
3402 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3403 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3404
3405 /* Parse and fetch number of APs */
3406 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3407 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3408 goto fail;
3409 }
3410 pReqMsg->numAp = nla_get_u32(
3411 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3412 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3413
3414 pReqMsg->sessionId = pAdapter->sessionId;
3415 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3416
3417 nla_for_each_nested(apTh,
3418 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3419 if(nla_parse(tb2,
3420 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3421 nla_data(apTh), nla_len(apTh),
3422 NULL)) {
3423 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3424 goto fail;
3425 }
3426
3427 /* Parse and fetch MAC address */
3428 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3429 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3430 goto fail;
3431 }
3432 memcpy(pReqMsg->ap[i].bssid, nla_data(
3433 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3434 sizeof(tSirMacAddr));
3435
3436 /* Parse and fetch low RSSI */
3437 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3438 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3439 goto fail;
3440 }
3441 pReqMsg->ap[i].low = nla_get_s32(
3442 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3443 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3444
3445 /* Parse and fetch high RSSI */
3446 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3447 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3448 goto fail;
3449 }
3450 pReqMsg->ap[i].high = nla_get_s32(
3451 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3452 hddLog(VOS_TRACE_LEVEL_INFO,
3453 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3454
3455 /* Parse and fetch channel */
3456 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3458 goto fail;
3459 }
3460 pReqMsg->ap[i].channel = nla_get_u32(
3461 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3462 hddLog(VOS_TRACE_LEVEL_INFO,
3463 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3464 i++;
3465 }
3466
3467 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3468 if (!HAL_STATUS_SUCCESS(status)) {
3469 hddLog(VOS_TRACE_LEVEL_ERROR,
3470 FL("sme_SetSignificantChange failed(err=%d)"), status);
3471 vos_mem_free(pReqMsg);
3472 return -EINVAL;
3473 }
Dino Myclee8843b32014-07-04 14:21:45 +05303474 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303475 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3476 return 0;
3477
3478fail:
3479 vos_mem_free(pReqMsg);
3480 return -EINVAL;
3481}
3482
3483static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3484 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303485 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303486{
3487 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3488 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3489 tANI_U8 numChannels = 0;
3490 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3491 tANI_U32 requestId;
3492 tWifiBand wifiBand;
3493 eHalStatus status;
3494 struct sk_buff *replySkb;
3495 tANI_U8 i;
3496
3497 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3498 status = wlan_hdd_validate_context(pHddCtx);
3499 if (0 != status)
3500 {
3501 hddLog(VOS_TRACE_LEVEL_ERROR,
3502 FL("HDD context is not valid"));
3503 return -EINVAL;
3504 }
Dino Myclee8843b32014-07-04 14:21:45 +05303505 /* check the EXTScan Capability */
3506 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3507 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3508 {
3509 hddLog(VOS_TRACE_LEVEL_ERROR,
3510 FL("EXTScan not enabled/supported by Firmware"));
3511 return -EINVAL;
3512 }
3513
Dino Mycle6fb96c12014-06-10 11:52:40 +05303514 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3515 data, dataLen,
3516 wlan_hdd_extscan_config_policy)) {
3517 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3518 return -EINVAL;
3519 }
3520
3521 /* Parse and fetch request Id */
3522 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3523 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3524 return -EINVAL;
3525 }
3526 requestId = nla_get_u32(
3527 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3528 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3529
3530 /* Parse and fetch wifi band */
3531 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3532 {
3533 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3534 return -EINVAL;
3535 }
3536 wifiBand = nla_get_u32(
3537 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3538 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3539
3540 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3541 wifiBand, ChannelList,
3542 &numChannels);
3543 if (eHAL_STATUS_SUCCESS != status) {
3544 hddLog(VOS_TRACE_LEVEL_ERROR,
3545 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3546 return -EINVAL;
3547 }
3548 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3549 for (i = 0; i < numChannels; i++)
3550 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3551
3552 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3553 sizeof(u32) * numChannels +
3554 NLMSG_HDRLEN);
3555
3556 if (!replySkb) {
3557 hddLog(VOS_TRACE_LEVEL_ERROR,
3558 FL("valid channels: buffer alloc fail"));
3559 return -EINVAL;
3560 }
3561 if (nla_put_u32(replySkb,
3562 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3563 numChannels) ||
3564 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3565 sizeof(u32) * numChannels, ChannelList)) {
3566
3567 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3568 kfree_skb(replySkb);
3569 return -EINVAL;
3570 }
3571
3572 return cfg80211_vendor_cmd_reply(replySkb);
3573}
3574
3575static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3576 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303577 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303578{
Dino Myclee8843b32014-07-04 14:21:45 +05303579 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303580 struct net_device *dev = wdev->netdev;
3581 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3582 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3583 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3584 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3585 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3586 struct nlattr *buckets;
3587 struct nlattr *channels;
3588 int rem1;
3589 int rem2;
3590 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303591 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303592
3593 status = wlan_hdd_validate_context(pHddCtx);
3594 if (0 != status)
3595 {
3596 hddLog(VOS_TRACE_LEVEL_ERROR,
3597 FL("HDD context is not valid"));
3598 return -EINVAL;
3599 }
Dino Myclee8843b32014-07-04 14:21:45 +05303600 /* check the EXTScan Capability */
3601 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3602 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3603 {
3604 hddLog(VOS_TRACE_LEVEL_ERROR,
3605 FL("EXTScan not enabled/supported by Firmware"));
3606 return -EINVAL;
3607 }
3608
Dino Mycle6fb96c12014-06-10 11:52:40 +05303609 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3610 data, dataLen,
3611 wlan_hdd_extscan_config_policy)) {
3612 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3613 return -EINVAL;
3614 }
3615
3616 /* Parse and fetch request Id */
3617 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3618 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3619 return -EINVAL;
3620 }
3621
Dino Myclee8843b32014-07-04 14:21:45 +05303622 pReqMsg = (tpSirEXTScanStartReqParams)
3623 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303624 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303625 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3626 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303627 }
3628
3629 pReqMsg->requestId = nla_get_u32(
3630 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3631 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3632
3633 pReqMsg->sessionId = pAdapter->sessionId;
3634 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3635
3636 /* Parse and fetch base period */
3637 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3638 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3639 goto fail;
3640 }
3641 pReqMsg->basePeriod = nla_get_u32(
3642 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3643 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3644 pReqMsg->basePeriod);
3645
3646 /* Parse and fetch max AP per scan */
3647 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3648 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3649 goto fail;
3650 }
3651 pReqMsg->maxAPperScan = nla_get_u32(
3652 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3653 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3654 pReqMsg->maxAPperScan);
3655
3656 /* Parse and fetch report threshold */
3657 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3658 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3659 goto fail;
3660 }
3661 pReqMsg->reportThreshold = nla_get_u8(
3662 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3663 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3664 pReqMsg->reportThreshold);
3665
3666 /* Parse and fetch number of buckets */
3667 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3668 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3669 goto fail;
3670 }
3671 pReqMsg->numBuckets = nla_get_u8(
3672 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3673 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3674 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3675 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3676 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3677 }
3678 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3679 pReqMsg->numBuckets);
3680 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3681 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3682 goto fail;
3683 }
3684
3685 nla_for_each_nested(buckets,
3686 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3687 if(nla_parse(bucket,
3688 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3689 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3690 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3691 goto fail;
3692 }
3693
3694 /* Parse and fetch bucket spec */
3695 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3696 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3697 goto fail;
3698 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303699
3700 pReqMsg->buckets[index].bucket = nla_get_u8(
3701 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3702
3703 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
3704 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303705
3706 /* Parse and fetch wifi band */
3707 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3708 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3709 goto fail;
3710 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303711 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303712 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3713 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303714 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303715
3716 /* Parse and fetch period */
3717 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3718 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3719 goto fail;
3720 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303721 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303722 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3723 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303724 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303725
3726 /* Parse and fetch report events */
3727 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3728 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3729 goto fail;
3730 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303731 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303732 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3733 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303734 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303735
3736 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303737 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
3738 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303739 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3740 goto fail;
3741 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303742 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303743 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3744 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303745 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303746
3747 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3748 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3749 goto fail;
3750 }
3751
3752 j = 0;
3753 nla_for_each_nested(channels,
3754 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3755 if(nla_parse(channel,
3756 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3757 nla_data(channels), nla_len(channels),
3758 NULL)) { //wlan_hdd_extscan_config_policy here
3759 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3760 goto fail;
3761 }
3762
3763 /* Parse and fetch channel */
3764 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3765 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3766 goto fail;
3767 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303768 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303769 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3770 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303771 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303772
3773 /* Parse and fetch dwell time */
3774 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3776 goto fail;
3777 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303778 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303779 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3780 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303781 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303782
3783 /* Parse and fetch channel spec passive */
3784 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3785 hddLog(VOS_TRACE_LEVEL_ERROR,
3786 FL("attr channel spec passive failed"));
3787 goto fail;
3788 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303789 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303790 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3791 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303792 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303793 j++;
3794 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303795 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303796 }
3797 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3798 if (!HAL_STATUS_SUCCESS(status)) {
3799 hddLog(VOS_TRACE_LEVEL_ERROR,
3800 FL("sme_EXTScanStart failed(err=%d)"), status);
3801 vos_mem_free(pReqMsg);
3802 return -EINVAL;
3803 }
3804
Dino Myclee8843b32014-07-04 14:21:45 +05303805 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303806 return 0;
3807
3808fail:
3809 vos_mem_free(pReqMsg);
3810 return -EINVAL;
3811}
3812
3813static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
3814 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303815 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303816{
Dino Myclee8843b32014-07-04 14:21:45 +05303817 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303818 struct net_device *dev = wdev->netdev;
3819 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3820 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3821 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3822 eHalStatus status;
3823
3824 status = wlan_hdd_validate_context(pHddCtx);
3825 if (0 != status)
3826 {
3827 hddLog(VOS_TRACE_LEVEL_ERROR,
3828 FL("HDD context is not valid"));
3829 return -EINVAL;
3830 }
Dino Myclee8843b32014-07-04 14:21:45 +05303831 /* check the EXTScan Capability */
3832 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3833 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3834 {
3835 hddLog(VOS_TRACE_LEVEL_ERROR,
3836 FL("EXTScan not enabled/supported by Firmware"));
3837 return -EINVAL;
3838 }
3839
Dino Mycle6fb96c12014-06-10 11:52:40 +05303840 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3841 data, dataLen,
3842 wlan_hdd_extscan_config_policy)) {
3843 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3844 return -EINVAL;
3845 }
3846
3847 /* Parse and fetch request Id */
3848 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3849 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3850 return -EINVAL;
3851 }
3852
Dino Myclee8843b32014-07-04 14:21:45 +05303853 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303854 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303855 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303856
Dino Myclee8843b32014-07-04 14:21:45 +05303857 reqMsg.sessionId = pAdapter->sessionId;
3858 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303859
Dino Myclee8843b32014-07-04 14:21:45 +05303860 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303861 if (!HAL_STATUS_SUCCESS(status)) {
3862 hddLog(VOS_TRACE_LEVEL_ERROR,
3863 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303864 return -EINVAL;
3865 }
3866
3867 return 0;
3868}
3869
3870static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
3871 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303872 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303873{
Dino Myclee8843b32014-07-04 14:21:45 +05303874 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303875 struct net_device *dev = wdev->netdev;
3876 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3877 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3878 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3879 eHalStatus status;
3880
3881 status = wlan_hdd_validate_context(pHddCtx);
3882 if (0 != status)
3883 {
3884 hddLog(VOS_TRACE_LEVEL_ERROR,
3885 FL("HDD context is not valid"));
3886 return -EINVAL;
3887 }
Dino Myclee8843b32014-07-04 14:21:45 +05303888 /* check the EXTScan Capability */
3889 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3890 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3891 {
3892 hddLog(VOS_TRACE_LEVEL_ERROR,
3893 FL("EXTScan not enabled/supported by Firmware"));
3894 return -EINVAL;
3895 }
3896
Dino Mycle6fb96c12014-06-10 11:52:40 +05303897 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3898 data, dataLen,
3899 wlan_hdd_extscan_config_policy)) {
3900 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3901 return -EINVAL;
3902 }
3903
3904 /* Parse and fetch request Id */
3905 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3906 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3907 return -EINVAL;
3908 }
3909
Dino Myclee8843b32014-07-04 14:21:45 +05303910 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303911 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303912 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303913
Dino Myclee8843b32014-07-04 14:21:45 +05303914 reqMsg.sessionId = pAdapter->sessionId;
3915 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303916
Dino Myclee8843b32014-07-04 14:21:45 +05303917 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303918 if (!HAL_STATUS_SUCCESS(status)) {
3919 hddLog(VOS_TRACE_LEVEL_ERROR,
3920 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303921 return -EINVAL;
3922 }
3923
3924 return 0;
3925}
3926
3927static int wlan_hdd_cfg80211_extscan_reset_significant_change(
3928 struct wiphy *wiphy,
3929 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303930 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303931{
Dino Myclee8843b32014-07-04 14:21:45 +05303932 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303933 struct net_device *dev = wdev->netdev;
3934 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3935 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3936 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3937 eHalStatus status;
3938
3939 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
3940 status = wlan_hdd_validate_context(pHddCtx);
3941 if (0 != status)
3942 {
3943 hddLog(VOS_TRACE_LEVEL_ERROR,
3944 FL("HDD context is not valid"));
3945 return -EINVAL;
3946 }
Dino Myclee8843b32014-07-04 14:21:45 +05303947 /* check the EXTScan Capability */
3948 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3949 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3950 {
3951 hddLog(VOS_TRACE_LEVEL_ERROR,
3952 FL("EXTScan not enabled/supported by Firmware"));
3953 return -EINVAL;
3954 }
3955
Dino Mycle6fb96c12014-06-10 11:52:40 +05303956 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3957 data, dataLen,
3958 wlan_hdd_extscan_config_policy)) {
3959 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3960 return -EINVAL;
3961 }
3962
3963 /* Parse and fetch request Id */
3964 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3965 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3966 return -EINVAL;
3967 }
3968
Dino Mycle6fb96c12014-06-10 11:52:40 +05303969
Dino Myclee8843b32014-07-04 14:21:45 +05303970 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303971 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303972 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303973
Dino Myclee8843b32014-07-04 14:21:45 +05303974 reqMsg.sessionId = pAdapter->sessionId;
3975 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303976
Dino Myclee8843b32014-07-04 14:21:45 +05303977 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303978 if (!HAL_STATUS_SUCCESS(status)) {
3979 hddLog(VOS_TRACE_LEVEL_ERROR,
3980 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303981 return -EINVAL;
3982 }
3983
3984 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3985 return 0;
3986}
3987
3988#endif /* WLAN_FEATURE_EXTSCAN */
3989
Atul Mittal115287b2014-07-08 13:26:33 +05303990/*EXT TDLS*/
3991static const struct nla_policy
3992wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
3993{
3994 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
3995 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
3996 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
3997 {.type = NLA_S32 },
3998 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
3999 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4000
4001};
4002
4003static const struct nla_policy
4004wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4005{
4006 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4007
4008};
4009
4010static const struct nla_policy
4011wlan_hdd_tdls_config_state_change_policy[
4012 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4013{
4014 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4015 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4016 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304017 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4018 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4019 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304020
4021};
4022
4023static const struct nla_policy
4024wlan_hdd_tdls_config_get_status_policy[
4025 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4026{
4027 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4028 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4029 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304030 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4031 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4032 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304033
4034};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304035
4036static const struct nla_policy
4037wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4038{
4039 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4040};
4041
4042static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
4043 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304044 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304045 int data_len)
4046{
4047
4048 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4049 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4050
4051 if (0 != wlan_hdd_validate_context(pHddCtx)){
4052 hddLog(VOS_TRACE_LEVEL_ERROR, FL("hdd Ctx invalid while spoof macAddr"));
4053 return -EINVAL;
4054 }
4055 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
4056 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN disabled in ini"));
4057 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304058 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304059 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
4060 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN not supported by FW"));
4061 return -ENOTSUPP;
4062 }
4063
4064 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4065 data, data_len, wlan_hdd_mac_config)) {
4066 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4067 return -EINVAL;
4068 }
4069
4070 /* Parse and fetch mac address */
4071 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4072 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4073 return -EINVAL;
4074 }
4075
4076 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4077 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4078 VOS_MAC_ADDR_LAST_3_BYTES);
4079
Siddharth Bhal76972212014-10-15 16:22:51 +05304080 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4081
4082 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304083 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4084 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304085 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4086 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4087 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4088 {
4089 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4090 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4091 VOS_MAC_ADDRESS_LEN);
4092 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304093 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304094
Siddharth Bhal76972212014-10-15 16:22:51 +05304095 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
4096 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304097 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4098 }
4099
4100 return 0;
4101}
4102
Atul Mittal115287b2014-07-08 13:26:33 +05304103static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4104 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304105 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304106 int data_len)
4107{
4108 u8 peer[6] = {0};
4109 struct net_device *dev = wdev->netdev;
4110 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4111 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4112 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4113 eHalStatus ret;
4114 tANI_S32 state;
4115 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304116 tANI_S32 global_operating_class = 0;
4117 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304118 struct sk_buff *skb = NULL;
4119
4120 ret = wlan_hdd_validate_context(pHddCtx);
4121 if (0 != ret) {
4122
4123 return -EINVAL;
4124 }
4125 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4126
4127 return -ENOTSUPP;
4128 }
4129 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4130 data, data_len,
4131 wlan_hdd_tdls_config_get_status_policy)) {
4132 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4133 return -EINVAL;
4134 }
4135
4136 /* Parse and fetch mac address */
4137 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4139 return -EINVAL;
4140 }
4141
4142 memcpy(peer, nla_data(
4143 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4144 sizeof(peer));
4145 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4146
4147 ret = wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
4148
4149 if (0 != ret) {
4150 hddLog(VOS_TRACE_LEVEL_ERROR,
4151 FL("get status Failed"));
4152 return -EINVAL;
4153 }
4154 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304155 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304156 NLMSG_HDRLEN);
4157
4158 if (!skb) {
4159 hddLog(VOS_TRACE_LEVEL_ERROR,
4160 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4161 return -EINVAL;
4162 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304163 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 +05304164 reason,
4165 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304166 global_operating_class,
4167 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304168 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304169 if (nla_put_s32(skb,
4170 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4171 state) ||
4172 nla_put_s32(skb,
4173 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4174 reason) ||
4175 nla_put_s32(skb,
4176 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4177 global_operating_class) ||
4178 nla_put_s32(skb,
4179 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4180 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304181
4182 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4183 goto nla_put_failure;
4184 }
4185
4186 return cfg80211_vendor_cmd_reply(skb);
4187
4188nla_put_failure:
4189 kfree_skb(skb);
4190 return -EINVAL;
4191}
4192
4193static int wlan_hdd_cfg80211_exttdls_callback(tANI_U8* mac,
4194 tANI_S32 state,
4195 tANI_S32 reason,
4196 void *ctx)
4197{
4198 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
4199 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4200 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304201 tANI_S32 global_operating_class = 0;
4202 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304203
4204 if (wlan_hdd_validate_context(pHddCtx)) {
4205 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "));
4206 return -EINVAL;
4207 }
4208
4209 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4210
4211 return -ENOTSUPP;
4212 }
4213 skb = cfg80211_vendor_event_alloc(
4214 pHddCtx->wiphy,
4215 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4216 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4217 GFP_KERNEL);
4218
4219 if (!skb) {
4220 hddLog(VOS_TRACE_LEVEL_ERROR,
4221 FL("cfg80211_vendor_event_alloc failed"));
4222 return -EINVAL;
4223 }
4224 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304225 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4226 reason,
4227 state,
4228 global_operating_class,
4229 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304230 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4231 MAC_ADDR_ARRAY(mac));
4232
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304233 if (nla_put(skb,
4234 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4235 VOS_MAC_ADDR_SIZE, mac) ||
4236 nla_put_s32(skb,
4237 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4238 state) ||
4239 nla_put_s32(skb,
4240 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4241 reason) ||
4242 nla_put_s32(skb,
4243 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4244 channel) ||
4245 nla_put_s32(skb,
4246 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4247 global_operating_class)
4248 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304249 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4250 goto nla_put_failure;
4251 }
4252
4253 cfg80211_vendor_event(skb, GFP_KERNEL);
4254 return (0);
4255
4256nla_put_failure:
4257 kfree_skb(skb);
4258 return -EINVAL;
4259}
4260
4261static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4262 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304263 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304264 int data_len)
4265{
4266 u8 peer[6] = {0};
4267 struct net_device *dev = wdev->netdev;
4268 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4269 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4270 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4271 eHalStatus status;
4272 tdls_req_params_t pReqMsg = {0};
4273
4274 status = wlan_hdd_validate_context(pHddCtx);
4275 if (0 != status) {
4276 hddLog(VOS_TRACE_LEVEL_ERROR,
4277 FL("HDD context is not valid"));
4278 return -EINVAL;
4279 }
4280 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4281
4282 return -ENOTSUPP;
4283 }
4284 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4285 data, data_len,
4286 wlan_hdd_tdls_config_enable_policy)) {
4287 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4288 return -EINVAL;
4289 }
4290
4291 /* Parse and fetch mac address */
4292 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4293 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4294 return -EINVAL;
4295 }
4296
4297 memcpy(peer, nla_data(
4298 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4299 sizeof(peer));
4300 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4301
4302 /* Parse and fetch channel */
4303 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4304 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4305 return -EINVAL;
4306 }
4307 pReqMsg.channel = nla_get_s32(
4308 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4309 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4310
4311 /* Parse and fetch global operating class */
4312 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4313 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4314 return -EINVAL;
4315 }
4316 pReqMsg.global_operating_class = nla_get_s32(
4317 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4318 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4319 pReqMsg.global_operating_class);
4320
4321 /* Parse and fetch latency ms */
4322 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4324 return -EINVAL;
4325 }
4326 pReqMsg.max_latency_ms = nla_get_s32(
4327 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4328 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4329 pReqMsg.max_latency_ms);
4330
4331 /* Parse and fetch required bandwidth kbps */
4332 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4333 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4334 return -EINVAL;
4335 }
4336
4337 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4338 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4339 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4340 pReqMsg.min_bandwidth_kbps);
4341
4342 return (wlan_hdd_tdls_extctrl_config_peer(pAdapter,
4343 peer,
4344 wlan_hdd_cfg80211_exttdls_callback));
4345}
4346
4347static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4348 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304349 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304350 int data_len)
4351{
4352 u8 peer[6] = {0};
4353 struct net_device *dev = wdev->netdev;
4354 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4355 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4356 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4357 eHalStatus status;
4358
4359 status = wlan_hdd_validate_context(pHddCtx);
4360 if (0 != status) {
4361 hddLog(VOS_TRACE_LEVEL_ERROR,
4362 FL("HDD context is not valid"));
4363 return -EINVAL;
4364 }
4365 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4366
4367 return -ENOTSUPP;
4368 }
4369 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4370 data, data_len,
4371 wlan_hdd_tdls_config_disable_policy)) {
4372 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4373 return -EINVAL;
4374 }
4375 /* Parse and fetch mac address */
4376 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4377 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4378 return -EINVAL;
4379 }
4380
4381 memcpy(peer, nla_data(
4382 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4383 sizeof(peer));
4384 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4385
4386 return (wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer));
4387}
4388
Dasari Srinivas7875a302014-09-26 17:50:57 +05304389static int
4390wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
4391 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304392 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05304393{
4394 struct net_device *dev = wdev->netdev;
4395 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4396 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4397 struct sk_buff *skb = NULL;
4398 tANI_U32 fset = 0;
4399
4400 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
4401 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
4402 fset |= WIFI_FEATURE_INFRA;
4403 }
4404
4405 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
4406 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
4407 fset |= WIFI_FEATURE_INFRA_5G;
4408 }
4409
4410#ifdef WLAN_FEATURE_P2P
4411 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
4412 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
4413 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
4414 fset |= WIFI_FEATURE_P2P;
4415 }
4416#endif
4417
4418 /* Soft-AP is supported currently by default */
4419 fset |= WIFI_FEATURE_SOFT_AP;
4420
4421#ifdef WLAN_FEATURE_EXTSCAN
4422 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
4423 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
4424 hddLog(LOG1, FL("EXTScan is supported by firmware"));
4425 fset |= WIFI_FEATURE_EXTSCAN;
4426 }
4427#endif
4428
4429#ifdef WLAN_FEATURE_NAN
4430 if (sme_IsFeatureSupportedByFW(NAN)) {
4431 hddLog(LOG1, FL("NAN is supported by firmware"));
4432 fset |= WIFI_FEATURE_NAN;
4433 }
4434#endif
4435
4436 /* D2D RTT is not supported currently by default */
4437 if (sme_IsFeatureSupportedByFW(RTT)) {
4438 hddLog(LOG1, FL("RTT is supported by firmware"));
4439 fset |= WIFI_FEATURE_D2AP_RTT;
4440 }
4441
4442#ifdef FEATURE_WLAN_BATCH_SCAN
4443 if (fset & WIFI_FEATURE_EXTSCAN) {
4444 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
4445 fset &= ~WIFI_FEATURE_BATCH_SCAN;
4446 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
4447 hddLog(LOG1, FL("Batch scan is supported by firmware"));
4448 fset |= WIFI_FEATURE_BATCH_SCAN;
4449 }
4450#endif
4451
4452#ifdef FEATURE_WLAN_SCAN_PNO
4453 if (pHddCtx->cfg_ini->configPNOScanSupport &&
4454 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
4455 hddLog(LOG1, FL("PNO is supported by firmware"));
4456 fset |= WIFI_FEATURE_PNO;
4457 }
4458#endif
4459
4460 /* STA+STA is supported currently by default */
4461 fset |= WIFI_FEATURE_ADDITIONAL_STA;
4462
4463#ifdef FEATURE_WLAN_TDLS
4464 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
4465 sme_IsFeatureSupportedByFW(TDLS)) {
4466 hddLog(LOG1, FL("TDLS is supported by firmware"));
4467 fset |= WIFI_FEATURE_TDLS;
4468 }
4469
4470 /* TDLS_OFFCHANNEL is not supported currently by default */
4471#endif
4472
4473#ifdef WLAN_AP_STA_CONCURRENCY
4474 /* AP+STA concurrency is supported currently by default */
4475 fset |= WIFI_FEATURE_AP_STA;
4476#endif
4477
4478 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
4479 NLMSG_HDRLEN);
4480
4481 if (!skb) {
4482 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4483 return -EINVAL;
4484 }
4485 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
4486
4487 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
4488 hddLog(LOGE, FL("nla put fail"));
4489 goto nla_put_failure;
4490 }
4491
4492 return cfg80211_vendor_cmd_reply(skb);
4493
4494nla_put_failure:
4495 kfree_skb(skb);
4496 return -EINVAL;
4497}
4498
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304499static int
4500wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
4501 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304502 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304503{
4504 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
4505 uint8_t i, feature_sets, max_feature_sets;
4506 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
4507 struct sk_buff *reply_skb;
4508
4509 ENTER();
4510
4511 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
4512 data, data_len, NULL)) {
4513 hddLog(LOGE, FL("Invalid ATTR"));
4514 return -EINVAL;
4515 }
4516
4517 /* Parse and fetch max feature set */
4518 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
4519 hddLog(LOGE, FL("Attr max feature set size failed"));
4520 return -EINVAL;
4521 }
4522 max_feature_sets = nla_get_u32(
4523 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
4524 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
4525
4526 /* Fill feature combination matrix */
4527 feature_sets = 0;
4528 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4529 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4530 WIFI_FEATURE_P2P;
4531
4532 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4533 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4534 WIFI_FEATURE_SOFT_AP;
4535
4536 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4537 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
4538 WIFI_FEATURE_SOFT_AP;
4539
4540 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4541 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4542 WIFI_FEATURE_SOFT_AP |
4543 WIFI_FEATURE_P2P;
4544
4545 /* Add more feature combinations here */
4546
4547 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
4548 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
4549 hddLog(LOG1, "Feature set matrix");
4550 for (i = 0; i < feature_sets; i++)
4551 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
4552
4553 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4554 sizeof(u32) * feature_sets +
4555 NLMSG_HDRLEN);
4556
4557 if (reply_skb) {
4558 if (nla_put_u32(reply_skb,
4559 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
4560 feature_sets) ||
4561 nla_put(reply_skb,
4562 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
4563 sizeof(u32) * feature_sets, feature_set_matrix)) {
4564 hddLog(LOGE, FL("nla put fail"));
4565 kfree_skb(reply_skb);
4566 return -EINVAL;
4567 }
4568
4569 return cfg80211_vendor_cmd_reply(reply_skb);
4570 }
4571 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
4572 return -ENOMEM;
4573
4574max_buffer_err:
4575 hddLog(LOGE, FL("Feature set max buffer size reached. feature_sets(%d) max(%d)"),
4576 feature_sets, WLAN_HDD_MAX_FEATURE_SET);
4577 return -EINVAL;
4578}
4579
Agarwal Ashish738843c2014-09-25 12:27:56 +05304580static const struct nla_policy
4581wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
4582 +1] =
4583{
4584 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
4585};
4586
4587static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
4588 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304589 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05304590 int data_len)
4591{
4592 struct net_device *dev = wdev->netdev;
4593 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4594 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4595 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4596 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
4597 eHalStatus status;
4598 u32 dfsFlag = 0;
4599
4600 status = wlan_hdd_validate_context(pHddCtx);
4601 if (0 != status) {
4602 hddLog(VOS_TRACE_LEVEL_ERROR,
4603 FL("HDD context is not valid"));
4604 return -EINVAL;
4605 }
4606 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
4607 data, data_len,
4608 wlan_hdd_set_no_dfs_flag_config_policy)) {
4609 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4610 return -EINVAL;
4611 }
4612
4613 /* Parse and fetch required bandwidth kbps */
4614 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
4615 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
4616 return -EINVAL;
4617 }
4618
4619 dfsFlag = nla_get_u32(
4620 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
4621 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
4622 dfsFlag);
4623
4624 pHddCtx->disable_dfs_flag = dfsFlag;
4625
4626 sme_disable_dfs_channel(hHal, dfsFlag);
4627 sme_FilterScanResults(hHal, pAdapter->sessionId);
4628 return 0;
4629}
Atul Mittal115287b2014-07-08 13:26:33 +05304630
Mukul Sharma2a271632014-10-13 14:59:01 +05304631const struct
4632nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
4633{
4634 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
4635 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
4636};
4637
4638static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05304639 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05304640{
4641
4642 u8 bssid[6] = {0};
4643 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4644 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
4645 eHalStatus status = eHAL_STATUS_SUCCESS;
4646 v_U32_t isFwrRoamEnabled = FALSE;
4647 int ret;
4648
4649 if (NULL == pHddCtx) {
4650 hddLog(VOS_TRACE_LEVEL_ERROR,
4651 FL("HDD context is not valid"));
4652 return -EINVAL;
4653 }
4654
4655 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
4656 data, data_len,
4657 qca_wlan_vendor_attr);
4658 if (ret){
4659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4660 return -EINVAL;
4661 }
4662
4663 /* Parse and fetch Enable flag */
4664 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
4665 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
4666 return -EINVAL;
4667 }
4668
4669 isFwrRoamEnabled = nla_get_u32(
4670 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
4671
4672 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
4673
4674 /* Parse and fetch bssid */
4675 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
4676 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
4677 return -EINVAL;
4678 }
4679
4680 memcpy(bssid, nla_data(
4681 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
4682 sizeof(bssid));
4683 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
4684
4685 //Update roaming
4686 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
4687 return status;
4688}
4689
Sunil Duttc69bccb2014-05-26 21:30:20 +05304690const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
4691{
Mukul Sharma2a271632014-10-13 14:59:01 +05304692 {
4693 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4694 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
4695 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4696 WIPHY_VENDOR_CMD_NEED_NETDEV |
4697 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304698 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05304699 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304700#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4701 {
4702 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4703 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
4704 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4705 WIPHY_VENDOR_CMD_NEED_NETDEV |
4706 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304707 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05304708 },
4709
4710 {
4711 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4712 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
4713 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4714 WIPHY_VENDOR_CMD_NEED_NETDEV |
4715 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304716 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05304717 },
4718
4719 {
4720 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4721 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
4722 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4723 WIPHY_VENDOR_CMD_NEED_NETDEV |
4724 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304725 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05304726 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304727#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304728#ifdef WLAN_FEATURE_EXTSCAN
4729 {
4730 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4731 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
4732 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4733 WIPHY_VENDOR_CMD_NEED_NETDEV |
4734 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304735 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05304736 },
4737 {
4738 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4739 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
4740 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4741 WIPHY_VENDOR_CMD_NEED_NETDEV |
4742 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304743 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05304744 },
4745 {
4746 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4747 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
4748 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4749 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304750 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05304751 },
4752 {
4753 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4754 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
4755 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4756 WIPHY_VENDOR_CMD_NEED_NETDEV |
4757 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304758 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05304759 },
4760 {
4761 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4762 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
4763 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4764 WIPHY_VENDOR_CMD_NEED_NETDEV |
4765 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304766 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05304767 },
4768 {
4769 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4770 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
4771 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4772 WIPHY_VENDOR_CMD_NEED_NETDEV |
4773 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304774 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05304775 },
4776 {
4777 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4778 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
4779 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4780 WIPHY_VENDOR_CMD_NEED_NETDEV |
4781 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304782 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05304783 },
4784 {
4785 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4786 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
4787 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4788 WIPHY_VENDOR_CMD_NEED_NETDEV |
4789 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304790 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05304791 },
4792 {
4793 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4794 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
4795 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4796 WIPHY_VENDOR_CMD_NEED_NETDEV |
4797 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304798 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05304799 },
4800#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304801/*EXT TDLS*/
4802 {
4803 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4804 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
4805 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4806 WIPHY_VENDOR_CMD_NEED_NETDEV |
4807 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304808 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05304809 },
4810 {
4811 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4812 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
4813 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4814 WIPHY_VENDOR_CMD_NEED_NETDEV |
4815 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304816 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05304817 },
4818 {
4819 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4820 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
4821 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4822 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304823 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05304824 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05304825 {
4826 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4827 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
4828 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4829 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304830 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05304831 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05304832 {
4833 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4834 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
4835 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4836 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304837 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05304838 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304839 {
4840 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4841 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
4842 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4843 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304844 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304845 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304846 {
4847 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4848 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
4849 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4850 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304851 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304852 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304853};
4854
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004855/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05304856static const
4857struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004858{
4859#ifdef FEATURE_WLAN_CH_AVOID
4860 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05304861 .vendor_id = QCA_NL80211_VENDOR_ID,
4862 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004863 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304864#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
4865#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4866 {
4867 /* Index = 1*/
4868 .vendor_id = QCA_NL80211_VENDOR_ID,
4869 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
4870 },
4871 {
4872 /* Index = 2*/
4873 .vendor_id = QCA_NL80211_VENDOR_ID,
4874 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
4875 },
4876 {
4877 /* Index = 3*/
4878 .vendor_id = QCA_NL80211_VENDOR_ID,
4879 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
4880 },
4881 {
4882 /* Index = 4*/
4883 .vendor_id = QCA_NL80211_VENDOR_ID,
4884 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
4885 },
4886 {
4887 /* Index = 5*/
4888 .vendor_id = QCA_NL80211_VENDOR_ID,
4889 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
4890 },
4891 {
4892 /* Index = 6*/
4893 .vendor_id = QCA_NL80211_VENDOR_ID,
4894 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
4895 },
4896#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304897#ifdef WLAN_FEATURE_EXTSCAN
4898 {
4899 .vendor_id = QCA_NL80211_VENDOR_ID,
4900 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
4901 },
4902 {
4903 .vendor_id = QCA_NL80211_VENDOR_ID,
4904 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
4905 },
4906 {
4907 .vendor_id = QCA_NL80211_VENDOR_ID,
4908 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
4909 },
4910 {
4911 .vendor_id = QCA_NL80211_VENDOR_ID,
4912 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
4913 },
4914 {
4915 .vendor_id = QCA_NL80211_VENDOR_ID,
4916 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
4917 },
4918 {
4919 .vendor_id = QCA_NL80211_VENDOR_ID,
4920 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
4921 },
4922 {
4923 .vendor_id = QCA_NL80211_VENDOR_ID,
4924 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
4925 },
4926 {
4927 .vendor_id = QCA_NL80211_VENDOR_ID,
4928 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
4929 },
4930 {
4931 .vendor_id = QCA_NL80211_VENDOR_ID,
4932 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
4933 },
4934 {
4935 .vendor_id = QCA_NL80211_VENDOR_ID,
4936 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
4937 },
4938 {
4939 .vendor_id = QCA_NL80211_VENDOR_ID,
4940 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
4941 },
4942 {
4943 .vendor_id = QCA_NL80211_VENDOR_ID,
4944 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
4945 },
4946 {
4947 .vendor_id = QCA_NL80211_VENDOR_ID,
4948 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
4949 },
4950#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304951/*EXT TDLS*/
4952 {
4953 .vendor_id = QCA_NL80211_VENDOR_ID,
4954 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
4955 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004956};
4957
Jeff Johnson295189b2012-06-20 16:38:30 -07004958/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304959 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304960 * This function is called by hdd_wlan_startup()
4961 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304962 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07004963 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304964struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07004965{
4966 struct wiphy *wiphy;
4967 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304968 /*
4969 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07004970 */
4971 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
4972
4973 if (!wiphy)
4974 {
4975 /* Print error and jump into err label and free the memory */
4976 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
4977 return NULL;
4978 }
4979
Sunil Duttc69bccb2014-05-26 21:30:20 +05304980
Jeff Johnson295189b2012-06-20 16:38:30 -07004981 return wiphy;
4982}
4983
4984/*
4985 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304986 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07004987 * private ioctl to change the band value
4988 */
4989int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
4990{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304991 int i, j;
4992 eNVChannelEnabledType channelEnabledState;
4993
Jeff Johnsone7245742012-09-05 17:12:55 -07004994 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304995
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304996 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07004997 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304998
4999 if (NULL == wiphy->bands[i])
5000 {
5001 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5002 __func__, i);
5003 continue;
5004 }
5005
5006 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5007 {
5008 struct ieee80211_supported_band *band = wiphy->bands[i];
5009
5010 channelEnabledState = vos_nv_getChannelEnabledState(
5011 band->channels[j].hw_value);
5012
5013 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
5014 {
Abhishek Singh678227a2014-11-04 10:52:38 +05305015 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305016 continue;
5017 }
5018 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
5019 {
5020 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5021 continue;
5022 }
5023
5024 if (NV_CHANNEL_DISABLE == channelEnabledState ||
5025 NV_CHANNEL_INVALID == channelEnabledState)
5026 {
5027 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5028 }
5029 else if (NV_CHANNEL_DFS == channelEnabledState)
5030 {
5031 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5032 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
5033 }
5034 else
5035 {
5036 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
5037 |IEEE80211_CHAN_RADAR);
5038 }
5039 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005040 }
5041 return 0;
5042}
5043/*
5044 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305045 * This function is called by hdd_wlan_startup()
5046 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005047 * This function is used to initialize and register wiphy structure.
5048 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305049int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005050 struct wiphy *wiphy,
5051 hdd_config_t *pCfg
5052 )
5053{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305054 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305055 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5056
Jeff Johnsone7245742012-09-05 17:12:55 -07005057 ENTER();
5058
Jeff Johnson295189b2012-06-20 16:38:30 -07005059 /* Now bind the underlying wlan device with wiphy */
5060 set_wiphy_dev(wiphy, dev);
5061
5062 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005063
Kiet Lam6c583332013-10-14 05:37:09 +05305064#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005065 /* the flag for the other case would be initialzed in
5066 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005067 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305068#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005069
Amar Singhalfddc28c2013-09-05 13:03:40 -07005070 /* This will disable updating of NL channels from passive to
5071 * active if a beacon is received on passive channel. */
5072 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07005073
Amar Singhalfddc28c2013-09-05 13:03:40 -07005074
Amar Singhala49cbc52013-10-08 18:37:44 -07005075
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005076#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005077 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5078 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5079 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005080 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05305081 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005082#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005083
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005084#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005085 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005086#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005087 || pCfg->isFastRoamIniFeatureEnabled
5088#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005089#ifdef FEATURE_WLAN_ESE
5090 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005091#endif
5092 )
5093 {
5094 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5095 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005096#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005097#ifdef FEATURE_WLAN_TDLS
5098 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5099 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5100#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305101#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305102 if (pCfg->configPNOScanSupport)
5103 {
5104 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5105 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5106 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5107 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5108 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305109#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005110
Amar Singhalfddc28c2013-09-05 13:03:40 -07005111#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005112 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5113 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005114 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005115 driver need to determine what to do with both
5116 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005117
5118 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005119#else
5120 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005121#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005122
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305123 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5124
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05305125 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005126
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305127 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5128
Jeff Johnson295189b2012-06-20 16:38:30 -07005129 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305130 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07005131 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07005132 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5133 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005134 | BIT(NL80211_IFTYPE_AP);
5135
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305136 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005137 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305138#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5139 if( pCfg->enableMCC )
5140 {
5141 /* Currently, supports up to two channels */
5142 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005143
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305144 if( !pCfg->allowMCCGODiffBI )
5145 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005146
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305147 }
5148 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5149 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005150#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305151 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005152
Jeff Johnson295189b2012-06-20 16:38:30 -07005153 /* Before registering we need to update the ht capabilitied based
5154 * on ini values*/
5155 if( !pCfg->ShortGI20MhzEnable )
5156 {
5157 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5158 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5159 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5160 }
5161
5162 if( !pCfg->ShortGI40MhzEnable )
5163 {
5164 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5165 }
5166
5167 if( !pCfg->nChannelBondingMode5GHz )
5168 {
5169 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5170 }
5171
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305172 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305173 if (true == hdd_is_5g_supported(pHddCtx))
5174 {
5175 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5176 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305177
5178 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5179 {
5180
5181 if (NULL == wiphy->bands[i])
5182 {
5183 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5184 __func__, i);
5185 continue;
5186 }
5187
5188 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5189 {
5190 struct ieee80211_supported_band *band = wiphy->bands[i];
5191
5192 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5193 {
5194 // Enable social channels for P2P
5195 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5196 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5197 else
5198 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5199 continue;
5200 }
5201 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5202 {
5203 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5204 continue;
5205 }
5206 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005207 }
5208 /*Initialise the supported cipher suite details*/
5209 wiphy->cipher_suites = hdd_cipher_suites;
5210 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5211
5212 /*signal strength in mBm (100*dBm) */
5213 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5214
5215#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305216 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005217#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005218
Sunil Duttc69bccb2014-05-26 21:30:20 +05305219 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
5220 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005221 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
5222 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
5223
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305224 EXIT();
5225 return 0;
5226}
5227
5228/* In this function we are registering wiphy. */
5229int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
5230{
5231 ENTER();
5232 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005233 if (0 > wiphy_register(wiphy))
5234 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305235 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07005236 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
5237 return -EIO;
5238 }
5239
5240 EXIT();
5241 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305242}
Jeff Johnson295189b2012-06-20 16:38:30 -07005243
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305244/* In this function we are updating channel list when,
5245 regulatory domain is FCC and country code is US.
5246 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
5247 As per FCC smart phone is not a indoor device.
5248 GO should not opeate on indoor channels */
5249void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
5250{
5251 int j;
5252 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5253 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
5254 //Default counrtycode from NV at the time of wiphy initialization.
5255 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
5256 &defaultCountryCode[0]))
5257 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005258 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305259 }
5260 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
5261 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305262 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
5263 {
5264 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
5265 return;
5266 }
5267 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
5268 {
5269 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
5270 // Mark UNII -1 band channel as passive
5271 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
5272 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
5273 }
5274 }
5275}
5276
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305277/* This function registers for all frame which supplicant is interested in */
5278void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005279{
Jeff Johnson295189b2012-06-20 16:38:30 -07005280 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5281 /* Register for all P2P action, public action etc frames */
5282 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5283
Jeff Johnsone7245742012-09-05 17:12:55 -07005284 ENTER();
5285
Jeff Johnson295189b2012-06-20 16:38:30 -07005286 /* Right now we are registering these frame when driver is getting
5287 initialized. Once we will move to 2.6.37 kernel, in which we have
5288 frame register ops, we will move this code as a part of that */
5289 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305290 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07005291 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5292
5293 /* GAS Initial Response */
5294 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5295 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305296
Jeff Johnson295189b2012-06-20 16:38:30 -07005297 /* GAS Comeback Request */
5298 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5299 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5300
5301 /* GAS Comeback Response */
5302 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5303 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5304
5305 /* P2P Public Action */
5306 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305307 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005308 P2P_PUBLIC_ACTION_FRAME_SIZE );
5309
5310 /* P2P Action */
5311 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5312 (v_U8_t*)P2P_ACTION_FRAME,
5313 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07005314
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05305315 /* WNM BSS Transition Request frame */
5316 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5317 (v_U8_t*)WNM_BSS_ACTION_FRAME,
5318 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005319
5320 /* WNM-Notification */
5321 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5322 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5323 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005324}
5325
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305326void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005327{
Jeff Johnson295189b2012-06-20 16:38:30 -07005328 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5329 /* Register for all P2P action, public action etc frames */
5330 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5331
Jeff Johnsone7245742012-09-05 17:12:55 -07005332 ENTER();
5333
Jeff Johnson295189b2012-06-20 16:38:30 -07005334 /* Right now we are registering these frame when driver is getting
5335 initialized. Once we will move to 2.6.37 kernel, in which we have
5336 frame register ops, we will move this code as a part of that */
5337 /* GAS Initial Request */
5338
5339 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5340 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5341
5342 /* GAS Initial Response */
5343 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5344 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305345
Jeff Johnson295189b2012-06-20 16:38:30 -07005346 /* GAS Comeback Request */
5347 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5348 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5349
5350 /* GAS Comeback Response */
5351 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5352 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5353
5354 /* P2P Public Action */
5355 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305356 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005357 P2P_PUBLIC_ACTION_FRAME_SIZE );
5358
5359 /* P2P Action */
5360 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5361 (v_U8_t*)P2P_ACTION_FRAME,
5362 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005363 /* WNM-Notification */
5364 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5365 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5366 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005367}
5368
5369#ifdef FEATURE_WLAN_WAPI
5370void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
5371 const u8 *mac_addr, u8 *key , int key_Len)
5372{
5373 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5374 tCsrRoamSetKey setKey;
5375 v_BOOL_t isConnected = TRUE;
5376 int status = 0;
5377 v_U32_t roamId= 0xFF;
5378 tANI_U8 *pKeyPtr = NULL;
5379 int n = 0;
5380
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305381 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
5382 __func__, hdd_device_modetoString(pAdapter->device_mode),
5383 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005384
Gopichand Nakkalae7480202013-02-11 15:24:22 +05305385 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005386 setKey.keyId = key_index; // Store Key ID
5387 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
5388 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
5389 setKey.paeRole = 0 ; // the PAE role
5390 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
5391 {
5392 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
5393 }
5394 else
5395 {
5396 isConnected = hdd_connIsConnected(pHddStaCtx);
5397 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
5398 }
5399 setKey.keyLength = key_Len;
5400 pKeyPtr = setKey.Key;
5401 memcpy( pKeyPtr, key, key_Len);
5402
Arif Hussain6d2a3322013-11-17 19:50:10 -08005403 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005404 __func__, key_Len);
5405 for (n = 0 ; n < key_Len; n++)
5406 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
5407 __func__,n,setKey.Key[n]);
5408
5409 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
5410 if ( isConnected )
5411 {
5412 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
5413 pAdapter->sessionId, &setKey, &roamId );
5414 }
5415 if ( status != 0 )
5416 {
5417 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5418 "[%4d] sme_RoamSetKey returned ERROR status= %d",
5419 __LINE__, status );
5420 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
5421 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05305422 /* Need to clear any trace of key value in the memory.
5423 * Thus zero out the memory even though it is local
5424 * variable.
5425 */
5426 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005427}
5428#endif /* FEATURE_WLAN_WAPI*/
5429
5430#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305431int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005432 beacon_data_t **ppBeacon,
5433 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005434#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305435int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005436 beacon_data_t **ppBeacon,
5437 struct cfg80211_beacon_data *params,
5438 int dtim_period)
5439#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305440{
Jeff Johnson295189b2012-06-20 16:38:30 -07005441 int size;
5442 beacon_data_t *beacon = NULL;
5443 beacon_data_t *old = NULL;
5444 int head_len,tail_len;
5445
Jeff Johnsone7245742012-09-05 17:12:55 -07005446 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005447 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305448 {
5449 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5450 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005451 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305452 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005453
5454 old = pAdapter->sessionCtx.ap.beacon;
5455
5456 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305457 {
5458 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5459 FL("session(%d) old and new heads points to NULL"),
5460 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005461 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305462 }
5463
5464 if (params->tail && !params->tail_len)
5465 {
5466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5467 FL("tail_len is zero but tail is not NULL"));
5468 return -EINVAL;
5469 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005470
Jeff Johnson295189b2012-06-20 16:38:30 -07005471#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
5472 /* Kernel 3.0 is not updating dtim_period for set beacon */
5473 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305474 {
5475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5476 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005477 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305478 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005479#endif
5480
5481 if(params->head)
5482 head_len = params->head_len;
5483 else
5484 head_len = old->head_len;
5485
5486 if(params->tail || !old)
5487 tail_len = params->tail_len;
5488 else
5489 tail_len = old->tail_len;
5490
5491 size = sizeof(beacon_data_t) + head_len + tail_len;
5492
5493 beacon = kzalloc(size, GFP_KERNEL);
5494
5495 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305496 {
5497 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5498 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005499 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305500 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005501
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005502#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005503 if(params->dtim_period || !old )
5504 beacon->dtim_period = params->dtim_period;
5505 else
5506 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005507#else
5508 if(dtim_period || !old )
5509 beacon->dtim_period = dtim_period;
5510 else
5511 beacon->dtim_period = old->dtim_period;
5512#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305513
Jeff Johnson295189b2012-06-20 16:38:30 -07005514 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
5515 beacon->tail = beacon->head + head_len;
5516 beacon->head_len = head_len;
5517 beacon->tail_len = tail_len;
5518
5519 if(params->head) {
5520 memcpy (beacon->head,params->head,beacon->head_len);
5521 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305522 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07005523 if(old)
5524 memcpy (beacon->head,old->head,beacon->head_len);
5525 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305526
Jeff Johnson295189b2012-06-20 16:38:30 -07005527 if(params->tail) {
5528 memcpy (beacon->tail,params->tail,beacon->tail_len);
5529 }
5530 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305531 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07005532 memcpy (beacon->tail,old->tail,beacon->tail_len);
5533 }
5534
5535 *ppBeacon = beacon;
5536
5537 kfree(old);
5538
5539 return 0;
5540
5541}
Jeff Johnson295189b2012-06-20 16:38:30 -07005542
5543v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
5544{
5545 int left = length;
5546 v_U8_t *ptr = pIes;
5547 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305548
Jeff Johnson295189b2012-06-20 16:38:30 -07005549 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305550 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005551 elem_id = ptr[0];
5552 elem_len = ptr[1];
5553 left -= 2;
5554 if(elem_len > left)
5555 {
5556 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005557 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005558 eid,elem_len,left);
5559 return NULL;
5560 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305561 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005562 {
5563 return ptr;
5564 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305565
Jeff Johnson295189b2012-06-20 16:38:30 -07005566 left -= elem_len;
5567 ptr += (elem_len + 2);
5568 }
5569 return NULL;
5570}
5571
Jeff Johnson295189b2012-06-20 16:38:30 -07005572/* Check if rate is 11g rate or not */
5573static int wlan_hdd_rate_is_11g(u8 rate)
5574{
Sanjay Devnani28322e22013-06-21 16:13:40 -07005575 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005576 u8 i;
5577 for (i = 0; i < 8; i++)
5578 {
5579 if(rate == gRateArray[i])
5580 return TRUE;
5581 }
5582 return FALSE;
5583}
5584
5585/* Check for 11g rate and set proper 11g only mode */
5586static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
5587 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
5588{
5589 u8 i, num_rates = pIe[0];
5590
5591 pIe += 1;
5592 for ( i = 0; i < num_rates; i++)
5593 {
5594 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
5595 {
5596 /* If rate set have 11g rate than change the mode to 11G */
5597 *pSapHw_mode = eSAP_DOT11_MODE_11g;
5598 if (pIe[i] & BASIC_RATE_MASK)
5599 {
5600 /* If we have 11g rate as basic rate, it means mode
5601 is 11g only mode.
5602 */
5603 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
5604 *pCheckRatesfor11g = FALSE;
5605 }
5606 }
5607 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
5608 {
5609 *require_ht = TRUE;
5610 }
5611 }
5612 return;
5613}
5614
5615static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
5616{
5617 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5618 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5619 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5620 u8 checkRatesfor11g = TRUE;
5621 u8 require_ht = FALSE;
5622 u8 *pIe=NULL;
5623
5624 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
5625
5626 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
5627 pBeacon->head_len, WLAN_EID_SUPP_RATES);
5628 if (pIe != NULL)
5629 {
5630 pIe += 1;
5631 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5632 &pConfig->SapHw_mode);
5633 }
5634
5635 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5636 WLAN_EID_EXT_SUPP_RATES);
5637 if (pIe != NULL)
5638 {
5639
5640 pIe += 1;
5641 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5642 &pConfig->SapHw_mode);
5643 }
5644
5645 if( pConfig->channel > 14 )
5646 {
5647 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
5648 }
5649
5650 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5651 WLAN_EID_HT_CAPABILITY);
5652
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305653 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005654 {
5655 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
5656 if(require_ht)
5657 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
5658 }
5659}
5660
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305661static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
5662 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
5663{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005664 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305665 v_U8_t *pIe = NULL;
5666 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5667
5668 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
5669 pBeacon->tail, pBeacon->tail_len);
5670
5671 if (pIe)
5672 {
5673 ielen = pIe[1] + 2;
5674 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5675 {
5676 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
5677 }
5678 else
5679 {
5680 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
5681 return -EINVAL;
5682 }
5683 *total_ielen += ielen;
5684 }
5685 return 0;
5686}
5687
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005688static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
5689 v_U8_t *genie, v_U8_t *total_ielen)
5690{
5691 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5692 int left = pBeacon->tail_len;
5693 v_U8_t *ptr = pBeacon->tail;
5694 v_U8_t elem_id, elem_len;
5695 v_U16_t ielen = 0;
5696
5697 if ( NULL == ptr || 0 == left )
5698 return;
5699
5700 while (left >= 2)
5701 {
5702 elem_id = ptr[0];
5703 elem_len = ptr[1];
5704 left -= 2;
5705 if (elem_len > left)
5706 {
5707 hddLog( VOS_TRACE_LEVEL_ERROR,
5708 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
5709 elem_id, elem_len, left);
5710 return;
5711 }
5712 if (IE_EID_VENDOR == elem_id)
5713 {
5714 /* skipping the VSIE's which we don't want to include or
5715 * it will be included by existing code
5716 */
5717 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
5718#ifdef WLAN_FEATURE_WFD
5719 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
5720#endif
5721 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5722 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5723 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
5724 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5725 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
5726 {
5727 ielen = ptr[1] + 2;
5728 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5729 {
5730 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
5731 *total_ielen += ielen;
5732 }
5733 else
5734 {
5735 hddLog( VOS_TRACE_LEVEL_ERROR,
5736 "IE Length is too big "
5737 "IEs eid=%d elem_len=%d total_ie_lent=%d",
5738 elem_id, elem_len, *total_ielen);
5739 }
5740 }
5741 }
5742
5743 left -= elem_len;
5744 ptr += (elem_len + 2);
5745 }
5746 return;
5747}
5748
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005749#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005750static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5751 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005752#else
5753static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5754 struct cfg80211_beacon_data *params)
5755#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005756{
5757 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305758 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005759 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07005760 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005761
5762 genie = vos_mem_malloc(MAX_GENIE_LEN);
5763
5764 if(genie == NULL) {
5765
5766 return -ENOMEM;
5767 }
5768
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305769 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5770 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005771 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305772 hddLog(LOGE,
5773 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305774 ret = -EINVAL;
5775 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005776 }
5777
5778#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305779 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5780 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
5781 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305782 hddLog(LOGE,
5783 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305784 ret = -EINVAL;
5785 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005786 }
5787#endif
5788
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305789 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5790 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005791 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305792 hddLog(LOGE,
5793 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305794 ret = -EINVAL;
5795 goto done;
5796 }
5797
5798 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
5799 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005800 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07005801 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005802
5803 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5804 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
5805 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
5806 {
5807 hddLog(LOGE,
5808 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005809 ret = -EINVAL;
5810 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005811 }
5812
5813 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5814 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5815 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5816 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5817 ==eHAL_STATUS_FAILURE)
5818 {
5819 hddLog(LOGE,
5820 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005821 ret = -EINVAL;
5822 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005823 }
5824
5825 // Added for ProResp IE
5826 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
5827 {
5828 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
5829 u8 probe_rsp_ie_len[3] = {0};
5830 u8 counter = 0;
5831 /* Check Probe Resp Length if it is greater then 255 then Store
5832 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
5833 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
5834 Store More then 255 bytes into One Variable.
5835 */
5836 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
5837 {
5838 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
5839 {
5840 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
5841 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
5842 }
5843 else
5844 {
5845 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
5846 rem_probe_resp_ie_len = 0;
5847 }
5848 }
5849
5850 rem_probe_resp_ie_len = 0;
5851
5852 if (probe_rsp_ie_len[0] > 0)
5853 {
5854 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5855 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
5856 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5857 probe_rsp_ie_len[0], NULL,
5858 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5859 {
5860 hddLog(LOGE,
5861 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005862 ret = -EINVAL;
5863 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005864 }
5865 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
5866 }
5867
5868 if (probe_rsp_ie_len[1] > 0)
5869 {
5870 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5871 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
5872 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5873 probe_rsp_ie_len[1], NULL,
5874 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5875 {
5876 hddLog(LOGE,
5877 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005878 ret = -EINVAL;
5879 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005880 }
5881 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
5882 }
5883
5884 if (probe_rsp_ie_len[2] > 0)
5885 {
5886 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5887 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
5888 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5889 probe_rsp_ie_len[2], NULL,
5890 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5891 {
5892 hddLog(LOGE,
5893 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005894 ret = -EINVAL;
5895 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005896 }
5897 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
5898 }
5899
5900 if (probe_rsp_ie_len[1] == 0 )
5901 {
5902 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5903 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
5904 eANI_BOOLEAN_FALSE) )
5905 {
5906 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005907 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005908 }
5909 }
5910
5911 if (probe_rsp_ie_len[2] == 0 )
5912 {
5913 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5914 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
5915 eANI_BOOLEAN_FALSE) )
5916 {
5917 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005918 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005919 }
5920 }
5921
5922 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5923 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5924 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5925 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5926 == eHAL_STATUS_FAILURE)
5927 {
5928 hddLog(LOGE,
5929 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005930 ret = -EINVAL;
5931 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005932 }
5933 }
5934 else
5935 {
5936 // Reset WNI_CFG_PROBE_RSP Flags
5937 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
5938
5939 hddLog(VOS_TRACE_LEVEL_INFO,
5940 "%s: No Probe Response IE received in set beacon",
5941 __func__);
5942 }
5943
5944 // Added for AssocResp IE
5945 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
5946 {
5947 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5948 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
5949 params->assocresp_ies_len, NULL,
5950 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5951 {
5952 hddLog(LOGE,
5953 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005954 ret = -EINVAL;
5955 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005956 }
5957
5958 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5959 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
5960 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5961 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5962 == eHAL_STATUS_FAILURE)
5963 {
5964 hddLog(LOGE,
5965 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005966 ret = -EINVAL;
5967 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005968 }
5969 }
5970 else
5971 {
5972 hddLog(VOS_TRACE_LEVEL_INFO,
5973 "%s: No Assoc Response IE received in set beacon",
5974 __func__);
5975
5976 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5977 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5978 eANI_BOOLEAN_FALSE) )
5979 {
5980 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005981 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005982 }
5983 }
5984
Jeff Johnsone7245742012-09-05 17:12:55 -07005985done:
Jeff Johnson295189b2012-06-20 16:38:30 -07005986 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305987 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005988}
Jeff Johnson295189b2012-06-20 16:38:30 -07005989
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305990/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005991 * FUNCTION: wlan_hdd_validate_operation_channel
5992 * called by wlan_hdd_cfg80211_start_bss() and
5993 * wlan_hdd_cfg80211_set_channel()
5994 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305995 * channel list.
5996 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005997VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005998{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305999
Jeff Johnson295189b2012-06-20 16:38:30 -07006000 v_U32_t num_ch = 0;
6001 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6002 u32 indx = 0;
6003 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306004 v_U8_t fValidChannel = FALSE, count = 0;
6005 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306006
Jeff Johnson295189b2012-06-20 16:38:30 -07006007 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6008
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306009 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006010 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306011 /* Validate the channel */
6012 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006013 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306014 if ( channel == rfChannels[count].channelNum )
6015 {
6016 fValidChannel = TRUE;
6017 break;
6018 }
6019 }
6020 if (fValidChannel != TRUE)
6021 {
6022 hddLog(VOS_TRACE_LEVEL_ERROR,
6023 "%s: Invalid Channel [%d]", __func__, channel);
6024 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006025 }
6026 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306027 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006028 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306029 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6030 valid_ch, &num_ch))
6031 {
6032 hddLog(VOS_TRACE_LEVEL_ERROR,
6033 "%s: failed to get valid channel list", __func__);
6034 return VOS_STATUS_E_FAILURE;
6035 }
6036 for (indx = 0; indx < num_ch; indx++)
6037 {
6038 if (channel == valid_ch[indx])
6039 {
6040 break;
6041 }
6042 }
6043
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306044 if (indx >= num_ch)
6045 {
6046 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6047 {
6048 eCsrBand band;
6049 unsigned int freq;
6050
6051 sme_GetFreqBand(hHal, &band);
6052
6053 if (eCSR_BAND_5G == band)
6054 {
6055#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6056 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6057 {
6058 freq = ieee80211_channel_to_frequency(channel,
6059 IEEE80211_BAND_2GHZ);
6060 }
6061 else
6062 {
6063 freq = ieee80211_channel_to_frequency(channel,
6064 IEEE80211_BAND_5GHZ);
6065 }
6066#else
6067 freq = ieee80211_channel_to_frequency(channel);
6068#endif
6069 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6070 return VOS_STATUS_SUCCESS;
6071 }
6072 }
6073
6074 hddLog(VOS_TRACE_LEVEL_ERROR,
6075 "%s: Invalid Channel [%d]", __func__, channel);
6076 return VOS_STATUS_E_FAILURE;
6077 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006078 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306079
Jeff Johnson295189b2012-06-20 16:38:30 -07006080 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306081
Jeff Johnson295189b2012-06-20 16:38:30 -07006082}
6083
Viral Modi3a32cc52013-02-08 11:14:52 -08006084/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306085 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08006086 * This function is used to set the channel number
6087 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306088static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08006089 struct ieee80211_channel *chan,
6090 enum nl80211_channel_type channel_type
6091 )
6092{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306093 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006094 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006095 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006096 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306097 hdd_context_t *pHddCtx;
6098 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006099
6100 ENTER();
6101
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306102
Viral Modi3a32cc52013-02-08 11:14:52 -08006103 if( NULL == dev )
6104 {
6105 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006106 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006107 return -ENODEV;
6108 }
6109 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306110
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306111 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6112 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6113 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006114 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306115 "%s: device_mode = %s (%d) freq = %d", __func__,
6116 hdd_device_modetoString(pAdapter->device_mode),
6117 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306118
6119 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6120 status = wlan_hdd_validate_context(pHddCtx);
6121
6122 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006123 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6125 "%s: HDD context is not valid", __func__);
6126 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006127 }
6128
6129 /*
6130 * Do freq to chan conversion
6131 * TODO: for 11a
6132 */
6133
6134 channel = ieee80211_frequency_to_channel(freq);
6135
6136 /* Check freq range */
6137 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6138 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6139 {
6140 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006141 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006142 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6143 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6144 return -EINVAL;
6145 }
6146
6147 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6148
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306149 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6150 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006151 {
6152 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6153 {
6154 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006155 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006156 return -EINVAL;
6157 }
6158 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6159 "%s: set channel to [%d] for device mode =%d",
6160 __func__, channel,pAdapter->device_mode);
6161 }
6162 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006163 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006164 )
6165 {
6166 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6167 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6168 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6169
6170 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6171 {
6172 /* Link is up then return cant set channel*/
6173 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006174 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006175 return -EINVAL;
6176 }
6177
6178 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6179 pHddStaCtx->conn_info.operationChannel = channel;
6180 pRoamProfile->ChannelInfo.ChannelList =
6181 &pHddStaCtx->conn_info.operationChannel;
6182 }
6183 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006184 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006185 )
6186 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306187 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6188 {
6189 if(VOS_STATUS_SUCCESS !=
6190 wlan_hdd_validate_operation_channel(pAdapter,channel))
6191 {
6192 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006193 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306194 return -EINVAL;
6195 }
6196 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6197 }
6198 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006199 {
6200 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6201
6202 /* If auto channel selection is configured as enable/ 1 then ignore
6203 channel set by supplicant
6204 */
6205 if ( cfg_param->apAutoChannelSelection )
6206 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306207 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6208 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006209 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306210 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6211 __func__, hdd_device_modetoString(pAdapter->device_mode),
6212 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006213 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306214 else
6215 {
6216 if(VOS_STATUS_SUCCESS !=
6217 wlan_hdd_validate_operation_channel(pAdapter,channel))
6218 {
6219 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006220 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306221 return -EINVAL;
6222 }
6223 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6224 }
Viral Modi3a32cc52013-02-08 11:14:52 -08006225 }
6226 }
6227 else
6228 {
6229 hddLog(VOS_TRACE_LEVEL_FATAL,
6230 "%s: Invalid device mode failed to set valid channel", __func__);
6231 return -EINVAL;
6232 }
6233 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306234 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006235}
6236
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306237static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
6238 struct net_device *dev,
6239 struct ieee80211_channel *chan,
6240 enum nl80211_channel_type channel_type
6241 )
6242{
6243 int ret;
6244
6245 vos_ssr_protect(__func__);
6246 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
6247 vos_ssr_unprotect(__func__);
6248
6249 return ret;
6250}
6251
Jeff Johnson295189b2012-06-20 16:38:30 -07006252#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6253static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6254 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006255#else
6256static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6257 struct cfg80211_beacon_data *params,
6258 const u8 *ssid, size_t ssid_len,
6259 enum nl80211_hidden_ssid hidden_ssid)
6260#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006261{
6262 tsap_Config_t *pConfig;
6263 beacon_data_t *pBeacon = NULL;
6264 struct ieee80211_mgmt *pMgmt_frame;
6265 v_U8_t *pIe=NULL;
6266 v_U16_t capab_info;
6267 eCsrAuthType RSNAuthType;
6268 eCsrEncryptionType RSNEncryptType;
6269 eCsrEncryptionType mcRSNEncryptType;
6270 int status = VOS_STATUS_SUCCESS;
6271 tpWLAN_SAPEventCB pSapEventCallback;
6272 hdd_hostapd_state_t *pHostapdState;
6273 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
6274 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306275 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006276 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306277 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07006278 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08006279 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05306280 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07006281 v_BOOL_t MFPCapable = VOS_FALSE;
6282 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306283 eHddDot11Mode sapDot11Mode =
6284 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07006285
6286 ENTER();
6287
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306288 iniConfig = pHddCtx->cfg_ini;
6289
Jeff Johnson295189b2012-06-20 16:38:30 -07006290 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
6291
6292 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6293
6294 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6295
6296 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6297
6298 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
6299
6300 //channel is already set in the set_channel Call back
6301 //pConfig->channel = pCommitConfig->channel;
6302
6303 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306304 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07006305 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
6306
6307 pConfig->dtim_period = pBeacon->dtim_period;
6308
Arif Hussain6d2a3322013-11-17 19:50:10 -08006309 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07006310 pConfig->dtim_period);
6311
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08006312 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07006313 {
6314 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006315 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05306316 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
6317 {
6318 tANI_BOOLEAN restartNeeded;
6319 pConfig->ieee80211d = 1;
6320 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
6321 sme_setRegInfo(hHal, pConfig->countryCode);
6322 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
6323 }
6324 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006325 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07006326 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07006327 pConfig->ieee80211d = 1;
6328 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
6329 sme_setRegInfo(hHal, pConfig->countryCode);
6330 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07006331 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006332 else
6333 {
6334 pConfig->ieee80211d = 0;
6335 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306336 /*
6337 * If auto channel is configured i.e. channel is 0,
6338 * so skip channel validation.
6339 */
6340 if( AUTO_CHANNEL_SELECT != pConfig->channel )
6341 {
6342 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
6343 {
6344 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006345 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306346 return -EINVAL;
6347 }
6348 }
6349 else
6350 {
6351 if(1 != pHddCtx->is_dynamic_channel_range_set)
6352 {
6353 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
6354 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
6355 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
6356 }
6357 pHddCtx->is_dynamic_channel_range_set = 0;
6358 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006359 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006360 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006361 {
6362 pConfig->ieee80211d = 0;
6363 }
6364 pConfig->authType = eSAP_AUTO_SWITCH;
6365
6366 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306367
6368 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07006369 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
6370
6371 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
6372
6373 /*Set wps station to configured*/
6374 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
6375
6376 if(pIe)
6377 {
6378 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
6379 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006380 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07006381 return -EINVAL;
6382 }
6383 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
6384 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006385 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07006386 /* Check 15 bit of WPS IE as it contain information for wps state
6387 * WPS state
6388 */
6389 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
6390 {
6391 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
6392 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
6393 {
6394 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
6395 }
6396 }
6397 }
6398 else
6399 {
6400 pConfig->wps_state = SAP_WPS_DISABLED;
6401 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306402 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07006403
c_hpothufe599e92014-06-16 11:38:55 +05306404 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6405 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6406 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
6407 eCSR_ENCRYPT_TYPE_NONE;
6408
Jeff Johnson295189b2012-06-20 16:38:30 -07006409 pConfig->RSNWPAReqIELength = 0;
6410 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306411 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006412 WLAN_EID_RSN);
6413 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306414 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006415 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6416 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6417 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306418 /* The actual processing may eventually be more extensive than
6419 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07006420 * by the app.
6421 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306422 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006423 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6424 &RSNEncryptType,
6425 &mcRSNEncryptType,
6426 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006427 &MFPCapable,
6428 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006429 pConfig->pRSNWPAReqIE[1]+2,
6430 pConfig->pRSNWPAReqIE );
6431
6432 if( VOS_STATUS_SUCCESS == status )
6433 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306434 /* Now copy over all the security attributes you have
6435 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006436 * */
6437 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6438 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6439 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6440 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306441 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006442 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6444 }
6445 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306446
Jeff Johnson295189b2012-06-20 16:38:30 -07006447 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6448 pBeacon->tail, pBeacon->tail_len);
6449
6450 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
6451 {
6452 if (pConfig->pRSNWPAReqIE)
6453 {
6454 /*Mixed mode WPA/WPA2*/
6455 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
6456 pConfig->RSNWPAReqIELength += pIe[1] + 2;
6457 }
6458 else
6459 {
6460 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6461 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6462 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306463 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006464 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6465 &RSNEncryptType,
6466 &mcRSNEncryptType,
6467 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006468 &MFPCapable,
6469 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006470 pConfig->pRSNWPAReqIE[1]+2,
6471 pConfig->pRSNWPAReqIE );
6472
6473 if( VOS_STATUS_SUCCESS == status )
6474 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306475 /* Now copy over all the security attributes you have
6476 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006477 * */
6478 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6479 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6480 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6481 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306482 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006483 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006484 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6485 }
6486 }
6487 }
6488
Jeff Johnson4416a782013-03-25 14:17:50 -07006489 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
6490 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
6491 return -EINVAL;
6492 }
6493
Jeff Johnson295189b2012-06-20 16:38:30 -07006494 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
6495
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006496#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006497 if (params->ssid != NULL)
6498 {
6499 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
6500 pConfig->SSIDinfo.ssid.length = params->ssid_len;
6501 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6502 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6503 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006504#else
6505 if (ssid != NULL)
6506 {
6507 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
6508 pConfig->SSIDinfo.ssid.length = ssid_len;
6509 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6510 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6511 }
6512#endif
6513
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306514 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07006515 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306516
Jeff Johnson295189b2012-06-20 16:38:30 -07006517 /* default value */
6518 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
6519 pConfig->num_accept_mac = 0;
6520 pConfig->num_deny_mac = 0;
6521
6522 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6523 pBeacon->tail, pBeacon->tail_len);
6524
6525 /* pIe for black list is following form:
6526 type : 1 byte
6527 length : 1 byte
6528 OUI : 4 bytes
6529 acl type : 1 byte
6530 no of mac addr in black list: 1 byte
6531 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306532 */
6533 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006534 {
6535 pConfig->SapMacaddr_acl = pIe[6];
6536 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006537 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006538 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306539 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
6540 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006541 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6542 for (i = 0; i < pConfig->num_deny_mac; i++)
6543 {
6544 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6545 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306546 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006547 }
6548 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6549 pBeacon->tail, pBeacon->tail_len);
6550
6551 /* pIe for white list is following form:
6552 type : 1 byte
6553 length : 1 byte
6554 OUI : 4 bytes
6555 acl type : 1 byte
6556 no of mac addr in white list: 1 byte
6557 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306558 */
6559 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006560 {
6561 pConfig->SapMacaddr_acl = pIe[6];
6562 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006563 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006564 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306565 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
6566 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006567 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6568 for (i = 0; i < pConfig->num_accept_mac; i++)
6569 {
6570 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6571 acl_entry++;
6572 }
6573 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306574
Jeff Johnson295189b2012-06-20 16:38:30 -07006575 wlan_hdd_set_sapHwmode(pHostapdAdapter);
6576
Jeff Johnsone7245742012-09-05 17:12:55 -07006577#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006578 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05306579 * This is valid only if mode is set to 11n in hostapd, either AUTO or
6580 * 11ac in .ini and 11ac is supported by both host and firmware.
6581 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
6582 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006583 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
6584 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306585 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
6586 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
6587 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
6588 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
6589 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07006590 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306591 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07006592 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306593 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006594
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306595 /* If ACS disable and selected channel <= 14
6596 * OR
6597 * ACS enabled and ACS operating band is choosen as 2.4
6598 * AND
6599 * VHT in 2.4G Disabled
6600 * THEN
6601 * Fallback to 11N mode
6602 */
6603 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
6604 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05306605 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306606 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006607 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306608 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
6609 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006610 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
6611 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006612 }
6613#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306614
Jeff Johnson295189b2012-06-20 16:38:30 -07006615 // ht_capab is not what the name conveys,this is used for protection bitmap
6616 pConfig->ht_capab =
6617 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
6618
6619 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
6620 {
6621 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
6622 return -EINVAL;
6623 }
6624
6625 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306626 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07006627 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
6628 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306629 pConfig->obssProtEnabled =
6630 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07006631
Chet Lanctot8cecea22014-02-11 19:09:36 -08006632#ifdef WLAN_FEATURE_11W
6633 pConfig->mfpCapable = MFPCapable;
6634 pConfig->mfpRequired = MFPRequired;
6635 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
6636 pConfig->mfpCapable, pConfig->mfpRequired);
6637#endif
6638
Arif Hussain6d2a3322013-11-17 19:50:10 -08006639 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07006640 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006641 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
6642 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
6643 (int)pConfig->channel);
6644 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
6645 pConfig->SapHw_mode, pConfig->privacy,
6646 pConfig->authType);
6647 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
6648 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
6649 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
6650 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07006651
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306652 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006653 {
6654 //Bss already started. just return.
6655 //TODO Probably it should update some beacon params.
6656 hddLog( LOGE, "Bss Already started...Ignore the request");
6657 EXIT();
6658 return 0;
6659 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306660
Agarwal Ashish51325b52014-06-16 16:50:49 +05306661 if (vos_max_concurrent_connections_reached()) {
6662 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6663 return -EINVAL;
6664 }
6665
Jeff Johnson295189b2012-06-20 16:38:30 -07006666 pConfig->persona = pHostapdAdapter->device_mode;
6667
Peng Xu2446a892014-09-05 17:21:18 +05306668 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
6669 if ( NULL != psmeConfig)
6670 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05306671 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05306672 sme_GetConfigParam(hHal, psmeConfig);
6673 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05306674#ifdef WLAN_FEATURE_AP_HT40_24G
6675 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
6676 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
6677 && pHddCtx->cfg_ini->apHT40_24GEnabled)
6678 {
6679 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
6680 sme_UpdateConfig (hHal, psmeConfig);
6681 }
6682#endif
Peng Xu2446a892014-09-05 17:21:18 +05306683 vos_mem_free(psmeConfig);
6684 }
Peng Xuafc34e32014-09-25 13:23:55 +05306685 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05306686
Jeff Johnson295189b2012-06-20 16:38:30 -07006687 pSapEventCallback = hdd_hostapd_SAPEventCB;
6688 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
6689 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
6690 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006691 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006692 return -EINVAL;
6693 }
6694
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306695 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07006696 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
6697
6698 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306699
Jeff Johnson295189b2012-06-20 16:38:30 -07006700 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306701 {
6702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006703 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07006704 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07006705 VOS_ASSERT(0);
6706 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306707
Jeff Johnson295189b2012-06-20 16:38:30 -07006708 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05306709 /* Initialize WMM configuation */
6710 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306711 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006712
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006713#ifdef WLAN_FEATURE_P2P_DEBUG
6714 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
6715 {
6716 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
6717 {
6718 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6719 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006720 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006721 }
6722 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
6723 {
6724 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6725 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006726 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006727 }
6728 }
6729#endif
6730
Jeff Johnson295189b2012-06-20 16:38:30 -07006731 pHostapdState->bCommit = TRUE;
6732 EXIT();
6733
6734 return 0;
6735}
6736
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006737#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05306738static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306739 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006740 struct beacon_parameters *params)
6741{
6742 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306743 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306744 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006745
6746 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306747
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306748 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6749 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
6750 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306751 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
6752 hdd_device_modetoString(pAdapter->device_mode),
6753 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006754
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306755 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6756 status = wlan_hdd_validate_context(pHddCtx);
6757
6758 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006759 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6761 "%s: HDD context is not valid", __func__);
6762 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006763 }
6764
Agarwal Ashish51325b52014-06-16 16:50:49 +05306765 if (vos_max_concurrent_connections_reached()) {
6766 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6767 return -EINVAL;
6768 }
6769
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306770 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006771 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006772 )
6773 {
6774 beacon_data_t *old,*new;
6775
6776 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306777
Jeff Johnson295189b2012-06-20 16:38:30 -07006778 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306779 {
6780 hddLog(VOS_TRACE_LEVEL_WARN,
6781 FL("already beacon info added to session(%d)"),
6782 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006783 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306784 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006785
6786 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6787
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306788 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07006789 {
6790 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006791 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006792 return -EINVAL;
6793 }
6794
6795 pAdapter->sessionCtx.ap.beacon = new;
6796
6797 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6798 }
6799
6800 EXIT();
6801 return status;
6802}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306803
Mukul Sharmab0e0a982014-12-15 18:58:53 +05306804static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
6805 struct net_device *dev,
6806 struct beacon_parameters *params)
6807{
6808 int ret;
6809
6810 vos_ssr_protect(__func__);
6811 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
6812 vos_ssr_unprotect(__func__);
6813
6814 return ret;
6815}
6816
6817static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006818 struct net_device *dev,
6819 struct beacon_parameters *params)
6820{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306821 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306822 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6823 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306824 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006825
6826 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306827 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6828 TRACE_CODE_HDD_CFG80211_SET_BEACON,
6829 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
6830 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6831 __func__, hdd_device_modetoString(pAdapter->device_mode),
6832 pAdapter->device_mode);
6833
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306834 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6835 status = wlan_hdd_validate_context(pHddCtx);
6836
6837 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006838 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306839 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6840 "%s: HDD context is not valid", __func__);
6841 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006842 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306843
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306844 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006845 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306846 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006847 {
6848 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306849
Jeff Johnson295189b2012-06-20 16:38:30 -07006850 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306851
Jeff Johnson295189b2012-06-20 16:38:30 -07006852 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306853 {
6854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6855 FL("session(%d) old and new heads points to NULL"),
6856 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006857 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306858 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006859
6860 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6861
6862 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306863 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006864 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006865 return -EINVAL;
6866 }
6867
6868 pAdapter->sessionCtx.ap.beacon = new;
6869
6870 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6871 }
6872
6873 EXIT();
6874 return status;
6875}
6876
Mukul Sharmab0e0a982014-12-15 18:58:53 +05306877static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
6878 struct net_device *dev,
6879 struct beacon_parameters *params)
6880{
6881 int ret;
6882
6883 vos_ssr_protect(__func__);
6884 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
6885 vos_ssr_unprotect(__func__);
6886
6887 return ret;
6888}
6889
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006890#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6891
6892#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05306893static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006894 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006895#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05306896static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006897 struct net_device *dev)
6898#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006899{
6900 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07006901 hdd_context_t *pHddCtx = NULL;
6902 hdd_scaninfo_t *pScanInfo = NULL;
6903 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306904 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306905 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006906
6907 ENTER();
6908
6909 if (NULL == pAdapter)
6910 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006912 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006913 return -ENODEV;
6914 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006915
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306916 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6917 TRACE_CODE_HDD_CFG80211_STOP_AP,
6918 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306919 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6920 status = wlan_hdd_validate_context(pHddCtx);
6921
6922 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006923 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306924 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6925 "%s: HDD context is not valid", __func__);
6926 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07006927 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006928
6929 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
6930 if (NULL == staAdapter)
6931 {
6932 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
6933 if (NULL == staAdapter)
6934 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07006935 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6936 "%s: HDD adapter context for STA/P2P-CLI is Null",
6937 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006938 }
6939 }
6940
6941 pScanInfo = &pHddCtx->scan_info;
6942
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306943 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6944 __func__, hdd_device_modetoString(pAdapter->device_mode),
6945 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006946
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306947 ret = wlan_hdd_scan_abort(pAdapter);
6948
Girish Gowli4bf7a632014-06-12 13:42:11 +05306949 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07006950 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6952 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306953
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306954 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07006955 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306956 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6957 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08006958
Jeff Johnsone7245742012-09-05 17:12:55 -07006959 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306960 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07006961 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306962 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07006963 }
6964
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05306965 /* Delete all associated STAs before stopping AP/P2P GO */
6966 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05306967 hdd_hostapd_stop(dev);
6968
Jeff Johnson295189b2012-06-20 16:38:30 -07006969 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006970 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006971 )
6972 {
6973 beacon_data_t *old;
6974
6975 old = pAdapter->sessionCtx.ap.beacon;
6976
6977 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306978 {
6979 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6980 FL("session(%d) beacon data points to NULL"),
6981 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006982 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306983 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006984
Jeff Johnson295189b2012-06-20 16:38:30 -07006985 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006986
6987 mutex_lock(&pHddCtx->sap_lock);
6988 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6989 {
Jeff Johnson4416a782013-03-25 14:17:50 -07006990 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006991 {
6992 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6993
6994 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6995
6996 if (!VOS_IS_STATUS_SUCCESS(status))
6997 {
6998 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006999 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007000 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307001 }
7002 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007003 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307004 /* BSS stopped, clear the active sessions for this device mode */
7005 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007006 }
7007 mutex_unlock(&pHddCtx->sap_lock);
7008
7009 if(status != VOS_STATUS_SUCCESS)
7010 {
7011 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007012 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007013 return -EINVAL;
7014 }
7015
Jeff Johnson4416a782013-03-25 14:17:50 -07007016 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007017 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
7018 ==eHAL_STATUS_FAILURE)
7019 {
7020 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007021 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007022 }
7023
Jeff Johnson4416a782013-03-25 14:17:50 -07007024 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007025 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7026 eANI_BOOLEAN_FALSE) )
7027 {
7028 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007029 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007030 }
7031
7032 // Reset WNI_CFG_PROBE_RSP Flags
7033 wlan_hdd_reset_prob_rspies(pAdapter);
7034
7035 pAdapter->sessionCtx.ap.beacon = NULL;
7036 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007037#ifdef WLAN_FEATURE_P2P_DEBUG
7038 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7039 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
7040 {
7041 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
7042 "GO got removed");
7043 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
7044 }
7045#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007046 }
7047 EXIT();
7048 return status;
7049}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007050
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307051#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7052static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
7053 struct net_device *dev)
7054{
7055 int ret;
7056
7057 vos_ssr_protect(__func__);
7058 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
7059 vos_ssr_unprotect(__func__);
7060
7061 return ret;
7062}
7063#else
7064static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7065 struct net_device *dev)
7066{
7067 int ret;
7068
7069 vos_ssr_protect(__func__);
7070 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7071 vos_ssr_unprotect(__func__);
7072
7073 return ret;
7074}
7075#endif
7076
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007077#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7078
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307079static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307080 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007081 struct cfg80211_ap_settings *params)
7082{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307083 hdd_adapter_t *pAdapter;
7084 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307085 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007086
7087 ENTER();
7088
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307089 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007090 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307092 "%s: Device is Null", __func__);
7093 return -ENODEV;
7094 }
7095
7096 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7097 if (NULL == pAdapter)
7098 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307100 "%s: HDD adapter is Null", __func__);
7101 return -ENODEV;
7102 }
7103
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307104 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7105 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
7106 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307107 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7108 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307110 "%s: HDD adapter magic is invalid", __func__);
7111 return -ENODEV;
7112 }
7113
7114 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307115 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307116
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307117 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307118 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7120 "%s: HDD context is not valid", __func__);
7121 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307122 }
7123
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307124 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7125 __func__, hdd_device_modetoString(pAdapter->device_mode),
7126 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307127
7128 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007129 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007130 )
7131 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307132 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007133
7134 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307135
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007136 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307137 {
7138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7139 FL("already beacon info added to session(%d)"),
7140 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007141 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307142 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007143
7144 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
7145
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307146 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007147 {
7148 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307149 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007150 return -EINVAL;
7151 }
7152 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007153#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007154 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7155#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7156 params->channel, params->channel_type);
7157#else
7158 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7159#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007160#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007161 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
7162 params->ssid_len, params->hidden_ssid);
7163 }
7164
7165 EXIT();
7166 return status;
7167}
7168
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307169static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7170 struct net_device *dev,
7171 struct cfg80211_ap_settings *params)
7172{
7173 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007174
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307175 vos_ssr_protect(__func__);
7176 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
7177 vos_ssr_unprotect(__func__);
7178
7179 return ret;
7180}
7181
7182static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007183 struct net_device *dev,
7184 struct cfg80211_beacon_data *params)
7185{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307186 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307187 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307188 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007189
7190 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307191
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307192 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7193 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7194 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007195 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007196 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307197
7198 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7199 status = wlan_hdd_validate_context(pHddCtx);
7200
7201 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007202 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307203 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7204 "%s: HDD context is not valid", __func__);
7205 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007206 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007207
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307208 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007209 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307210 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007211 {
7212 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307213
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007214 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307215
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007216 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307217 {
7218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7219 FL("session(%d) beacon data points to NULL"),
7220 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007221 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307222 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007223
7224 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
7225
7226 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307227 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007228 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007229 return -EINVAL;
7230 }
7231
7232 pAdapter->sessionCtx.ap.beacon = new;
7233
7234 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
7235 }
7236
7237 EXIT();
7238 return status;
7239}
7240
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307241static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
7242 struct net_device *dev,
7243 struct cfg80211_beacon_data *params)
7244{
7245 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007246
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307247 vos_ssr_protect(__func__);
7248 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
7249 vos_ssr_unprotect(__func__);
7250
7251 return ret;
7252}
7253
7254#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007255
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307256static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007257 struct net_device *dev,
7258 struct bss_parameters *params)
7259{
7260 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307261 hdd_context_t *pHddCtx;
7262 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007263
7264 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307265
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307266 if (NULL == pAdapter)
7267 {
7268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7269 "%s: HDD adapter is Null", __func__);
7270 return -ENODEV;
7271 }
7272 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7273
7274 ret = wlan_hdd_validate_context(pHddCtx);
7275 if (0 != ret)
7276 {
7277 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7278 "%s: HDD context is not valid", __func__);
7279 return ret;
7280 }
7281
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307282 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7283 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
7284 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307285 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7286 __func__, hdd_device_modetoString(pAdapter->device_mode),
7287 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007288
7289 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007290 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307291 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007292 {
7293 /* ap_isolate == -1 means that in change bss, upper layer doesn't
7294 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307295 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07007296 {
7297 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307298 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007299 }
7300
7301 EXIT();
7302 return 0;
7303}
7304
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307305static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
7306 struct net_device *dev,
7307 struct bss_parameters *params)
7308{
7309 int ret;
7310
7311 vos_ssr_protect(__func__);
7312 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
7313 vos_ssr_unprotect(__func__);
7314
7315 return ret;
7316}
Kiet Lam10841362013-11-01 11:36:50 +05307317/* FUNCTION: wlan_hdd_change_country_code_cd
7318* to wait for contry code completion
7319*/
7320void* wlan_hdd_change_country_code_cb(void *pAdapter)
7321{
7322 hdd_adapter_t *call_back_pAdapter = pAdapter;
7323 complete(&call_back_pAdapter->change_country_code);
7324 return NULL;
7325}
7326
Jeff Johnson295189b2012-06-20 16:38:30 -07007327/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307328 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07007329 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
7330 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307331int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007332 struct net_device *ndev,
7333 enum nl80211_iftype type,
7334 u32 *flags,
7335 struct vif_params *params
7336 )
7337{
7338 struct wireless_dev *wdev;
7339 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007340 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07007341 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007342 tCsrRoamProfile *pRoamProfile = NULL;
7343 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307344 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007345 eMib_dot11DesiredBssType connectedBssType;
7346 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307347 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007348
7349 ENTER();
7350
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307351 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007352 {
7353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7354 "%s: Adapter context is null", __func__);
7355 return VOS_STATUS_E_FAILURE;
7356 }
7357
7358 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7359 if (!pHddCtx)
7360 {
7361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7362 "%s: HDD context is null", __func__);
7363 return VOS_STATUS_E_FAILURE;
7364 }
7365
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307366 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7367 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
7368 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307369 status = wlan_hdd_validate_context(pHddCtx);
7370
7371 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007372 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7374 "%s: HDD context is not valid", __func__);
7375 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007376 }
7377
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307378 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7379 __func__, hdd_device_modetoString(pAdapter->device_mode),
7380 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007381
Agarwal Ashish51325b52014-06-16 16:50:49 +05307382 if (vos_max_concurrent_connections_reached()) {
7383 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7384 return -EINVAL;
7385 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307386 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007387 wdev = ndev->ieee80211_ptr;
7388
7389#ifdef WLAN_BTAMP_FEATURE
7390 if((NL80211_IFTYPE_P2P_CLIENT == type)||
7391 (NL80211_IFTYPE_ADHOC == type)||
7392 (NL80211_IFTYPE_AP == type)||
7393 (NL80211_IFTYPE_P2P_GO == type))
7394 {
7395 pHddCtx->isAmpAllowed = VOS_FALSE;
7396 // stop AMP traffic
7397 status = WLANBAP_StopAmp();
7398 if(VOS_STATUS_SUCCESS != status )
7399 {
7400 pHddCtx->isAmpAllowed = VOS_TRUE;
7401 hddLog(VOS_TRACE_LEVEL_FATAL,
7402 "%s: Failed to stop AMP", __func__);
7403 return -EINVAL;
7404 }
7405 }
7406#endif //WLAN_BTAMP_FEATURE
7407 /* Reset the current device mode bit mask*/
7408 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7409
7410 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007411 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07007412 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07007413 )
7414 {
7415 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007416 if (!pWextState)
7417 {
7418 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7419 "%s: pWextState is null", __func__);
7420 return VOS_STATUS_E_FAILURE;
7421 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007422 pRoamProfile = &pWextState->roamProfile;
7423 LastBSSType = pRoamProfile->BSSType;
7424
7425 switch (type)
7426 {
7427 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007428 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007429 hddLog(VOS_TRACE_LEVEL_INFO,
7430 "%s: setting interface Type to INFRASTRUCTURE", __func__);
7431 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07007432#ifdef WLAN_FEATURE_11AC
7433 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
7434 {
7435 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
7436 }
7437#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307438 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07007439 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007440 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007441 //Check for sub-string p2p to confirm its a p2p interface
7442 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307443 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007444 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7445 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7446 }
7447 else
7448 {
7449 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007450 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007451 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007452 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05307453
Jeff Johnson295189b2012-06-20 16:38:30 -07007454 case NL80211_IFTYPE_ADHOC:
7455 hddLog(VOS_TRACE_LEVEL_INFO,
7456 "%s: setting interface Type to ADHOC", __func__);
7457 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
7458 pRoamProfile->phyMode =
7459 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07007460 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007461 wdev->iftype = type;
7462 break;
7463
7464 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007465 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007466 {
7467 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7468 "%s: setting interface Type to %s", __func__,
7469 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
7470
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007471 //Cancel any remain on channel for GO mode
7472 if (NL80211_IFTYPE_P2P_GO == type)
7473 {
7474 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
7475 }
Mohit Khanna0f232092012-09-11 14:46:08 -07007476 if (NL80211_IFTYPE_AP == type)
7477 {
7478 /* As Loading WLAN Driver one interface being created for p2p device
7479 * address. This will take one HW STA and the max number of clients
7480 * that can connect to softAP will be reduced by one. so while changing
7481 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
7482 * interface as it is not required in SoftAP mode.
7483 */
7484
7485 // Get P2P Adapter
7486 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
7487
7488 if (pP2pAdapter)
7489 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307490 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07007491 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
7492 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
7493 }
7494 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05307495 //Disable IMPS & BMPS for SAP/GO
7496 if(VOS_STATUS_E_FAILURE ==
7497 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
7498 {
7499 //Fail to Exit BMPS
7500 VOS_ASSERT(0);
7501 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05307502
7503 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
7504
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307505#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07007506
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307507 /* A Mutex Lock is introduced while changing the mode to
7508 * protect the concurrent access for the Adapters by TDLS
7509 * module.
7510 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307511 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307512#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007513 //De-init the adapter.
Jeff Johnson295189b2012-06-20 16:38:30 -07007514 hdd_deinit_adapter( pHddCtx, pAdapter );
7515 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07007516 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7517 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307518#ifdef FEATURE_WLAN_TDLS
7519 mutex_unlock(&pHddCtx->tdls_lock);
7520#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007521 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
7522 (pConfig->apRandomBssidEnabled))
7523 {
7524 /* To meet Android requirements create a randomized
7525 MAC address of the form 02:1A:11:Fx:xx:xx */
7526 get_random_bytes(&ndev->dev_addr[3], 3);
7527 ndev->dev_addr[0] = 0x02;
7528 ndev->dev_addr[1] = 0x1A;
7529 ndev->dev_addr[2] = 0x11;
7530 ndev->dev_addr[3] |= 0xF0;
7531 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
7532 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08007533 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
7534 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007535 }
7536
Jeff Johnson295189b2012-06-20 16:38:30 -07007537 hdd_set_ap_ops( pAdapter->dev );
7538
Kiet Lam10841362013-11-01 11:36:50 +05307539 /* This is for only SAP mode where users can
7540 * control country through ini.
7541 * P2P GO follows station country code
7542 * acquired during the STA scanning. */
7543 if((NL80211_IFTYPE_AP == type) &&
7544 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
7545 {
7546 int status = 0;
7547 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
7548 "%s: setting country code from INI ", __func__);
7549 init_completion(&pAdapter->change_country_code);
7550 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
7551 (void *)(tSmeChangeCountryCallback)
7552 wlan_hdd_change_country_code_cb,
7553 pConfig->apCntryCode, pAdapter,
7554 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05307555 eSIR_FALSE,
7556 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05307557 if (eHAL_STATUS_SUCCESS == status)
7558 {
7559 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307560 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05307561 &pAdapter->change_country_code,
7562 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307563 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05307564 {
7565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307566 FL("SME Timed out while setting country code %ld"),
7567 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08007568
7569 if (pHddCtx->isLogpInProgress)
7570 {
7571 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7572 "%s: LOGP in Progress. Ignore!!!", __func__);
7573 return -EAGAIN;
7574 }
Kiet Lam10841362013-11-01 11:36:50 +05307575 }
7576 }
7577 else
7578 {
7579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007580 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05307581 return -EINVAL;
7582 }
7583 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007584 status = hdd_init_ap_mode(pAdapter);
7585 if(status != VOS_STATUS_SUCCESS)
7586 {
7587 hddLog(VOS_TRACE_LEVEL_FATAL,
7588 "%s: Error initializing the ap mode", __func__);
7589 return -EINVAL;
7590 }
7591 hdd_set_conparam(1);
7592
Jeff Johnson295189b2012-06-20 16:38:30 -07007593 /*interface type changed update in wiphy structure*/
7594 if(wdev)
7595 {
7596 wdev->iftype = type;
7597 pHddCtx->change_iface = type;
7598 }
7599 else
7600 {
7601 hddLog(VOS_TRACE_LEVEL_ERROR,
7602 "%s: ERROR !!!! Wireless dev is NULL", __func__);
7603 return -EINVAL;
7604 }
7605 goto done;
7606 }
7607
7608 default:
7609 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7610 __func__);
7611 return -EOPNOTSUPP;
7612 }
7613 }
7614 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007615 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007616 )
7617 {
7618 switch(type)
7619 {
7620 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007621 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007622 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05307623
7624 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307625#ifdef FEATURE_WLAN_TDLS
7626
7627 /* A Mutex Lock is introduced while changing the mode to
7628 * protect the concurrent access for the Adapters by TDLS
7629 * module.
7630 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307631 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307632#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07007633 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007634 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007635 //Check for sub-string p2p to confirm its a p2p interface
7636 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007637 {
7638 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7639 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7640 }
7641 else
7642 {
7643 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007644 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007645 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007646 hdd_set_conparam(0);
7647 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007648 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
7649 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307650#ifdef FEATURE_WLAN_TDLS
7651 mutex_unlock(&pHddCtx->tdls_lock);
7652#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05307653 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007654 if( VOS_STATUS_SUCCESS != status )
7655 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07007656 /* In case of JB, for P2P-GO, only change interface will be called,
7657 * This is the right place to enable back bmps_imps()
7658 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307659 if (pHddCtx->hdd_wlan_suspended)
7660 {
7661 hdd_set_pwrparams(pHddCtx);
7662 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007663 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007664 goto done;
7665 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007666 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007667 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007668 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7669 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007670 goto done;
7671 default:
7672 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7673 __func__);
7674 return -EOPNOTSUPP;
7675
7676 }
7677
7678 }
7679 else
7680 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307681 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
7682 __func__, hdd_device_modetoString(pAdapter->device_mode),
7683 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007684 return -EOPNOTSUPP;
7685 }
7686
7687
7688 if(pRoamProfile)
7689 {
7690 if ( LastBSSType != pRoamProfile->BSSType )
7691 {
7692 /*interface type changed update in wiphy structure*/
7693 wdev->iftype = type;
7694
7695 /*the BSS mode changed, We need to issue disconnect
7696 if connected or in IBSS disconnect state*/
7697 if ( hdd_connGetConnectedBssType(
7698 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
7699 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
7700 {
7701 /*need to issue a disconnect to CSR.*/
7702 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7703 if( eHAL_STATUS_SUCCESS ==
7704 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
7705 pAdapter->sessionId,
7706 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
7707 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307708 ret = wait_for_completion_interruptible_timeout(
7709 &pAdapter->disconnect_comp_var,
7710 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7711 if (ret <= 0)
7712 {
7713 hddLog(VOS_TRACE_LEVEL_ERROR,
7714 FL("wait on disconnect_comp_var failed %ld"), ret);
7715 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007716 }
7717 }
7718 }
7719 }
7720
7721done:
7722 /*set bitmask based on updated value*/
7723 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07007724
7725 /* Only STA mode support TM now
7726 * all other mode, TM feature should be disabled */
7727 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
7728 (~VOS_STA & pHddCtx->concurrency_mode) )
7729 {
7730 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
7731 }
7732
Jeff Johnson295189b2012-06-20 16:38:30 -07007733#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307734 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05307735 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07007736 {
7737 //we are ok to do AMP
7738 pHddCtx->isAmpAllowed = VOS_TRUE;
7739 }
7740#endif //WLAN_BTAMP_FEATURE
7741 EXIT();
7742 return 0;
7743}
7744
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307745/*
7746 * FUNCTION: wlan_hdd_cfg80211_change_iface
7747 * wrapper function to protect the actual implementation from SSR.
7748 */
7749int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
7750 struct net_device *ndev,
7751 enum nl80211_iftype type,
7752 u32 *flags,
7753 struct vif_params *params
7754 )
7755{
7756 int ret;
7757
7758 vos_ssr_protect(__func__);
7759 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
7760 vos_ssr_unprotect(__func__);
7761
7762 return ret;
7763}
7764
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007765#ifdef FEATURE_WLAN_TDLS
7766static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
7767 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
7768{
7769 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7770 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7771 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007772 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307773 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307774 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007775
7776 ENTER();
7777
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307778 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007779 {
7780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7781 "Invalid arguments");
7782 return -EINVAL;
7783 }
Hoonki Lee27511902013-03-14 18:19:06 -07007784
7785 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
7786 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
7787 {
7788 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7789 "%s: TDLS mode is disabled OR not enabled in FW."
7790 MAC_ADDRESS_STR " Request declined.",
7791 __func__, MAC_ADDR_ARRAY(mac));
7792 return -ENOTSUPP;
7793 }
7794
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007795 if (pHddCtx->isLogpInProgress)
7796 {
7797 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7798 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05307799 wlan_hdd_tdls_set_link_status(pAdapter,
7800 mac,
7801 eTDLS_LINK_IDLE,
7802 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007803 return -EBUSY;
7804 }
7805
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05307806 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007807
7808 if ( NULL == pTdlsPeer ) {
7809 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7810 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
7811 __func__, MAC_ADDR_ARRAY(mac), update);
7812 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007813 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007814
7815 /* in add station, we accept existing valid staId if there is */
7816 if ((0 == update) &&
7817 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
7818 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007819 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007820 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007821 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007822 " link_status %d. staId %d. add station ignored.",
7823 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
7824 return 0;
7825 }
7826 /* in change station, we accept only when staId is valid */
7827 if ((1 == update) &&
7828 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
7829 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
7830 {
7831 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7832 "%s: " MAC_ADDRESS_STR
7833 " link status %d. staId %d. change station %s.",
7834 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
7835 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
7836 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007837 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007838
7839 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307840 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007841 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7843 "%s: " MAC_ADDRESS_STR
7844 " TDLS setup is ongoing. Request declined.",
7845 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07007846 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007847 }
7848
7849 /* first to check if we reached to maximum supported TDLS peer.
7850 TODO: for now, return -EPERM looks working fine,
7851 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307852 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
7853 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007854 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7856 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307857 " TDLS Max peer already connected. Request declined."
7858 " Num of peers (%d), Max allowed (%d).",
7859 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
7860 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007861 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007862 }
7863 else
7864 {
7865 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307866 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007867 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007868 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007869 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7870 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
7871 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007872 return -EPERM;
7873 }
7874 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007875 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05307876 wlan_hdd_tdls_set_link_status(pAdapter,
7877 mac,
7878 eTDLS_LINK_CONNECTING,
7879 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007880
Jeff Johnsond75fe012013-04-06 10:53:06 -07007881 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307882 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007883 {
7884 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7885 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007886 if(StaParams->htcap_present)
7887 {
7888 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7889 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
7890 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7891 "ht_capa->extended_capabilities: %0x",
7892 StaParams->HTCap.extendedHtCapInfo);
7893 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007894 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7895 "params->capability: %0x",StaParams->capability);
7896 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007897 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007898 if(StaParams->vhtcap_present)
7899 {
7900 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7901 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
7902 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
7903 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
7904 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007905 {
7906 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007907 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007908 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
7909 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7910 "[%d]: %x ", i, StaParams->supported_rates[i]);
7911 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07007912 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307913 else if ((1 == update) && (NULL == StaParams))
7914 {
7915 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7916 "%s : update is true, but staParams is NULL. Error!", __func__);
7917 return -EPERM;
7918 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007919
7920 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
7921
7922 if (!update)
7923 {
7924 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7925 pAdapter->sessionId, mac);
7926 }
7927 else
7928 {
7929 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7930 pAdapter->sessionId, mac, StaParams);
7931 }
7932
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307933 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007934 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
7935
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307936 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007937 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007938 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307939 "%s: timeout waiting for tdls add station indication %ld",
7940 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007941 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007942 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307943
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007944 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
7945 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007946 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007947 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007948 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007949 }
7950
7951 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007952
7953error:
Atul Mittal115287b2014-07-08 13:26:33 +05307954 wlan_hdd_tdls_set_link_status(pAdapter,
7955 mac,
7956 eTDLS_LINK_IDLE,
7957 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007958 return -EPERM;
7959
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007960}
7961#endif
7962
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307963static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007964 struct net_device *dev,
7965 u8 *mac,
7966 struct station_parameters *params)
7967{
7968 VOS_STATUS status = VOS_STATUS_SUCCESS;
7969 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05307970 hdd_context_t *pHddCtx;
7971 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007972 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307973 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007974#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007975 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007976 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307977 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007978#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007979 ENTER();
7980
Gopichand Nakkala29149562013-05-10 21:43:41 +05307981 if ((NULL == pAdapter))
7982 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307983 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05307984 "invalid adapter ");
7985 return -EINVAL;
7986 }
7987
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307988 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7989 TRACE_CODE_HDD_CHANGE_STATION,
7990 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05307991 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05307992
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307993 ret = wlan_hdd_validate_context(pHddCtx);
7994 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05307995 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7997 "%s: HDD context is not valid", __func__);
7998 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05307999 }
8000
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308001 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8002
8003 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008004 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308005 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8006 "invalid HDD station context");
8007 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008008 }
8009
Jeff Johnson295189b2012-06-20 16:38:30 -07008010 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
8011
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008012 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8013 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07008014 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008015 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07008016 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308017 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07008018 WLANTL_STA_AUTHENTICATED);
8019
Gopichand Nakkala29149562013-05-10 21:43:41 +05308020 if (status != VOS_STATUS_SUCCESS)
8021 {
8022 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8023 "%s: Not able to change TL state to AUTHENTICATED", __func__);
8024 return -EINVAL;
8025 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008026 }
8027 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07008028 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8029 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308030#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008031 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8032 StaParams.capability = params->capability;
8033 StaParams.uapsd_queues = params->uapsd_queues;
8034 StaParams.max_sp = params->max_sp;
8035
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308036 /* Convert (first channel , number of channels) tuple to
8037 * the total list of channels. This goes with the assumption
8038 * that if the first channel is < 14, then the next channels
8039 * are an incremental of 1 else an incremental of 4 till the number
8040 * of channels.
8041 */
8042 if (0 != params->supported_channels_len) {
8043 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
8044 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
8045 {
8046 int wifi_chan_index;
8047 StaParams.supported_channels[j] = params->supported_channels[i];
8048 wifi_chan_index =
8049 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
8050 no_of_channels = params->supported_channels[i+1];
8051 for(k=1; k <= no_of_channels; k++)
8052 {
8053 StaParams.supported_channels[j+1] =
8054 StaParams.supported_channels[j] + wifi_chan_index;
8055 j+=1;
8056 }
8057 }
8058 StaParams.supported_channels_len = j;
8059 }
8060 vos_mem_copy(StaParams.supported_oper_classes,
8061 params->supported_oper_classes,
8062 params->supported_oper_classes_len);
8063 StaParams.supported_oper_classes_len =
8064 params->supported_oper_classes_len;
8065
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008066 if (0 != params->ext_capab_len)
8067 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
8068 sizeof(StaParams.extn_capability));
8069
8070 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008071 {
8072 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008073 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008074 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008075
8076 StaParams.supported_rates_len = params->supported_rates_len;
8077
8078 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
8079 * The supported_rates array , for all the structures propogating till Add Sta
8080 * to the firmware has to be modified , if the supplicant (ieee80211) is
8081 * modified to send more rates.
8082 */
8083
8084 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
8085 */
8086 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
8087 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
8088
8089 if (0 != StaParams.supported_rates_len) {
8090 int i = 0;
8091 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
8092 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008094 "Supported Rates with Length %d", StaParams.supported_rates_len);
8095 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008097 "[%d]: %0x", i, StaParams.supported_rates[i]);
8098 }
8099
8100 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008101 {
8102 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008103 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008104 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008105
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008106 if (0 != params->ext_capab_len ) {
8107 /*Define A Macro : TODO Sunil*/
8108 if ((1<<4) & StaParams.extn_capability[3]) {
8109 isBufSta = 1;
8110 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308111 /* TDLS Channel Switching Support */
8112 if ((1<<6) & StaParams.extn_capability[3]) {
8113 isOffChannelSupported = 1;
8114 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008115 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308116 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
8117 &StaParams, isBufSta,
8118 isOffChannelSupported);
8119
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308120 if (VOS_STATUS_SUCCESS != status) {
8121 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8122 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
8123 return -EINVAL;
8124 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008125 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
8126
8127 if (VOS_STATUS_SUCCESS != status) {
8128 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8129 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
8130 return -EINVAL;
8131 }
8132 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008133#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05308134 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008135 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008136 return status;
8137}
8138
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308139static int wlan_hdd_change_station(struct wiphy *wiphy,
8140 struct net_device *dev,
8141 u8 *mac,
8142 struct station_parameters *params)
8143{
8144 int ret;
8145
8146 vos_ssr_protect(__func__);
8147 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
8148 vos_ssr_unprotect(__func__);
8149
8150 return ret;
8151}
8152
Jeff Johnson295189b2012-06-20 16:38:30 -07008153/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308154 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008155 * This function is used to initialize the key information
8156 */
8157#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308158static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008159 struct net_device *ndev,
8160 u8 key_index, bool pairwise,
8161 const u8 *mac_addr,
8162 struct key_params *params
8163 )
8164#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308165static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008166 struct net_device *ndev,
8167 u8 key_index, const u8 *mac_addr,
8168 struct key_params *params
8169 )
8170#endif
8171{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008172 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07008173 tCsrRoamSetKey setKey;
8174 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308175 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008176 v_U32_t roamId= 0xFF;
8177 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008178 hdd_hostapd_state_t *pHostapdState;
8179 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008180 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308181 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008182
8183 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308184
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308185 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8186 TRACE_CODE_HDD_CFG80211_ADD_KEY,
8187 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308188 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8189 status = wlan_hdd_validate_context(pHddCtx);
8190
8191 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008192 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8194 "%s: HDD context is not valid", __func__);
8195 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008196 }
8197
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308198 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8199 __func__, hdd_device_modetoString(pAdapter->device_mode),
8200 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008201
8202 if (CSR_MAX_NUM_KEY <= key_index)
8203 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008204 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008205 key_index);
8206
8207 return -EINVAL;
8208 }
8209
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008210 if (CSR_MAX_KEY_LEN < params->key_len)
8211 {
8212 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
8213 params->key_len);
8214
8215 return -EINVAL;
8216 }
8217
8218 hddLog(VOS_TRACE_LEVEL_INFO,
8219 "%s: called with key index = %d & key length %d",
8220 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008221
8222 /*extract key idx, key len and key*/
8223 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8224 setKey.keyId = key_index;
8225 setKey.keyLength = params->key_len;
8226 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
8227
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008228 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07008229 {
8230 case WLAN_CIPHER_SUITE_WEP40:
8231 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
8232 break;
8233
8234 case WLAN_CIPHER_SUITE_WEP104:
8235 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
8236 break;
8237
8238 case WLAN_CIPHER_SUITE_TKIP:
8239 {
8240 u8 *pKey = &setKey.Key[0];
8241 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
8242
8243 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
8244
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008245 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07008246
8247 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008248 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008249 |--------------|----------|----------|
8250 <---16bytes---><--8bytes--><--8bytes-->
8251
8252 */
8253 /*Sme expects the 32 bytes key to be in the below order
8254
8255 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008256 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008257 |--------------|----------|----------|
8258 <---16bytes---><--8bytes--><--8bytes-->
8259 */
8260 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008261 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07008262
8263 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008264 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008265
8266 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008267 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008268
8269
8270 break;
8271 }
8272
8273 case WLAN_CIPHER_SUITE_CCMP:
8274 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
8275 break;
8276
8277#ifdef FEATURE_WLAN_WAPI
8278 case WLAN_CIPHER_SUITE_SMS4:
8279 {
8280 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8281 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
8282 params->key, params->key_len);
8283 return 0;
8284 }
8285#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008286
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008287#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07008288 case WLAN_CIPHER_SUITE_KRK:
8289 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
8290 break;
8291#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008292
8293#ifdef WLAN_FEATURE_11W
8294 case WLAN_CIPHER_SUITE_AES_CMAC:
8295 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07008296 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07008297#endif
8298
Jeff Johnson295189b2012-06-20 16:38:30 -07008299 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008300 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07008301 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308302 status = -EOPNOTSUPP;
8303 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008304 }
8305
8306 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
8307 __func__, setKey.encType);
8308
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008309 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07008310#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8311 (!pairwise)
8312#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008313 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07008314#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008315 )
8316 {
8317 /* set group key*/
8318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8319 "%s- %d: setting Broadcast key",
8320 __func__, __LINE__);
8321 setKey.keyDirection = eSIR_RX_ONLY;
8322 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8323 }
8324 else
8325 {
8326 /* set pairwise key*/
8327 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8328 "%s- %d: setting pairwise key",
8329 __func__, __LINE__);
8330 setKey.keyDirection = eSIR_TX_RX;
8331 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8332 }
8333 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
8334 {
8335 setKey.keyDirection = eSIR_TX_RX;
8336 /*Set the group key*/
8337 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8338 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07008339
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008340 if ( 0 != status )
8341 {
8342 hddLog(VOS_TRACE_LEVEL_ERROR,
8343 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308344 status = -EINVAL;
8345 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008346 }
8347 /*Save the keys here and call sme_RoamSetKey for setting
8348 the PTK after peer joins the IBSS network*/
8349 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
8350 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308351 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008352 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05308353 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
8354 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
8355 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008356 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008357 if( pHostapdState->bssState == BSS_START )
8358 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008359 status = WLANSAP_SetKeySta( pVosContext, &setKey);
8360
8361 if ( status != eHAL_STATUS_SUCCESS )
8362 {
8363 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8364 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8365 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308366 status = -EINVAL;
8367 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008368 }
8369 }
8370
8371 /* Saving WEP keys */
8372 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
8373 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
8374 {
8375 //Save the wep key in ap context. Issue setkey after the BSS is started.
8376 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8377 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
8378 }
8379 else
8380 {
8381 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008382 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008383 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
8384 }
8385 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008386 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
8387 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008388 {
8389 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8390 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8391
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308392#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8393 if (!pairwise)
8394#else
8395 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8396#endif
8397 {
8398 /* set group key*/
8399 if (pHddStaCtx->roam_info.deferKeyComplete)
8400 {
8401 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8402 "%s- %d: Perform Set key Complete",
8403 __func__, __LINE__);
8404 hdd_PerformRoamSetKeyComplete(pAdapter);
8405 }
8406 }
8407
Jeff Johnson295189b2012-06-20 16:38:30 -07008408 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
8409
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08008410 pWextState->roamProfile.Keys.defaultIndex = key_index;
8411
8412
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008413 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008414 params->key, params->key_len);
8415
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308416
Jeff Johnson295189b2012-06-20 16:38:30 -07008417 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8418
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308419 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008420 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308421 __func__, setKey.peerMac[0], setKey.peerMac[1],
8422 setKey.peerMac[2], setKey.peerMac[3],
8423 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008424 setKey.keyDirection);
8425
Nirav Shah4f765af2015-01-21 19:51:30 +05308426 /* Wait for EAPOL M4 before setting key.
8427 * No need to consider Dynamic WEP as we will receive M8.
8428 */
8429 if ( (setKey.encType == eCSR_ENCRYPT_TYPE_AES ||
8430 setKey.encType == eCSR_ENCRYPT_TYPE_TKIP) &&
8431 ( 1
8432#if defined WLAN_FEATURE_VOWIFI_11R
8433 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_FT_RSN
8434 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_FT_RSN_PSK
8435#endif
8436#ifdef FEATURE_WLAN_ESE
8437 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_CCKM_WPA
8438 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_CCKM_RSN
8439#endif
8440 ))
Jeff Johnson295189b2012-06-20 16:38:30 -07008441 {
Nirav Shah4f765af2015-01-21 19:51:30 +05308442 vos_status = wlan_hdd_check_ula_done(pAdapter);
8443
8444 if ( vos_status != VOS_STATUS_SUCCESS )
8445 {
8446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008447 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8448 __LINE__, vos_status );
8449
Nirav Shah4f765af2015-01-21 19:51:30 +05308450 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008451
Nirav Shah4f765af2015-01-21 19:51:30 +05308452 status = -EINVAL;
8453 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008454
Nirav Shah4f765af2015-01-21 19:51:30 +05308455 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008456 }
8457
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008458#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308459 /* The supplicant may attempt to set the PTK once pre-authentication
8460 is done. Save the key in the UMAC and include it in the ADD BSS
8461 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008462 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308463 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008464 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308465 hddLog(VOS_TRACE_LEVEL_INFO_MED,
8466 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308467 status = 0;
8468 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308469 }
8470 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
8471 {
8472 hddLog(VOS_TRACE_LEVEL_ERROR,
8473 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308474 status = -EINVAL;
8475 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008476 }
8477#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07008478
8479 /* issue set key request to SME*/
8480 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8481 pAdapter->sessionId, &setKey, &roamId );
8482
8483 if ( 0 != status )
8484 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308485 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008486 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
8487 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308488 status = -EINVAL;
8489 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008490 }
8491
8492
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308493 /* in case of IBSS as there was no information available about WEP keys during
8494 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07008495 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308496 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
8497 !( ( IW_AUTH_KEY_MGMT_802_1X
8498 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07008499 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
8500 )
8501 &&
8502 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
8503 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
8504 )
8505 )
8506 {
8507 setKey.keyDirection = eSIR_RX_ONLY;
8508 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8509
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308510 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008511 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308512 __func__, setKey.peerMac[0], setKey.peerMac[1],
8513 setKey.peerMac[2], setKey.peerMac[3],
8514 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008515 setKey.keyDirection);
8516
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308517 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008518 pAdapter->sessionId, &setKey, &roamId );
8519
8520 if ( 0 != status )
8521 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308522 hddLog(VOS_TRACE_LEVEL_ERROR,
8523 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008524 __func__, status);
8525 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308526 status = -EINVAL;
8527 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008528 }
8529 }
8530 }
8531
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308532end:
8533 /* Need to clear any trace of key value in the memory.
8534 * Thus zero out the memory even though it is local
8535 * variable.
8536 */
8537 vos_mem_zero(&setKey, sizeof(setKey));
8538
8539 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008540}
8541
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308542#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8543static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8544 struct net_device *ndev,
8545 u8 key_index, bool pairwise,
8546 const u8 *mac_addr,
8547 struct key_params *params
8548 )
8549#else
8550static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8551 struct net_device *ndev,
8552 u8 key_index, const u8 *mac_addr,
8553 struct key_params *params
8554 )
8555#endif
8556{
8557 int ret;
8558 vos_ssr_protect(__func__);
8559#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8560 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
8561 mac_addr, params);
8562#else
8563 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
8564 params);
8565#endif
8566 vos_ssr_unprotect(__func__);
8567
8568 return ret;
8569}
8570
Jeff Johnson295189b2012-06-20 16:38:30 -07008571/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308572 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008573 * This function is used to get the key information
8574 */
8575#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308576static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308577 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008578 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308579 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008580 const u8 *mac_addr, void *cookie,
8581 void (*callback)(void *cookie, struct key_params*)
8582 )
8583#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308584static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308585 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008586 struct net_device *ndev,
8587 u8 key_index, const u8 *mac_addr, void *cookie,
8588 void (*callback)(void *cookie, struct key_params*)
8589 )
8590#endif
8591{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308592 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308593 hdd_wext_state_t *pWextState = NULL;
8594 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008595 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308596 hdd_context_t *pHddCtx;
8597 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008598
8599 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308600
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308601 if (NULL == pAdapter)
8602 {
8603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8604 "%s: HDD adapter is Null", __func__);
8605 return -ENODEV;
8606 }
8607
8608 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8609 ret = wlan_hdd_validate_context(pHddCtx);
8610 if (0 != ret)
8611 {
8612 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8613 "%s: HDD context is not valid", __func__);
8614 return ret;
8615 }
8616
8617 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8618 pRoamProfile = &(pWextState->roamProfile);
8619
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308620 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8621 __func__, hdd_device_modetoString(pAdapter->device_mode),
8622 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308623
Jeff Johnson295189b2012-06-20 16:38:30 -07008624 memset(&params, 0, sizeof(params));
8625
8626 if (CSR_MAX_NUM_KEY <= key_index)
8627 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308628 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07008629 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308630 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008631
8632 switch(pRoamProfile->EncryptionType.encryptionType[0])
8633 {
8634 case eCSR_ENCRYPT_TYPE_NONE:
8635 params.cipher = IW_AUTH_CIPHER_NONE;
8636 break;
8637
8638 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
8639 case eCSR_ENCRYPT_TYPE_WEP40:
8640 params.cipher = WLAN_CIPHER_SUITE_WEP40;
8641 break;
8642
8643 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
8644 case eCSR_ENCRYPT_TYPE_WEP104:
8645 params.cipher = WLAN_CIPHER_SUITE_WEP104;
8646 break;
8647
8648 case eCSR_ENCRYPT_TYPE_TKIP:
8649 params.cipher = WLAN_CIPHER_SUITE_TKIP;
8650 break;
8651
8652 case eCSR_ENCRYPT_TYPE_AES:
8653 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
8654 break;
8655
8656 default:
8657 params.cipher = IW_AUTH_CIPHER_NONE;
8658 break;
8659 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308660
c_hpothuaaf19692014-05-17 17:01:48 +05308661 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8662 TRACE_CODE_HDD_CFG80211_GET_KEY,
8663 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308664
Jeff Johnson295189b2012-06-20 16:38:30 -07008665 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
8666 params.seq_len = 0;
8667 params.seq = NULL;
8668 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
8669 callback(cookie, &params);
8670 return 0;
8671}
8672
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308673#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8674static int wlan_hdd_cfg80211_get_key(
8675 struct wiphy *wiphy,
8676 struct net_device *ndev,
8677 u8 key_index, bool pairwise,
8678 const u8 *mac_addr, void *cookie,
8679 void (*callback)(void *cookie, struct key_params*)
8680 )
8681#else
8682static int wlan_hdd_cfg80211_get_key(
8683 struct wiphy *wiphy,
8684 struct net_device *ndev,
8685 u8 key_index, const u8 *mac_addr, void *cookie,
8686 void (*callback)(void *cookie, struct key_params*)
8687 )
8688#endif
8689{
8690 int ret;
8691
8692 vos_ssr_protect(__func__);
8693#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8694 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
8695 mac_addr, cookie, callback);
8696#else
8697 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
8698 callback);
8699#endif
8700 vos_ssr_unprotect(__func__);
8701
8702 return ret;
8703}
8704
Jeff Johnson295189b2012-06-20 16:38:30 -07008705/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308706 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008707 * This function is used to delete the key information
8708 */
8709#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308710static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008711 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308712 u8 key_index,
8713 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008714 const u8 *mac_addr
8715 )
8716#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308717static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008718 struct net_device *ndev,
8719 u8 key_index,
8720 const u8 *mac_addr
8721 )
8722#endif
8723{
8724 int status = 0;
8725
8726 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308727 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07008728 //it is observed that this is invalidating peer
8729 //key index whenever re-key is done. This is affecting data link.
8730 //It should be ok to ignore del_key.
8731#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308732 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
8733 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008734 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
8735 tCsrRoamSetKey setKey;
8736 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308737
Jeff Johnson295189b2012-06-20 16:38:30 -07008738 ENTER();
8739
8740 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
8741 __func__,pAdapter->device_mode);
8742
8743 if (CSR_MAX_NUM_KEY <= key_index)
8744 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308745 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008746 key_index);
8747
8748 return -EINVAL;
8749 }
8750
8751 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8752 setKey.keyId = key_index;
8753
8754 if (mac_addr)
8755 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8756 else
8757 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
8758
8759 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
8760
8761 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008762 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308763 )
8764 {
8765
8766 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07008767 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8768 if( pHostapdState->bssState == BSS_START)
8769 {
8770 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308771
Jeff Johnson295189b2012-06-20 16:38:30 -07008772 if ( status != eHAL_STATUS_SUCCESS )
8773 {
8774 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8775 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8776 __LINE__, status );
8777 }
8778 }
8779 }
8780 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308781 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07008782 )
8783 {
8784 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8785
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308786 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8787
8788 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008789 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308790 __func__, setKey.peerMac[0], setKey.peerMac[1],
8791 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07008792 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308793 if(pAdapter->sessionCtx.station.conn_info.connState ==
8794 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07008795 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308796 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008797 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308798
Jeff Johnson295189b2012-06-20 16:38:30 -07008799 if ( 0 != status )
8800 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308801 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008802 "%s: sme_RoamSetKey failure, returned %d",
8803 __func__, status);
8804 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8805 return -EINVAL;
8806 }
8807 }
8808 }
8809#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008810 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008811 return status;
8812}
8813
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308814#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8815static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
8816 struct net_device *ndev,
8817 u8 key_index,
8818 bool pairwise,
8819 const u8 *mac_addr
8820 )
8821#else
8822static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
8823 struct net_device *ndev,
8824 u8 key_index,
8825 const u8 *mac_addr
8826 )
8827#endif
8828{
8829 int ret;
8830
8831 vos_ssr_protect(__func__);
8832#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8833 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
8834 mac_addr);
8835#else
8836 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
8837#endif
8838 vos_ssr_unprotect(__func__);
8839
8840 return ret;
8841}
8842
Jeff Johnson295189b2012-06-20 16:38:30 -07008843/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308844 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008845 * This function is used to set the default tx key index
8846 */
8847#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308848static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008849 struct net_device *ndev,
8850 u8 key_index,
8851 bool unicast, bool multicast)
8852#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308853static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008854 struct net_device *ndev,
8855 u8 key_index)
8856#endif
8857{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308858 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308859 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308860 hdd_wext_state_t *pWextState;
8861 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308862 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008863
8864 ENTER();
8865
Gopichand Nakkala29149562013-05-10 21:43:41 +05308866 if ((NULL == pAdapter))
8867 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308869 "invalid adapter");
8870 return -EINVAL;
8871 }
8872
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308873 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8874 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
8875 pAdapter->sessionId, key_index));
8876
Gopichand Nakkala29149562013-05-10 21:43:41 +05308877 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8878 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8879
8880 if ((NULL == pWextState) || (NULL == pHddStaCtx))
8881 {
8882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8883 "invalid Wext state or HDD context");
8884 return -EINVAL;
8885 }
8886
Arif Hussain6d2a3322013-11-17 19:50:10 -08008887 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008888 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308889
Jeff Johnson295189b2012-06-20 16:38:30 -07008890 if (CSR_MAX_NUM_KEY <= key_index)
8891 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308892 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008893 key_index);
8894
8895 return -EINVAL;
8896 }
8897
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308898 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8899 status = wlan_hdd_validate_context(pHddCtx);
8900
8901 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008902 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8904 "%s: HDD context is not valid", __func__);
8905 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008906 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308907
Jeff Johnson295189b2012-06-20 16:38:30 -07008908 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008909 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308910 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008911 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308912 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08008913 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308914 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08008915 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07008916 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308917 {
8918 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07008919 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308920
Jeff Johnson295189b2012-06-20 16:38:30 -07008921 tCsrRoamSetKey setKey;
8922 v_U32_t roamId= 0xFF;
8923 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308924
8925 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008926 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308927
Jeff Johnson295189b2012-06-20 16:38:30 -07008928 Keys->defaultIndex = (u8)key_index;
8929 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8930 setKey.keyId = key_index;
8931 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308932
8933 vos_mem_copy(&setKey.Key[0],
8934 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008935 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308936
Gopichand Nakkala29149562013-05-10 21:43:41 +05308937 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308938
8939 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07008940 &pHddStaCtx->conn_info.bssId[0],
8941 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308942
Gopichand Nakkala29149562013-05-10 21:43:41 +05308943 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
8944 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
8945 eCSR_ENCRYPT_TYPE_WEP104)
8946 {
8947 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
8948 even though ap is configured for WEP-40 encryption. In this canse the key length
8949 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
8950 type(104) and switching encryption type to 40*/
8951 pWextState->roamProfile.EncryptionType.encryptionType[0] =
8952 eCSR_ENCRYPT_TYPE_WEP40;
8953 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
8954 eCSR_ENCRYPT_TYPE_WEP40;
8955 }
8956
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308957 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07008958 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308959
Jeff Johnson295189b2012-06-20 16:38:30 -07008960 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308961 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008962 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308963
Jeff Johnson295189b2012-06-20 16:38:30 -07008964 if ( 0 != status )
8965 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308966 hddLog(VOS_TRACE_LEVEL_ERROR,
8967 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008968 status);
8969 return -EINVAL;
8970 }
8971 }
8972 }
8973
8974 /* In SoftAp mode setting key direction for default mode */
8975 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
8976 {
8977 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
8978 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
8979 (eCSR_ENCRYPT_TYPE_AES !=
8980 pWextState->roamProfile.EncryptionType.encryptionType[0])
8981 )
8982 {
8983 /* Saving key direction for default key index to TX default */
8984 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8985 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
8986 }
8987 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308988
Jeff Johnson295189b2012-06-20 16:38:30 -07008989 return status;
8990}
8991
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308992#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8993static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8994 struct net_device *ndev,
8995 u8 key_index,
8996 bool unicast, bool multicast)
8997#else
8998static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8999 struct net_device *ndev,
9000 u8 key_index)
9001#endif
9002{
9003 int ret;
9004 vos_ssr_protect(__func__);
9005#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9006 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
9007 multicast);
9008#else
9009 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
9010#endif
9011 vos_ssr_unprotect(__func__);
9012
9013 return ret;
9014}
9015
Jeff Johnson295189b2012-06-20 16:38:30 -07009016/*
9017 * FUNCTION: wlan_hdd_cfg80211_inform_bss
9018 * This function is used to inform the BSS details to nl80211 interface.
9019 */
9020static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
9021 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
9022{
9023 struct net_device *dev = pAdapter->dev;
9024 struct wireless_dev *wdev = dev->ieee80211_ptr;
9025 struct wiphy *wiphy = wdev->wiphy;
9026 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
9027 int chan_no;
9028 int ie_length;
9029 const char *ie;
9030 unsigned int freq;
9031 struct ieee80211_channel *chan;
9032 int rssi = 0;
9033 struct cfg80211_bss *bss = NULL;
9034
9035 ENTER();
9036
9037 if( NULL == pBssDesc )
9038 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009039 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009040 return bss;
9041 }
9042
9043 chan_no = pBssDesc->channelId;
9044 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
9045 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
9046
9047 if( NULL == ie )
9048 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009049 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009050 return bss;
9051 }
9052
9053#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9054 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9055 {
9056 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9057 }
9058 else
9059 {
9060 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9061 }
9062#else
9063 freq = ieee80211_channel_to_frequency(chan_no);
9064#endif
9065
9066 chan = __ieee80211_get_channel(wiphy, freq);
9067
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05309068 if (!chan) {
9069 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
9070 return NULL;
9071 }
9072
Abhishek Singhaee43942014-06-16 18:55:47 +05309073 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07009074
Abhishek Singhaee43942014-06-16 18:55:47 +05309075 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309076 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07009077 pBssDesc->capabilityInfo,
9078 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05309079 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07009080}
9081
9082
9083
9084/*
9085 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
9086 * This function is used to inform the BSS details to nl80211 interface.
9087 */
9088struct cfg80211_bss*
9089wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
9090 tSirBssDescription *bss_desc
9091 )
9092{
9093 /*
9094 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
9095 already exists in bss data base of cfg80211 for that particular BSS ID.
9096 Using cfg80211_inform_bss_frame to update the bss entry instead of
9097 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
9098 now there is no possibility to get the mgmt(probe response) frame from PE,
9099 converting bss_desc to ieee80211_mgmt(probe response) and passing to
9100 cfg80211_inform_bss_frame.
9101 */
9102 struct net_device *dev = pAdapter->dev;
9103 struct wireless_dev *wdev = dev->ieee80211_ptr;
9104 struct wiphy *wiphy = wdev->wiphy;
9105 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009106#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9107 qcom_ie_age *qie_age = NULL;
9108 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
9109#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009110 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009111#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009112 const char *ie =
9113 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
9114 unsigned int freq;
9115 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309116 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009117 struct cfg80211_bss *bss_status = NULL;
9118 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
9119 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07009120 hdd_context_t *pHddCtx;
9121 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07009122#ifdef WLAN_OPEN_SOURCE
9123 struct timespec ts;
9124#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009125
Wilson Yangf80a0542013-10-07 13:02:37 -07009126 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9127 status = wlan_hdd_validate_context(pHddCtx);
9128
9129 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309130 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009131 {
9132 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9133 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9134 return NULL;
9135 }
9136
9137
9138 if (0 != status)
9139 {
9140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9141 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009142 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009143 }
9144
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309145 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07009146 if (!mgmt)
9147 {
9148 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9149 "%s: memory allocation failed ", __func__);
9150 return NULL;
9151 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009152
Jeff Johnson295189b2012-06-20 16:38:30 -07009153 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07009154
9155#ifdef WLAN_OPEN_SOURCE
9156 /* Android does not want the timestamp from the frame.
9157 Instead it wants a monotonic increasing value */
9158 get_monotonic_boottime(&ts);
9159 mgmt->u.probe_resp.timestamp =
9160 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
9161#else
9162 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009163 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
9164 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07009165
9166#endif
9167
Jeff Johnson295189b2012-06-20 16:38:30 -07009168 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
9169 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009170
9171#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9172 /* GPS Requirement: need age ie per entry. Using vendor specific. */
9173 /* Assuming this is the last IE, copy at the end */
9174 ie_length -=sizeof(qcom_ie_age);
9175 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
9176 qie_age->element_id = QCOM_VENDOR_IE_ID;
9177 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
9178 qie_age->oui_1 = QCOM_OUI1;
9179 qie_age->oui_2 = QCOM_OUI2;
9180 qie_age->oui_3 = QCOM_OUI3;
9181 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
9182 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
9183#endif
9184
Jeff Johnson295189b2012-06-20 16:38:30 -07009185 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05309186 if (bss_desc->fProbeRsp)
9187 {
9188 mgmt->frame_control |=
9189 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
9190 }
9191 else
9192 {
9193 mgmt->frame_control |=
9194 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
9195 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009196
9197#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309198 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009199 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
9200 {
9201 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9202 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309203 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009204 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
9205
9206 {
9207 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9208 }
9209 else
9210 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309211 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
9212 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07009213 kfree(mgmt);
9214 return NULL;
9215 }
9216#else
9217 freq = ieee80211_channel_to_frequency(chan_no);
9218#endif
9219 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009220 /*when the band is changed on the fly using the GUI, three things are done
9221 * 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)
9222 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
9223 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
9224 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
9225 * and discards the channels correponding to previous band and calls back with zero bss results.
9226 * 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
9227 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
9228 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
9229 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
9230 * So drop the bss and continue to next bss.
9231 */
9232 if(chan == NULL)
9233 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309234 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07009235 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009236 return NULL;
9237 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009238 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309239 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07009240 * */
9241 if (( eConnectionState_Associated ==
9242 pAdapter->sessionCtx.station.conn_info.connState ) &&
9243 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
9244 pAdapter->sessionCtx.station.conn_info.bssId,
9245 WNI_CFG_BSSID_LEN)))
9246 {
9247 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
9248 rssi = (pAdapter->rssi * 100);
9249 }
9250 else
9251 {
9252 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
9253 }
9254
Nirav Shah20ac06f2013-12-12 18:14:06 +05309255 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
9256 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
9257 chan->center_freq, (int)(rssi/100));
9258
Jeff Johnson295189b2012-06-20 16:38:30 -07009259 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
9260 frame_len, rssi, GFP_KERNEL);
9261 kfree(mgmt);
9262 return bss_status;
9263}
9264
9265/*
9266 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
9267 * This function is used to update the BSS data base of CFG8011
9268 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309269struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009270 tCsrRoamInfo *pRoamInfo
9271 )
9272{
9273 tCsrRoamConnectedProfile roamProfile;
9274 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9275 struct cfg80211_bss *bss = NULL;
9276
9277 ENTER();
9278
9279 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
9280 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
9281
9282 if (NULL != roamProfile.pBssDesc)
9283 {
Girish Gowlif4b68022014-08-28 23:18:57 +05309284 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9285 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009286
9287 if (NULL == bss)
9288 {
9289 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
9290 __func__);
9291 }
9292
9293 sme_RoamFreeConnectProfile(hHal, &roamProfile);
9294 }
9295 else
9296 {
9297 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
9298 __func__);
9299 }
9300 return bss;
9301}
9302
9303/*
9304 * FUNCTION: wlan_hdd_cfg80211_update_bss
9305 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309306static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
9307 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07009308 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309309{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309310 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009311 tCsrScanResultInfo *pScanResult;
9312 eHalStatus status = 0;
9313 tScanResultHandle pResult;
9314 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009315 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009316
9317 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309318
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309319 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9320 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
9321 NO_SESSION, pAdapter->sessionId));
9322
Wilson Yangf80a0542013-10-07 13:02:37 -07009323 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9324
9325 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009326 {
Wilson Yangf80a0542013-10-07 13:02:37 -07009327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9328 "%s:LOGP in Progress. Ignore!!!",__func__);
9329 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009330 }
9331
Wilson Yangf80a0542013-10-07 13:02:37 -07009332
9333 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309334 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009335 {
9336 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9337 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9338 return VOS_STATUS_E_PERM;
9339 }
9340
9341
Jeff Johnson295189b2012-06-20 16:38:30 -07009342 /*
9343 * start getting scan results and populate cgf80211 BSS database
9344 */
9345 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
9346
9347 /* no scan results */
9348 if (NULL == pResult)
9349 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309350 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
9351 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009352 return status;
9353 }
9354
9355 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
9356
9357 while (pScanResult)
9358 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309359 /*
9360 * cfg80211_inform_bss() is not updating ie field of bss entry, if
9361 * entry already exists in bss data base of cfg80211 for that
9362 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
9363 * bss entry instead of cfg80211_inform_bss, But this call expects
9364 * mgmt packet as input. As of now there is no possibility to get
9365 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07009366 * ieee80211_mgmt(probe response) and passing to c
9367 * fg80211_inform_bss_frame.
9368 * */
9369
9370 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9371 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309372
Jeff Johnson295189b2012-06-20 16:38:30 -07009373
9374 if (NULL == bss_status)
9375 {
9376 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009377 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009378 }
9379 else
9380 {
Yue Maf49ba872013-08-19 12:04:25 -07009381 cfg80211_put_bss(
9382#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
9383 wiphy,
9384#endif
9385 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009386 }
9387
9388 pScanResult = sme_ScanResultGetNext(hHal, pResult);
9389 }
9390
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309391 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07009392
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309393 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009394}
9395
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009396void
9397hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
9398{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309399 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08009400 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009401} /****** end hddPrintMacAddr() ******/
9402
9403void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009404hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009405{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309406 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009407 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009408 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
9409 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
9410 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009411} /****** end hddPrintPmkId() ******/
9412
9413//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
9414//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
9415
9416//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
9417//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
9418
9419#define dump_bssid(bssid) \
9420 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009421 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
9422 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009423 }
9424
9425#define dump_pmkid(pMac, pmkid) \
9426 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009427 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
9428 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009429 }
9430
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009431#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009432/*
9433 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
9434 * This function is used to notify the supplicant of a new PMKSA candidate.
9435 */
9436int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309437 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009438 int index, bool preauth )
9439{
Jeff Johnsone7245742012-09-05 17:12:55 -07009440#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009441 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009442 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009443
9444 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07009445 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009446
9447 if( NULL == pRoamInfo )
9448 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009449 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009450 return -EINVAL;
9451 }
9452
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009453 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
9454 {
9455 dump_bssid(pRoamInfo->bssid);
9456 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009457 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009458 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009459#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309460 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009461}
9462#endif //FEATURE_WLAN_LFR
9463
Yue Maef608272013-04-08 23:09:17 -07009464#ifdef FEATURE_WLAN_LFR_METRICS
9465/*
9466 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
9467 * 802.11r/LFR metrics reporting function to report preauth initiation
9468 *
9469 */
9470#define MAX_LFR_METRICS_EVENT_LENGTH 100
9471VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
9472 tCsrRoamInfo *pRoamInfo)
9473{
9474 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9475 union iwreq_data wrqu;
9476
9477 ENTER();
9478
9479 if (NULL == pAdapter)
9480 {
9481 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9482 return VOS_STATUS_E_FAILURE;
9483 }
9484
9485 /* create the event */
9486 memset(&wrqu, 0, sizeof(wrqu));
9487 memset(metrics_notification, 0, sizeof(metrics_notification));
9488
9489 wrqu.data.pointer = metrics_notification;
9490 wrqu.data.length = scnprintf(metrics_notification,
9491 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
9492 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9493
9494 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9495
9496 EXIT();
9497
9498 return VOS_STATUS_SUCCESS;
9499}
9500
9501/*
9502 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
9503 * 802.11r/LFR metrics reporting function to report preauth completion
9504 * or failure
9505 */
9506VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
9507 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
9508{
9509 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9510 union iwreq_data wrqu;
9511
9512 ENTER();
9513
9514 if (NULL == pAdapter)
9515 {
9516 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9517 return VOS_STATUS_E_FAILURE;
9518 }
9519
9520 /* create the event */
9521 memset(&wrqu, 0, sizeof(wrqu));
9522 memset(metrics_notification, 0, sizeof(metrics_notification));
9523
9524 scnprintf(metrics_notification, sizeof(metrics_notification),
9525 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
9526 MAC_ADDR_ARRAY(pRoamInfo->bssid));
9527
9528 if (1 == preauth_status)
9529 strncat(metrics_notification, " TRUE", 5);
9530 else
9531 strncat(metrics_notification, " FALSE", 6);
9532
9533 wrqu.data.pointer = metrics_notification;
9534 wrqu.data.length = strlen(metrics_notification);
9535
9536 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9537
9538 EXIT();
9539
9540 return VOS_STATUS_SUCCESS;
9541}
9542
9543/*
9544 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
9545 * 802.11r/LFR metrics reporting function to report handover initiation
9546 *
9547 */
9548VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
9549 tCsrRoamInfo *pRoamInfo)
9550{
9551 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9552 union iwreq_data wrqu;
9553
9554 ENTER();
9555
9556 if (NULL == pAdapter)
9557 {
9558 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9559 return VOS_STATUS_E_FAILURE;
9560 }
9561
9562 /* create the event */
9563 memset(&wrqu, 0, sizeof(wrqu));
9564 memset(metrics_notification, 0, sizeof(metrics_notification));
9565
9566 wrqu.data.pointer = metrics_notification;
9567 wrqu.data.length = scnprintf(metrics_notification,
9568 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
9569 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9570
9571 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9572
9573 EXIT();
9574
9575 return VOS_STATUS_SUCCESS;
9576}
9577#endif
9578
Jeff Johnson295189b2012-06-20 16:38:30 -07009579/*
9580 * FUNCTION: hdd_cfg80211_scan_done_callback
9581 * scanning callback function, called after finishing scan
9582 *
9583 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309584static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07009585 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
9586{
9587 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309588 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009589 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009590 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9591 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07009592 struct cfg80211_scan_request *req = NULL;
9593 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309594 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309595 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +05309596 tANI_U8 i;
Jeff Johnson295189b2012-06-20 16:38:30 -07009597
9598 ENTER();
9599
9600 hddLog(VOS_TRACE_LEVEL_INFO,
9601 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08009602 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009603 __func__, halHandle, pContext, (int) scanId, (int) status);
9604
Kiet Lamac06e2c2013-10-23 16:25:07 +05309605 pScanInfo->mScanPendingCounter = 0;
9606
Jeff Johnson295189b2012-06-20 16:38:30 -07009607 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309608 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009609 &pScanInfo->scan_req_completion_event,
9610 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309611 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009612 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309613 hddLog(VOS_TRACE_LEVEL_ERROR,
9614 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07009615 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009616 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009617 }
9618
Yue Maef608272013-04-08 23:09:17 -07009619 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07009620 {
9621 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009622 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009623 }
9624
9625 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309626 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07009627 {
9628 hddLog(VOS_TRACE_LEVEL_INFO,
9629 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009630 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07009631 (int) scanId);
9632 }
9633
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309634 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009635 pAdapter);
9636
9637 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309638 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009639
9640
9641 /* If any client wait scan result through WEXT
9642 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009643 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07009644 {
9645 /* The other scan request waiting for current scan finish
9646 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009647 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009648 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009649 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07009650 }
9651 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009652 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009653 {
9654 struct net_device *dev = pAdapter->dev;
9655 union iwreq_data wrqu;
9656 int we_event;
9657 char *msg;
9658
9659 memset(&wrqu, '\0', sizeof(wrqu));
9660 we_event = SIOCGIWSCAN;
9661 msg = NULL;
9662 wireless_send_event(dev, we_event, &wrqu, msg);
9663 }
9664 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009665 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009666
9667 /* Get the Scan Req */
9668 req = pAdapter->request;
9669
9670 if (!req)
9671 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009672 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009673 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07009674 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009675 }
9676
Jeff Johnson295189b2012-06-20 16:38:30 -07009677 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009678 /* Scan is no longer pending */
9679 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009680
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +05309681 /* last_scan_timestamp is used to decide if new scan
9682 * is needed or not on station interface. If last station
9683 * scan time and new station scan time is less then
9684 * last_scan_timestamp ; driver will return cached scan.
9685 */
9686 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
9687 {
9688 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
9689
9690 if ( req->n_channels )
9691 {
9692 for (i = 0; i < req->n_channels ; i++ )
9693 {
9694 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
9695 }
9696 /* store no of channel scanned */
9697 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
9698 }
9699
9700 }
9701
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07009702 /*
9703 * cfg80211_scan_done informing NL80211 about completion
9704 * of scanning
9705 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309706 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
9707 {
9708 aborted = true;
9709 }
9710 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009711 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07009712
Siddharth Bhal76972212014-10-15 16:22:51 +05309713 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
9714 /* Generate new random mac addr for next scan */
9715 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
9716 hdd_processSpoofMacAddrRequest(pHddCtx);
9717 }
9718
Jeff Johnsone7245742012-09-05 17:12:55 -07009719allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009720 /* release the wake lock at the end of the scan*/
9721 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009722
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009723 /* Acquire wakelock to handle the case where APP's tries to suspend
9724 * immediatly after the driver gets connect request(i.e after scan)
9725 * from supplicant, this result in app's is suspending and not able
9726 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309727 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009728
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009729#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05309730 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
9731 {
9732 wlan_hdd_tdls_scan_done_callback(pAdapter);
9733 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009734#endif
9735
Jeff Johnson295189b2012-06-20 16:38:30 -07009736 EXIT();
9737 return 0;
9738}
9739
9740/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05309741 * FUNCTION: hdd_isConnectionInProgress
9742 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009743 *
9744 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +05309745v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009746{
9747 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9748 hdd_station_ctx_t *pHddStaCtx = NULL;
9749 hdd_adapter_t *pAdapter = NULL;
9750 VOS_STATUS status = 0;
9751 v_U8_t staId = 0;
9752 v_U8_t *staMac = NULL;
9753
c_hpothu9b781ba2013-12-30 20:57:45 +05309754 if (TRUE == pHddCtx->btCoexModeSet)
9755 {
9756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05309757 FL("BTCoex Mode operation in progress"));
9758 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05309759 }
9760
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009761 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9762
9763 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9764 {
9765 pAdapter = pAdapterNode->pAdapter;
9766
9767 if( pAdapter )
9768 {
9769 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309770 "%s: Adapter with device mode %s (%d) exists",
9771 __func__, hdd_device_modetoString(pAdapter->device_mode),
9772 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +05309773 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +05309774 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9775 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
9776 (eConnectionState_Connecting ==
9777 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
9778 {
9779 hddLog(VOS_TRACE_LEVEL_ERROR,
9780 "%s: %p(%d) Connection is in progress", __func__,
9781 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
9782 return VOS_TRUE;
9783 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +05309784 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
9785 smeNeighborRoamIsHandoffInProgress(WLAN_HDD_GET_HAL_CTX(pAdapter)))
9786 {
9787 hddLog(VOS_TRACE_LEVEL_ERROR,
9788 "%s: %p(%d) Reassociation is in progress", __func__,
9789 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
9790 return VOS_TRUE;
9791 }
9792 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309793 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9794 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009795 {
9796 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9797 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309798 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009799 {
9800 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
9801 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009802 "%s: client " MAC_ADDRESS_STR
9803 " is in the middle of WPS/EAPOL exchange.", __func__,
9804 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309805 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009806 }
9807 }
9808 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
9809 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
9810 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05309811 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9812 ptSapContext pSapCtx = NULL;
9813 pSapCtx = VOS_GET_SAP_CB(pVosContext);
9814 if(pSapCtx == NULL){
9815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9816 FL("psapCtx is NULL"));
9817 return VOS_FALSE;
9818 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009819 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
9820 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05309821 if ((pSapCtx->aStaInfo[staId].isUsed) &&
9822 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009823 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05309824 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009825
9826 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009827 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
9828 "middle of WPS/EAPOL exchange.", __func__,
9829 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309830 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009831 }
9832 }
9833 }
9834 }
9835 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9836 pAdapterNode = pNext;
9837 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05309838 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309839}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009840
9841/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309842 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07009843 * this scan respond to scan trigger and update cfg80211 scan database
9844 * later, scan dump command can be used to recieve scan results
9845 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309846int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009847#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9848 struct net_device *dev,
9849#endif
9850 struct cfg80211_scan_request *request)
9851{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309852 hdd_adapter_t *pAdapter = NULL;
9853 hdd_context_t *pHddCtx = NULL;
9854 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309855 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009856 tCsrScanRequest scanRequest;
9857 tANI_U8 *channelList = NULL, i;
9858 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309859 int status;
9860 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009861 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +05309862 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009863
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309864#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
9865 struct net_device *dev = NULL;
9866 if (NULL == request)
9867 {
9868 hddLog(VOS_TRACE_LEVEL_ERROR,
9869 "%s: scan req param null", __func__);
9870 return -EINVAL;
9871 }
9872 dev = request->wdev->netdev;
9873#endif
9874
9875 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
9876 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9877 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9878
Jeff Johnson295189b2012-06-20 16:38:30 -07009879 ENTER();
9880
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309881
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309882 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9883 __func__, hdd_device_modetoString(pAdapter->device_mode),
9884 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309885
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309886 status = wlan_hdd_validate_context(pHddCtx);
9887
9888 if (0 != status)
9889 {
9890 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9891 "%s: HDD context is not valid", __func__);
9892 return status;
9893 }
9894
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309895 if (NULL == pwextBuf)
9896 {
9897 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
9898 __func__);
9899 return -EIO;
9900 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309901 cfg_param = pHddCtx->cfg_ini;
9902 pScanInfo = &pHddCtx->scan_info;
9903
Jeff Johnson295189b2012-06-20 16:38:30 -07009904#ifdef WLAN_BTAMP_FEATURE
9905 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009906 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07009907 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009908 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009909 "%s: No scanning when AMP is on", __func__);
9910 return -EOPNOTSUPP;
9911 }
9912#endif
9913 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009914 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009915 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009916 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309917 "%s: Not scanning on device_mode = %s (%d)",
9918 __func__, hdd_device_modetoString(pAdapter->device_mode),
9919 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009920 return -EOPNOTSUPP;
9921 }
9922
9923 if (TRUE == pScanInfo->mScanPending)
9924 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309925 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
9926 {
9927 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
9928 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009929 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009930 }
9931
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309932 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07009933 //Channel and action frame is pending
9934 //Otherwise Cancel Remain On Channel and allow Scan
9935 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009936 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07009937 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309938 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009939 return -EBUSY;
9940 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009941#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009942 /* if tdls disagree scan right now, return immediately.
9943 tdls will schedule the scan when scan is allowed. (return SUCCESS)
9944 or will reject the scan if any TDLS is in progress. (return -EBUSY)
9945 */
9946 status = wlan_hdd_tdls_scan_callback (pAdapter,
9947 wiphy,
9948#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9949 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07009950#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009951 request);
9952 if(status <= 0)
9953 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309954 if(!status)
9955 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
9956 "scan rejected %d", __func__, status);
9957 else
9958 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
9959 __func__, status);
9960
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009961 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009962 }
9963#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07009964
Jeff Johnson295189b2012-06-20 16:38:30 -07009965 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
9966 {
9967 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08009968 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009969 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309970 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009971 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
9972 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309973 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009974 "%s: MAX TM Level Scan not allowed", __func__);
9975 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309976 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009977 }
9978 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
9979
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009980 /* Check if scan is allowed at this point of time.
9981 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +05309982 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009983 {
9984 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
9985 return -EBUSY;
9986 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309987
Jeff Johnson295189b2012-06-20 16:38:30 -07009988 vos_mem_zero( &scanRequest, sizeof(scanRequest));
9989
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309990 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
9991 (int)request->n_ssids);
9992
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +05309993
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309994 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
9995 * Becasue of this, driver is assuming that this is not wildcard scan and so
9996 * is not aging out the scan results.
9997 */
9998 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07009999 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010000 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010001 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010002
10003 if ((request->ssids) && (0 < request->n_ssids))
10004 {
10005 tCsrSSIDInfo *SsidInfo;
10006 int j;
10007 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
10008 /* Allocate num_ssid tCsrSSIDInfo structure */
10009 SsidInfo = scanRequest.SSIDs.SSIDList =
10010 ( tCsrSSIDInfo *)vos_mem_malloc(
10011 request->n_ssids*sizeof(tCsrSSIDInfo));
10012
10013 if(NULL == scanRequest.SSIDs.SSIDList)
10014 {
10015 hddLog(VOS_TRACE_LEVEL_ERROR,
10016 "%s: memory alloc failed SSIDInfo buffer", __func__);
10017 return -ENOMEM;
10018 }
10019
10020 /* copy all the ssid's and their length */
10021 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
10022 {
10023 /* get the ssid length */
10024 SsidInfo->SSID.length = request->ssids[j].ssid_len;
10025 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
10026 SsidInfo->SSID.length);
10027 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
10028 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
10029 j, SsidInfo->SSID.ssId);
10030 }
10031 /* set the scan type to active */
10032 scanRequest.scanType = eSIR_ACTIVE_SCAN;
10033 }
10034 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070010035 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010036 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10037 TRACE_CODE_HDD_CFG80211_SCAN,
10038 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070010039 /* set the scan type to active */
10040 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010041 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010042 else
10043 {
10044 /*Set the scan type to default type, in this case it is ACTIVE*/
10045 scanRequest.scanType = pScanInfo->scan_mode;
10046 }
10047 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
10048 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070010049
10050 /* set BSSType to default type */
10051 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
10052
10053 /*TODO: scan the requested channels only*/
10054
10055 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010056 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070010057 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010058 hddLog(VOS_TRACE_LEVEL_WARN,
10059 "No of Scan Channels exceeded limit: %d", request->n_channels);
10060 request->n_channels = MAX_CHANNEL;
10061 }
10062
10063 hddLog(VOS_TRACE_LEVEL_INFO,
10064 "No of Scan Channels: %d", request->n_channels);
10065
10066
10067 if( request->n_channels )
10068 {
10069 char chList [(request->n_channels*5)+1];
10070 int len;
10071 channelList = vos_mem_malloc( request->n_channels );
10072 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053010073 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010074 hddLog(VOS_TRACE_LEVEL_ERROR,
10075 "%s: memory alloc failed channelList", __func__);
10076 status = -ENOMEM;
10077 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053010078 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010079
10080 for( i = 0, len = 0; i < request->n_channels ; i++ )
10081 {
10082 channelList[i] = request->channels[i]->hw_value;
10083 len += snprintf(chList+len, 5, "%d ", channelList[i]);
10084 }
10085
Nirav Shah20ac06f2013-12-12 18:14:06 +053010086 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010087 "Channel-List: %s ", chList);
10088 }
c_hpothu53512302014-04-15 18:49:53 +053010089
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010090 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
10091 scanRequest.ChannelInfo.ChannelList = channelList;
10092
10093 /* set requestType to full scan */
10094 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10095
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010096 /* if there is back to back scan happening in driver with in
10097 * nDeferScanTimeInterval interval driver should defer new scan request
10098 * and should provide last cached scan results instead of new channel list.
10099 * This rule is not applicable if scan is p2p scan.
10100 * This condition will work only in case when last request no of channels
10101 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053010102 * This should be done only in connected state
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010103 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010104
Agarwal Ashish57e84372014-12-05 18:26:53 +053010105 if ((VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
10106 {
10107 if ( pScanInfo->last_scan_timestamp !=0 &&
10108 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
10109 {
10110 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
10111 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
10112 vos_mem_compare(pScanInfo->last_scan_channelList,
10113 channelList, pScanInfo->last_scan_numChannels))
10114 {
10115 hddLog(VOS_TRACE_LEVEL_WARN,
10116 " New and old station scan time differ is less then %u",
10117 pHddCtx->cfg_ini->nDeferScanTimeInterval);
10118
10119 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010120 pAdapter);
10121
Agarwal Ashish57e84372014-12-05 18:26:53 +053010122 hddLog(VOS_TRACE_LEVEL_WARN,
10123 "Return old cached scan as all channels"
10124 "and no of channles are same");
10125 if (0 > ret)
10126 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010127
Agarwal Ashish57e84372014-12-05 18:26:53 +053010128 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
10129 return eHAL_STATUS_SUCCESS ;
10130 }
10131 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010132 }
10133
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010134 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10135 * search (Flush on both full scan and social scan but not on single
10136 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10137 */
10138
10139 /* Supplicant does single channel scan after 8-way handshake
10140 * and in that case driver shoudnt flush scan results. If
10141 * driver flushes the scan results here and unfortunately if
10142 * the AP doesnt respond to our probe req then association
10143 * fails which is not desired
10144 */
10145
10146 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
10147 {
10148 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
10149 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
10150 pAdapter->sessionId );
10151 }
10152
10153 if( request->ie_len )
10154 {
10155 /* save this for future association (join requires this) */
10156 /*TODO: Array needs to be converted to dynamic allocation,
10157 * as multiple ie.s can be sent in cfg80211_scan_request structure
10158 * CR 597966
10159 */
10160 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
10161 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
10162 pScanInfo->scanAddIE.length = request->ie_len;
10163
10164 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10165 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10166 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010167 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010168 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070010169 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010170 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
10171 memcpy( pwextBuf->roamProfile.addIEScan,
10172 request->ie, request->ie_len);
10173 }
10174 else
10175 {
10176 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
10177 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070010178 }
10179
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010180 }
10181 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
10182 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
10183
10184 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
10185 request->ie_len);
10186 if (pP2pIe != NULL)
10187 {
10188#ifdef WLAN_FEATURE_P2P_DEBUG
10189 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
10190 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
10191 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053010192 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010193 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
10194 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10195 "Go nego completed to Connection is started");
10196 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10197 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053010198 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010199 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
10200 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010201 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010202 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
10203 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10204 "Disconnected state to Connection is started");
10205 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10206 "for 4way Handshake");
10207 }
10208#endif
10209
10210 /* no_cck will be set during p2p find to disable 11b rates */
10211 if(TRUE == request->no_cck)
10212 {
10213 hddLog(VOS_TRACE_LEVEL_INFO,
10214 "%s: This is a P2P Search", __func__);
10215 scanRequest.p2pSearch = 1;
10216
10217 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053010218 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010219 /* set requestType to P2P Discovery */
10220 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
10221 }
10222
10223 /*
10224 Skip Dfs Channel in case of P2P Search
10225 if it is set in ini file
10226 */
10227 if(cfg_param->skipDfsChnlInP2pSearch)
10228 {
10229 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010230 }
10231 else
10232 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010233 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010234 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010235
Agarwal Ashish4f616132013-12-30 23:32:50 +053010236 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010237 }
10238 }
10239
10240 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
10241
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010242 /* acquire the wakelock to avoid the apps suspend during the scan. To
10243 * address the following issues.
10244 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
10245 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
10246 * for long time, this result in apps running at full power for long time.
10247 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
10248 * be stuck in full power because of resume BMPS
10249 */
10250 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -070010251
Nirav Shah20ac06f2013-12-12 18:14:06 +053010252 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10253 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010254 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
10255 scanRequest.requestType, scanRequest.scanType,
10256 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053010257 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
10258
Siddharth Bhal76972212014-10-15 16:22:51 +053010259 if (pHddCtx->spoofMacAddr.isEnabled)
10260 {
10261 hddLog(VOS_TRACE_LEVEL_INFO,
10262 "%s: MAC Spoofing enabled for current scan", __func__);
10263 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
10264 * to fill TxBds for probe request during current scan
10265 */
10266 WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
10267 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
10268 }
10269
Jeff Johnsone7245742012-09-05 17:12:55 -070010270 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010271 pAdapter->sessionId, &scanRequest, &scanId,
10272 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070010273
Jeff Johnson295189b2012-06-20 16:38:30 -070010274 if (eHAL_STATUS_SUCCESS != status)
10275 {
10276 hddLog(VOS_TRACE_LEVEL_ERROR,
10277 "%s: sme_ScanRequest returned error %d", __func__, status);
10278 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010279 if(eHAL_STATUS_RESOURCES == status)
10280 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010281 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
10282 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010283 status = -EBUSY;
10284 } else {
10285 status = -EIO;
10286 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010287 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -070010288 goto free_mem;
10289 }
10290
10291 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010292 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070010293 pAdapter->request = request;
10294 pScanInfo->scanId = scanId;
10295
10296 complete(&pScanInfo->scan_req_completion_event);
10297
10298free_mem:
10299 if( scanRequest.SSIDs.SSIDList )
10300 {
10301 vos_mem_free(scanRequest.SSIDs.SSIDList);
10302 }
10303
10304 if( channelList )
10305 vos_mem_free( channelList );
10306
10307 EXIT();
10308
10309 return status;
10310}
10311
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010312int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
10313#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10314 struct net_device *dev,
10315#endif
10316 struct cfg80211_scan_request *request)
10317{
10318 int ret;
10319
10320 vos_ssr_protect(__func__);
10321 ret = __wlan_hdd_cfg80211_scan(wiphy,
10322#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10323 dev,
10324#endif
10325 request);
10326 vos_ssr_unprotect(__func__);
10327
10328 return ret;
10329}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010330
10331void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
10332{
10333 v_U8_t iniDot11Mode =
10334 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
10335 eHddDot11Mode hddDot11Mode = iniDot11Mode;
10336
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010337 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
10338 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010339 switch ( iniDot11Mode )
10340 {
10341 case eHDD_DOT11_MODE_AUTO:
10342 case eHDD_DOT11_MODE_11ac:
10343 case eHDD_DOT11_MODE_11ac_ONLY:
10344#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053010345 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
10346 sme_IsFeatureSupportedByFW(DOT11AC) )
10347 hddDot11Mode = eHDD_DOT11_MODE_11ac;
10348 else
10349 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010350#else
10351 hddDot11Mode = eHDD_DOT11_MODE_11n;
10352#endif
10353 break;
10354 case eHDD_DOT11_MODE_11n:
10355 case eHDD_DOT11_MODE_11n_ONLY:
10356 hddDot11Mode = eHDD_DOT11_MODE_11n;
10357 break;
10358 default:
10359 hddDot11Mode = iniDot11Mode;
10360 break;
10361 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010362#ifdef WLAN_FEATURE_AP_HT40_24G
10363 if (operationChannel > SIR_11B_CHANNEL_END)
10364#endif
10365 {
10366 /* This call decides required channel bonding mode */
10367 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010368 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
10369 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010370 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010371}
10372
Jeff Johnson295189b2012-06-20 16:38:30 -070010373/*
10374 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010375 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010376 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010377int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010378 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010379{
10380 int status = 0;
10381 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080010382 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010383 v_U32_t roamId;
10384 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070010385 eCsrAuthType RSNAuthType;
10386
10387 ENTER();
10388
10389 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080010390 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10391
10392 status = wlan_hdd_validate_context(pHddCtx);
10393 if (status)
10394 {
10395 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10396 "%s: HDD context is not valid!", __func__);
10397 return status;
10398 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010399
Jeff Johnson295189b2012-06-20 16:38:30 -070010400 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
10401 {
10402 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
10403 return -EINVAL;
10404 }
10405
10406 pRoamProfile = &pWextState->roamProfile;
10407
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010408 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070010409 {
Jeff Johnsone7245742012-09-05 17:12:55 -070010410 hdd_station_ctx_t *pHddStaCtx;
10411 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010412
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010413 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070010414 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
10415 {
10416 /*QoS not enabled in cfg file*/
10417 pRoamProfile->uapsd_mask = 0;
10418 }
10419 else
10420 {
10421 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010422 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070010423 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
10424 }
10425
10426 pRoamProfile->SSIDs.numOfSSIDs = 1;
10427 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
10428 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010429 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070010430 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
10431 ssid, ssid_len);
10432
10433 if (bssid)
10434 {
10435 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
10436 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
10437 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010438 /* Save BSSID in seperate variable as well, as RoamProfile
10439 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070010440 case of join failure we should send valid BSSID to supplicant
10441 */
10442 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
10443 WNI_CFG_BSSID_LEN);
10444 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070010445 else
10446 {
10447 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
10448 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010449
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010450 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
10451 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010452 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
10453 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010454 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010455 /*set gen ie*/
10456 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
10457 /*set auth*/
10458 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
10459 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010460#ifdef FEATURE_WLAN_WAPI
10461 if (pAdapter->wapi_info.nWapiMode)
10462 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010463 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010464 switch (pAdapter->wapi_info.wapiAuthMode)
10465 {
10466 case WAPI_AUTH_MODE_PSK:
10467 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010468 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010469 pAdapter->wapi_info.wapiAuthMode);
10470 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
10471 break;
10472 }
10473 case WAPI_AUTH_MODE_CERT:
10474 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010475 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010476 pAdapter->wapi_info.wapiAuthMode);
10477 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
10478 break;
10479 }
10480 } // End of switch
10481 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
10482 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
10483 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010484 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010485 pRoamProfile->AuthType.numEntries = 1;
10486 pRoamProfile->EncryptionType.numEntries = 1;
10487 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10488 pRoamProfile->mcEncryptionType.numEntries = 1;
10489 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10490 }
10491 }
10492#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010493#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010494 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010495 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10496 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
10497 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010498 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
10499 sizeof (tSirGtkOffloadParams));
10500 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010501 }
10502#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010503 pRoamProfile->csrPersona = pAdapter->device_mode;
10504
Jeff Johnson32d95a32012-09-10 13:15:23 -070010505 if( operatingChannel )
10506 {
10507 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
10508 pRoamProfile->ChannelInfo.numOfChannels = 1;
10509 }
Chet Lanctot186b5732013-03-18 10:26:30 -070010510 else
10511 {
10512 pRoamProfile->ChannelInfo.ChannelList = NULL;
10513 pRoamProfile->ChannelInfo.numOfChannels = 0;
10514 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010515 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
10516 {
10517 hdd_select_cbmode(pAdapter,operatingChannel);
10518 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010519
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010520 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
10521 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010522 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010523 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010524 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
10525 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010526 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10527 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053010528 {
10529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10530 "%s: Set HDD connState to eConnectionState_Connecting",
10531 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010532 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
10533 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053010534 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010535 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010536 pAdapter->sessionId, pRoamProfile, &roamId);
10537
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010538 if ((eHAL_STATUS_SUCCESS != status) &&
10539 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10540 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010541
10542 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010543 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
10544 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
10545 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010546 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010547 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010548 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010549
10550 pRoamProfile->ChannelInfo.ChannelList = NULL;
10551 pRoamProfile->ChannelInfo.numOfChannels = 0;
10552
Jeff Johnson295189b2012-06-20 16:38:30 -070010553 }
10554 else
10555 {
10556 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
10557 return -EINVAL;
10558 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010559 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010560 return status;
10561}
10562
10563/*
10564 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
10565 * This function is used to set the authentication type (OPEN/SHARED).
10566 *
10567 */
10568static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
10569 enum nl80211_auth_type auth_type)
10570{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010571 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010572 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10573
10574 ENTER();
10575
10576 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010577 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070010578 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010579 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010580 hddLog(VOS_TRACE_LEVEL_INFO,
10581 "%s: set authentication type to AUTOSWITCH", __func__);
10582 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
10583 break;
10584
10585 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010586#ifdef WLAN_FEATURE_VOWIFI_11R
10587 case NL80211_AUTHTYPE_FT:
10588#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010589 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010590 "%s: set authentication type to OPEN", __func__);
10591 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
10592 break;
10593
10594 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010595 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010596 "%s: set authentication type to SHARED", __func__);
10597 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
10598 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010599#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010600 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010601 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010602 "%s: set authentication type to CCKM WPA", __func__);
10603 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
10604 break;
10605#endif
10606
10607
10608 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010609 hddLog(VOS_TRACE_LEVEL_ERROR,
10610 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010611 auth_type);
10612 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
10613 return -EINVAL;
10614 }
10615
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010616 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010617 pHddStaCtx->conn_info.authType;
10618 return 0;
10619}
10620
10621/*
10622 * FUNCTION: wlan_hdd_set_akm_suite
10623 * This function is used to set the key mgmt type(PSK/8021x).
10624 *
10625 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010626static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010627 u32 key_mgmt
10628 )
10629{
10630 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10631 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053010632 /* Should be in ieee802_11_defs.h */
10633#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
10634#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070010635 /*set key mgmt type*/
10636 switch(key_mgmt)
10637 {
10638 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053010639 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010640#ifdef WLAN_FEATURE_VOWIFI_11R
10641 case WLAN_AKM_SUITE_FT_PSK:
10642#endif
10643 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070010644 __func__);
10645 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
10646 break;
10647
10648 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053010649 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010650#ifdef WLAN_FEATURE_VOWIFI_11R
10651 case WLAN_AKM_SUITE_FT_8021X:
10652#endif
10653 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070010654 __func__);
10655 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10656 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010657#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010658#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
10659#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
10660 case WLAN_AKM_SUITE_CCKM:
10661 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
10662 __func__);
10663 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
10664 break;
10665#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070010666#ifndef WLAN_AKM_SUITE_OSEN
10667#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
10668 case WLAN_AKM_SUITE_OSEN:
10669 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
10670 __func__);
10671 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10672 break;
10673#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010674
10675 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010676 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010677 __func__, key_mgmt);
10678 return -EINVAL;
10679
10680 }
10681 return 0;
10682}
10683
10684/*
10685 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010686 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070010687 * (NONE/WEP40/WEP104/TKIP/CCMP).
10688 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010689static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
10690 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070010691 bool ucast
10692 )
10693{
10694 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010695 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010696 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10697
10698 ENTER();
10699
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010700 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010701 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010702 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070010703 __func__, cipher);
10704 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10705 }
10706 else
10707 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010708
Jeff Johnson295189b2012-06-20 16:38:30 -070010709 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010710 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010711 {
10712 case IW_AUTH_CIPHER_NONE:
10713 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10714 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010715
Jeff Johnson295189b2012-06-20 16:38:30 -070010716 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010717 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070010718 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010719
Jeff Johnson295189b2012-06-20 16:38:30 -070010720 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010721 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070010722 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010723
Jeff Johnson295189b2012-06-20 16:38:30 -070010724 case WLAN_CIPHER_SUITE_TKIP:
10725 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
10726 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010727
Jeff Johnson295189b2012-06-20 16:38:30 -070010728 case WLAN_CIPHER_SUITE_CCMP:
10729 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10730 break;
10731#ifdef FEATURE_WLAN_WAPI
10732 case WLAN_CIPHER_SUITE_SMS4:
10733 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
10734 break;
10735#endif
10736
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010737#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010738 case WLAN_CIPHER_SUITE_KRK:
10739 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
10740 break;
10741#endif
10742 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010743 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010744 __func__, cipher);
10745 return -EOPNOTSUPP;
10746 }
10747 }
10748
10749 if (ucast)
10750 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010751 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010752 __func__, encryptionType);
10753 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10754 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010755 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010756 encryptionType;
10757 }
10758 else
10759 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010760 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010761 __func__, encryptionType);
10762 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
10763 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
10764 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
10765 }
10766
10767 return 0;
10768}
10769
10770
10771/*
10772 * FUNCTION: wlan_hdd_cfg80211_set_ie
10773 * This function is used to parse WPA/RSN IE's.
10774 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010775int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
10776 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070010777 size_t ie_len
10778 )
10779{
10780 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10781 u8 *genie = ie;
10782 v_U16_t remLen = ie_len;
10783#ifdef FEATURE_WLAN_WAPI
10784 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
10785 u16 *tmp;
10786 v_U16_t akmsuiteCount;
10787 int *akmlist;
10788#endif
10789 ENTER();
10790
10791 /* clear previous assocAddIE */
10792 pWextState->assocAddIE.length = 0;
10793 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010794 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010795
10796 while (remLen >= 2)
10797 {
10798 v_U16_t eLen = 0;
10799 v_U8_t elementId;
10800 elementId = *genie++;
10801 eLen = *genie++;
10802 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010803
Arif Hussain6d2a3322013-11-17 19:50:10 -080010804 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070010805 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010806
10807 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070010808 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010809 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010810 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 -070010811 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010812 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010813 "%s: Invalid WPA IE", __func__);
10814 return -EINVAL;
10815 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010816 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070010817 {
10818 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010819 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010820 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010821
Jeff Johnson295189b2012-06-20 16:38:30 -070010822 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10823 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010824 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
10825 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010826 VOS_ASSERT(0);
10827 return -ENOMEM;
10828 }
10829 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10830 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10831 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010832
Jeff Johnson295189b2012-06-20 16:38:30 -070010833 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
10834 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10835 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10836 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010837 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
10838 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010839 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
10840 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10841 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
10842 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
10843 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
10844 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010845 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053010846 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010847 {
10848 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010849 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010850 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010851
Jeff Johnson295189b2012-06-20 16:38:30 -070010852 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10853 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010854 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10855 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010856 VOS_ASSERT(0);
10857 return -ENOMEM;
10858 }
10859 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10860 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10861 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010862
Jeff Johnson295189b2012-06-20 16:38:30 -070010863 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10864 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10865 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010866#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010867 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
10868 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010869 /*Consider WFD IE, only for P2P Client */
10870 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10871 {
10872 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010873 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010874 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010875
Jeff Johnson295189b2012-06-20 16:38:30 -070010876 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10877 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010878 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10879 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010880 VOS_ASSERT(0);
10881 return -ENOMEM;
10882 }
10883 // WFD IE is saved to Additional IE ; it should be accumulated to handle
10884 // WPS IE + P2P IE + WFD IE
10885 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10886 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010887
Jeff Johnson295189b2012-06-20 16:38:30 -070010888 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10889 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10890 }
10891#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010892 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010893 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010894 HS20_OUI_TYPE_SIZE)) )
10895 {
10896 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010897 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010898 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010899
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010900 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10901 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010902 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10903 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010904 VOS_ASSERT(0);
10905 return -ENOMEM;
10906 }
10907 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10908 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010909
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010910 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10911 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10912 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010913 /* Appending OSEN Information Element in Assiciation Request */
10914 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
10915 OSEN_OUI_TYPE_SIZE)) )
10916 {
10917 v_U16_t curAddIELen = pWextState->assocAddIE.length;
10918 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
10919 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010920
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010921 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10922 {
10923 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10924 "Need bigger buffer space");
10925 VOS_ASSERT(0);
10926 return -ENOMEM;
10927 }
10928 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10929 pWextState->assocAddIE.length += eLen + 2;
10930
10931 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
10932 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10933 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10934 }
10935
10936 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070010937 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
10938
10939 /* populating as ADDIE in beacon frames */
10940 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10941 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
10942 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
10943 {
10944 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10945 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10946 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10947 {
10948 hddLog(LOGE,
10949 "Coldn't pass "
10950 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
10951 }
10952 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
10953 else
10954 hddLog(LOGE,
10955 "Could not pass on "
10956 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
10957
10958 /* IBSS mode doesn't contain params->proberesp_ies still
10959 beaconIE's need to be populated in probe response frames */
10960 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
10961 {
10962 u16 rem_probe_resp_ie_len = eLen + 2;
10963 u8 probe_rsp_ie_len[3] = {0};
10964 u8 counter = 0;
10965
10966 /* Check Probe Resp Length if it is greater then 255 then
10967 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
10968 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
10969 not able Store More then 255 bytes into One Variable */
10970
10971 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
10972 {
10973 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
10974 {
10975 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
10976 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
10977 }
10978 else
10979 {
10980 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
10981 rem_probe_resp_ie_len = 0;
10982 }
10983 }
10984
10985 rem_probe_resp_ie_len = 0;
10986
10987 if (probe_rsp_ie_len[0] > 0)
10988 {
10989 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10990 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
10991 (tANI_U8*)(genie - 2),
10992 probe_rsp_ie_len[0], NULL,
10993 eANI_BOOLEAN_FALSE)
10994 == eHAL_STATUS_FAILURE)
10995 {
10996 hddLog(LOGE,
10997 "Could not pass"
10998 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
10999 }
11000 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
11001 }
11002
11003 if (probe_rsp_ie_len[1] > 0)
11004 {
11005 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11006 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
11007 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11008 probe_rsp_ie_len[1], NULL,
11009 eANI_BOOLEAN_FALSE)
11010 == eHAL_STATUS_FAILURE)
11011 {
11012 hddLog(LOGE,
11013 "Could not pass"
11014 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
11015 }
11016 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
11017 }
11018
11019 if (probe_rsp_ie_len[2] > 0)
11020 {
11021 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11022 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
11023 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11024 probe_rsp_ie_len[2], NULL,
11025 eANI_BOOLEAN_FALSE)
11026 == eHAL_STATUS_FAILURE)
11027 {
11028 hddLog(LOGE,
11029 "Could not pass"
11030 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
11031 }
11032 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
11033 }
11034
11035 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11036 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
11037 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11038 {
11039 hddLog(LOGE,
11040 "Could not pass"
11041 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
11042 }
11043 }
11044 else
11045 {
11046 // Reset WNI_CFG_PROBE_RSP Flags
11047 wlan_hdd_reset_prob_rspies(pAdapter);
11048
11049 hddLog(VOS_TRACE_LEVEL_INFO,
11050 "%s: No Probe Response IE received in set beacon",
11051 __func__);
11052 }
11053 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011054 break;
11055 case DOT11F_EID_RSN:
11056 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
11057 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11058 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
11059 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
11060 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
11061 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011062 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
11063 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011064 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011065 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011066 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011067 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011068
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011069 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11070 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011071 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11072 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011073 VOS_ASSERT(0);
11074 return -ENOMEM;
11075 }
11076 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11077 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011078
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011079 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11080 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11081 break;
11082 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011083#ifdef FEATURE_WLAN_WAPI
11084 case WLAN_EID_WAPI:
11085 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011086 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011087 pAdapter->wapi_info.nWapiMode);
11088 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011089 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070011090 akmsuiteCount = WPA_GET_LE16(tmp);
11091 tmp = tmp + 1;
11092 akmlist = (int *)(tmp);
11093 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
11094 {
11095 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
11096 }
11097 else
11098 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011099 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070011100 VOS_ASSERT(0);
11101 return -EINVAL;
11102 }
11103
11104 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
11105 {
11106 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011107 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011108 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011109 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011110 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011111 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011112 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011113 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011114 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
11115 }
11116 break;
11117#endif
11118 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011119 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011120 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011121 /* when Unknown IE is received we should break and continue
11122 * to the next IE in the buffer instead we were returning
11123 * so changing this to break */
11124 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011125 }
11126 genie += eLen;
11127 remLen -= eLen;
11128 }
11129 EXIT();
11130 return 0;
11131}
11132
11133/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053011134 * FUNCTION: hdd_isWPAIEPresent
11135 * Parse the received IE to find the WPA IE
11136 *
11137 */
11138static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
11139{
11140 v_U8_t eLen = 0;
11141 v_U16_t remLen = ie_len;
11142 v_U8_t elementId = 0;
11143
11144 while (remLen >= 2)
11145 {
11146 elementId = *ie++;
11147 eLen = *ie++;
11148 remLen -= 2;
11149 if (eLen > remLen)
11150 {
11151 hddLog(VOS_TRACE_LEVEL_ERROR,
11152 "%s: IE length is wrong %d", __func__, eLen);
11153 return FALSE;
11154 }
11155 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
11156 {
11157 /* OUI - 0x00 0X50 0XF2
11158 WPA Information Element - 0x01
11159 WPA version - 0x01*/
11160 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
11161 return TRUE;
11162 }
11163 ie += eLen;
11164 remLen -= eLen;
11165 }
11166 return FALSE;
11167}
11168
11169/*
Jeff Johnson295189b2012-06-20 16:38:30 -070011170 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011171 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011172 * parameters during connect operation.
11173 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011174int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011175 struct cfg80211_connect_params *req
11176 )
11177{
11178 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011179 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011180 ENTER();
11181
11182 /*set wpa version*/
11183 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
11184
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011185 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011186 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053011187 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011188 {
11189 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11190 }
11191 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
11192 {
11193 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11194 }
11195 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011196
11197 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011198 pWextState->wpaVersion);
11199
11200 /*set authentication type*/
11201 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
11202
11203 if (0 > status)
11204 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011205 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011206 "%s: failed to set authentication type ", __func__);
11207 return status;
11208 }
11209
11210 /*set key mgmt type*/
11211 if (req->crypto.n_akm_suites)
11212 {
11213 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
11214 if (0 > status)
11215 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011216 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070011217 __func__);
11218 return status;
11219 }
11220 }
11221
11222 /*set pairwise cipher type*/
11223 if (req->crypto.n_ciphers_pairwise)
11224 {
11225 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
11226 req->crypto.ciphers_pairwise[0], true);
11227 if (0 > status)
11228 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011229 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011230 "%s: failed to set unicast cipher type", __func__);
11231 return status;
11232 }
11233 }
11234 else
11235 {
11236 /*Reset previous cipher suite to none*/
11237 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
11238 if (0 > status)
11239 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011240 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011241 "%s: failed to set unicast cipher type", __func__);
11242 return status;
11243 }
11244 }
11245
11246 /*set group cipher type*/
11247 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
11248 false);
11249
11250 if (0 > status)
11251 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011252 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070011253 __func__);
11254 return status;
11255 }
11256
Chet Lanctot186b5732013-03-18 10:26:30 -070011257#ifdef WLAN_FEATURE_11W
11258 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
11259#endif
11260
Jeff Johnson295189b2012-06-20 16:38:30 -070011261 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
11262 if (req->ie_len)
11263 {
11264 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
11265 if ( 0 > status)
11266 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011267 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011268 __func__);
11269 return status;
11270 }
11271 }
11272
11273 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011274 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011275 {
11276 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
11277 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
11278 )
11279 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011280 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070011281 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
11282 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011283 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011284 __func__);
11285 return -EOPNOTSUPP;
11286 }
11287 else
11288 {
11289 u8 key_len = req->key_len;
11290 u8 key_idx = req->key_idx;
11291
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011292 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011293 && (CSR_MAX_NUM_KEY > key_idx)
11294 )
11295 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011296 hddLog(VOS_TRACE_LEVEL_INFO,
11297 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011298 __func__, key_idx, key_len);
11299 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011300 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011301 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011302 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011303 (u8)key_len;
11304 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
11305 }
11306 }
11307 }
11308 }
11309
11310 return status;
11311}
11312
11313/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011314 * FUNCTION: wlan_hdd_try_disconnect
11315 * This function is used to disconnect from previous
11316 * connection
11317 */
11318static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
11319{
11320 long ret = 0;
11321 hdd_station_ctx_t *pHddStaCtx;
11322 eMib_dot11DesiredBssType connectedBssType;
11323
11324 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11325
11326 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
11327
11328 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
11329 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
11330 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
11331 {
11332 /* Issue disconnect to CSR */
11333 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11334 if( eHAL_STATUS_SUCCESS ==
11335 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11336 pAdapter->sessionId,
11337 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11338 {
11339 ret = wait_for_completion_interruptible_timeout(
11340 &pAdapter->disconnect_comp_var,
11341 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11342 if (0 >= ret)
11343 {
11344 hddLog(LOGE, FL("Failed to receive disconnect event"));
11345 return -EALREADY;
11346 }
11347 }
11348 }
11349 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
11350 {
11351 ret = wait_for_completion_interruptible_timeout(
11352 &pAdapter->disconnect_comp_var,
11353 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11354 if (0 >= ret)
11355 {
11356 hddLog(LOGE, FL("Failed to receive disconnect event"));
11357 return -EALREADY;
11358 }
11359 }
11360
11361 return 0;
11362}
11363
11364/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053011365 * FUNCTION: __wlan_hdd_cfg80211_connect
11366 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011367 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011368static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011369 struct net_device *ndev,
11370 struct cfg80211_connect_params *req
11371 )
11372{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011373 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011374 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011375 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053011376 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011377
11378 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011379
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011380 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11381 TRACE_CODE_HDD_CFG80211_CONNECT,
11382 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011383 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011384 "%s: device_mode = %s (%d)", __func__,
11385 hdd_device_modetoString(pAdapter->device_mode),
11386 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011387
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011388 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011389 if (!pHddCtx)
11390 {
11391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11392 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011393 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011394 }
11395
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011396 status = wlan_hdd_validate_context(pHddCtx);
11397
11398 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011399 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11401 "%s: HDD context is not valid", __func__);
11402 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011403 }
11404
Agarwal Ashish51325b52014-06-16 16:50:49 +053011405 if (vos_max_concurrent_connections_reached()) {
11406 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11407 return -ECONNREFUSED;
11408 }
11409
Jeff Johnson295189b2012-06-20 16:38:30 -070011410#ifdef WLAN_BTAMP_FEATURE
11411 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011412 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070011413 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011414 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011415 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011416 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070011417 }
11418#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011419
11420 //If Device Mode is Station Concurrent Sessions Exit BMps
11421 //P2P Mode will be taken care in Open/close adapter
11422 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011423 (vos_concurrent_open_sessions_running())) {
11424 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
11425 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011426 }
11427
11428 /*Try disconnecting if already in connected state*/
11429 status = wlan_hdd_try_disconnect(pAdapter);
11430 if ( 0 > status)
11431 {
11432 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11433 " connection"));
11434 return -EALREADY;
11435 }
11436
Jeff Johnson295189b2012-06-20 16:38:30 -070011437 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011438 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070011439
11440 if ( 0 > status)
11441 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011442 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070011443 __func__);
11444 return status;
11445 }
Mohit Khanna765234a2012-09-11 15:08:35 -070011446 if ( req->channel )
11447 {
11448 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
11449 req->ssid_len, req->bssid,
11450 req->channel->hw_value);
11451 }
11452 else
11453 {
11454 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011455 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070011456 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011457
11458 if (0 > status)
11459 {
11460 //ReEnable BMPS if disabled
11461 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
11462 (NULL != pHddCtx))
11463 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011464 if (pHddCtx->hdd_wlan_suspended)
11465 {
11466 hdd_set_pwrparams(pHddCtx);
11467 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011468 //ReEnable Bmps and Imps back
11469 hdd_enable_bmps_imps(pHddCtx);
11470 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011471 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011472 return status;
11473 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011474 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011475 EXIT();
11476 return status;
11477}
11478
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011479static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
11480 struct net_device *ndev,
11481 struct cfg80211_connect_params *req)
11482{
11483 int ret;
11484 vos_ssr_protect(__func__);
11485 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
11486 vos_ssr_unprotect(__func__);
11487
11488 return ret;
11489}
Jeff Johnson295189b2012-06-20 16:38:30 -070011490
11491/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011492 * FUNCTION: wlan_hdd_disconnect
11493 * This function is used to issue a disconnect request to SME
11494 */
11495int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
11496{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011497 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011498 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011499 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011500 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011501
11502 status = wlan_hdd_validate_context(pHddCtx);
11503
11504 if (0 != status)
11505 {
11506 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11507 "%s: HDD context is not valid", __func__);
11508 return status;
11509 }
11510
11511 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011512
Agarwal Ashish47d18112014-08-04 19:55:07 +053011513 /* Need to apply spin lock before decreasing active sessions
11514 * as there can be chance for double decrement if context switch
11515 * Calls hdd_DisConnectHandler.
11516 */
11517
11518 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011519 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11520 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011521 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11522 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053011523 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
11524 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011525
Abhishek Singhf4669da2014-05-26 15:07:49 +053011526 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053011527 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
11528
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011529 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011530
Mihir Shete182a0b22014-08-18 16:08:48 +053011531 /*
11532 * stop tx queues before deleting STA/BSS context from the firmware.
11533 * tx has to be disabled because the firmware can get busy dropping
11534 * the tx frames after BSS/STA has been deleted and will not send
11535 * back a response resulting in WDI timeout
11536 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053011537 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053011538 netif_tx_disable(pAdapter->dev);
11539 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011540
Mihir Shete182a0b22014-08-18 16:08:48 +053011541 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011542 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11543 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011544 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
11545 {
11546 hddLog(VOS_TRACE_LEVEL_INFO,
11547 FL("status = %d, already disconnected"),
11548 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011549
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011550 }
11551 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011552 {
11553 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011554 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011555 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011556 result = -EINVAL;
11557 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011558 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011559 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011560 &pAdapter->disconnect_comp_var,
11561 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011562 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011563 {
11564 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011565 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011566 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011567 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011568 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011569 {
11570 hddLog(VOS_TRACE_LEVEL_ERROR,
11571 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011572 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011573 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011574disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11576 FL("Set HDD connState to eConnectionState_NotConnected"));
11577 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
11578
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011579 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011580}
11581
11582
11583/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011584 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070011585 * This function is used to issue a disconnect request to SME
11586 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011587static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011588 struct net_device *dev,
11589 u16 reason
11590 )
11591{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011592 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011593 tCsrRoamProfile *pRoamProfile =
11594 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011595 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011596 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11597 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011598#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011599 tANI_U8 staIdx;
11600#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011601
Jeff Johnson295189b2012-06-20 16:38:30 -070011602 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011603
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011604 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11605 TRACE_CODE_HDD_CFG80211_DISCONNECT,
11606 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011607 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
11608 __func__, hdd_device_modetoString(pAdapter->device_mode),
11609 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011610
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011611 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
11612 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070011613
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011614 status = wlan_hdd_validate_context(pHddCtx);
11615
11616 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011617 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11619 "%s: HDD context is not valid", __func__);
11620 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011621 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011622
Jeff Johnson295189b2012-06-20 16:38:30 -070011623 if (NULL != pRoamProfile)
11624 {
11625 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011626 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
11627 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070011628 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011629 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070011630 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011631 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070011632 switch(reason)
11633 {
11634 case WLAN_REASON_MIC_FAILURE:
11635 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
11636 break;
11637
11638 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
11639 case WLAN_REASON_DISASSOC_AP_BUSY:
11640 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
11641 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
11642 break;
11643
11644 case WLAN_REASON_PREV_AUTH_NOT_VALID:
11645 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053011646 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070011647 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
11648 break;
11649
Jeff Johnson295189b2012-06-20 16:38:30 -070011650 default:
11651 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
11652 break;
11653 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011654 pScanInfo = &pHddCtx->scan_info;
11655 if (pScanInfo->mScanPending)
11656 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011657 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011658 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011659 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011660 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011661 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011662
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011663#ifdef FEATURE_WLAN_TDLS
11664 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011665 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011666 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011667 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
11668 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011669 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011670 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011671 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011672 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011673 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011674 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011675 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011676 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011677 pAdapter->sessionId,
11678 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011679 }
11680 }
11681#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011682 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011683 status = wlan_hdd_disconnect(pAdapter, reasonCode);
11684 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070011685 {
11686 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011687 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011688 __func__, (int)status );
11689 return -EINVAL;
11690 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011691 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011692 else
11693 {
11694 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
11695 "called while in %d state", __func__,
11696 pHddStaCtx->conn_info.connState);
11697 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011698 }
11699 else
11700 {
11701 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
11702 }
11703
11704 return status;
11705}
11706
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011707static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
11708 struct net_device *dev,
11709 u16 reason
11710 )
11711{
11712 int ret;
11713 vos_ssr_protect(__func__);
11714 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
11715 vos_ssr_unprotect(__func__);
11716
11717 return ret;
11718}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011719
Jeff Johnson295189b2012-06-20 16:38:30 -070011720/*
11721 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011722 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011723 * settings in IBSS mode.
11724 */
11725static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011726 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011727 struct cfg80211_ibss_params *params
11728 )
11729{
11730 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011731 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011732 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11733 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011734
Jeff Johnson295189b2012-06-20 16:38:30 -070011735 ENTER();
11736
11737 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070011738 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070011739
11740 if (params->ie_len && ( NULL != params->ie) )
11741 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011742 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11743 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011744 {
11745 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11746 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11747 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011748 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011749 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011750 tDot11fIEWPA dot11WPAIE;
11751 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011752 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011753
Wilson Yang00256342013-10-10 23:13:38 -070011754 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011755 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11756 params->ie_len, DOT11F_EID_WPA);
11757 if ( NULL != ie )
11758 {
11759 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11760 // Unpack the WPA IE
11761 //Skip past the EID byte and length byte - and four byte WiFi OUI
11762 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
11763 &ie[2+4],
11764 ie[1] - 4,
11765 &dot11WPAIE);
11766 /*Extract the multicast cipher, the encType for unicast
11767 cipher for wpa-none is none*/
11768 encryptionType =
11769 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
11770 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011771 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011772
Jeff Johnson295189b2012-06-20 16:38:30 -070011773 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
11774
11775 if (0 > status)
11776 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011777 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011778 __func__);
11779 return status;
11780 }
11781 }
11782
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011783 pWextState->roamProfile.AuthType.authType[0] =
11784 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011785 eCSR_AUTH_TYPE_OPEN_SYSTEM;
11786
11787 if (params->privacy)
11788 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011789 /* Security enabled IBSS, At this time there is no information available
11790 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070011791 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011792 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070011793 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011794 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070011795 *enable privacy bit in beacons */
11796
11797 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11798 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011799 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
11800 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070011801 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11802 pWextState->roamProfile.EncryptionType.numEntries = 1;
11803 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070011804 return status;
11805}
11806
11807/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011808 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011809 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011810 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011811static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011812 struct net_device *dev,
11813 struct cfg80211_ibss_params *params
11814 )
11815{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011816 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011817 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11818 tCsrRoamProfile *pRoamProfile;
11819 int status;
krunal sonie9002db2013-11-25 14:24:17 -080011820 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011821 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11822 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011823
11824 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011825
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011826 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11827 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
11828 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011829 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011830 "%s: device_mode = %s (%d)", __func__,
11831 hdd_device_modetoString(pAdapter->device_mode),
11832 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011833
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011834 status = wlan_hdd_validate_context(pHddCtx);
11835
11836 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011837 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11839 "%s: HDD context is not valid", __func__);
11840 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011841 }
11842
11843 if (NULL == pWextState)
11844 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011845 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011846 __func__);
11847 return -EIO;
11848 }
11849
Agarwal Ashish51325b52014-06-16 16:50:49 +053011850 if (vos_max_concurrent_connections_reached()) {
11851 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11852 return -ECONNREFUSED;
11853 }
11854
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011855 /*Try disconnecting if already in connected state*/
11856 status = wlan_hdd_try_disconnect(pAdapter);
11857 if ( 0 > status)
11858 {
11859 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11860 " IBSS connection"));
11861 return -EALREADY;
11862 }
11863
Jeff Johnson295189b2012-06-20 16:38:30 -070011864 pRoamProfile = &pWextState->roamProfile;
11865
11866 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
11867 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011868 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011869 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011870 return -EINVAL;
11871 }
11872
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011873 /* BSSID is provided by upper layers hence no need to AUTO generate */
11874 if (NULL != params->bssid) {
11875 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11876 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
11877 hddLog (VOS_TRACE_LEVEL_ERROR,
11878 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11879 return -EIO;
11880 }
11881 }
krunal sonie9002db2013-11-25 14:24:17 -080011882 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
11883 {
11884 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11885 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
11886 {
11887 hddLog (VOS_TRACE_LEVEL_ERROR,
11888 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11889 return -EIO;
11890 }
11891 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
11892 if (!params->bssid)
11893 {
11894 hddLog (VOS_TRACE_LEVEL_ERROR,
11895 "%s:Failed memory allocation", __func__);
11896 return -EIO;
11897 }
11898 vos_mem_copy((v_U8_t *)params->bssid,
11899 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
11900 VOS_MAC_ADDR_SIZE);
11901 alloc_bssid = VOS_TRUE;
11902 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011903
Jeff Johnson295189b2012-06-20 16:38:30 -070011904 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070011905 if (NULL !=
11906#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11907 params->chandef.chan)
11908#else
11909 params->channel)
11910#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011911 {
11912 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011913 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
11914 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
11915 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
11916 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011917
11918 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011919 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070011920 ieee80211_frequency_to_channel(
11921#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11922 params->chandef.chan->center_freq);
11923#else
11924 params->channel->center_freq);
11925#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011926
11927 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
11928 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070011929 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011930 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
11931 __func__);
11932 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070011933 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011934
11935 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011936 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011937 if (channelNum == validChan[indx])
11938 {
11939 break;
11940 }
11941 }
11942 if (indx >= numChans)
11943 {
11944 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011945 __func__, channelNum);
11946 return -EINVAL;
11947 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011948 /* Set the Operational Channel */
11949 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
11950 channelNum);
11951 pRoamProfile->ChannelInfo.numOfChannels = 1;
11952 pHddStaCtx->conn_info.operationChannel = channelNum;
11953 pRoamProfile->ChannelInfo.ChannelList =
11954 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070011955 }
11956
11957 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011958 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070011959 if (status < 0)
11960 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011961 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070011962 __func__);
11963 return status;
11964 }
11965
11966 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011967 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011968 params->ssid_len, params->bssid,
11969 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011970
11971 if (0 > status)
11972 {
11973 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
11974 return status;
11975 }
11976
krunal sonie9002db2013-11-25 14:24:17 -080011977 if (NULL != params->bssid &&
11978 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
11979 alloc_bssid == VOS_TRUE)
11980 {
11981 vos_mem_free(params->bssid);
11982 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011983 return 0;
11984}
11985
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011986static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
11987 struct net_device *dev,
11988 struct cfg80211_ibss_params *params
11989 )
11990{
11991 int ret = 0;
11992
11993 vos_ssr_protect(__func__);
11994 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
11995 vos_ssr_unprotect(__func__);
11996
11997 return ret;
11998}
11999
Jeff Johnson295189b2012-06-20 16:38:30 -070012000/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012001 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012002 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012003 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012004static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012005 struct net_device *dev
12006 )
12007{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012008 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012009 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12010 tCsrRoamProfile *pRoamProfile;
12011 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012012 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012013
12014 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012015
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012016 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12017 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
12018 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012019 status = wlan_hdd_validate_context(pHddCtx);
12020
12021 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012022 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12024 "%s: HDD context is not valid", __func__);
12025 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012026 }
12027
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012028 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
12029 hdd_device_modetoString(pAdapter->device_mode),
12030 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012031 if (NULL == pWextState)
12032 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012033 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012034 __func__);
12035 return -EIO;
12036 }
12037
12038 pRoamProfile = &pWextState->roamProfile;
12039
12040 /* Issue disconnect only if interface type is set to IBSS */
12041 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
12042 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012043 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070012044 __func__);
12045 return -EINVAL;
12046 }
12047
12048 /* Issue Disconnect request */
12049 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12050 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12051 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
12052
12053 return 0;
12054}
12055
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012056static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
12057 struct net_device *dev
12058 )
12059{
12060 int ret = 0;
12061
12062 vos_ssr_protect(__func__);
12063 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
12064 vos_ssr_unprotect(__func__);
12065
12066 return ret;
12067}
12068
Jeff Johnson295189b2012-06-20 16:38:30 -070012069/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012070 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070012071 * This function is used to set the phy parameters
12072 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
12073 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012074static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012075 u32 changed)
12076{
12077 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
12078 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012079 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012080
12081 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012082 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12083 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
12084 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012085 status = wlan_hdd_validate_context(pHddCtx);
12086
12087 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012088 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012089 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12090 "%s: HDD context is not valid", __func__);
12091 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012092 }
12093
Jeff Johnson295189b2012-06-20 16:38:30 -070012094 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
12095 {
12096 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
12097 WNI_CFG_RTS_THRESHOLD_STAMAX :
12098 wiphy->rts_threshold;
12099
12100 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012101 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070012102 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012103 hddLog(VOS_TRACE_LEVEL_ERROR,
12104 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012105 __func__, rts_threshold);
12106 return -EINVAL;
12107 }
12108
12109 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
12110 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012111 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012112 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012113 hddLog(VOS_TRACE_LEVEL_ERROR,
12114 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012115 __func__, rts_threshold);
12116 return -EIO;
12117 }
12118
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012119 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012120 rts_threshold);
12121 }
12122
12123 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
12124 {
12125 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
12126 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
12127 wiphy->frag_threshold;
12128
12129 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012130 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012131 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012132 hddLog(VOS_TRACE_LEVEL_ERROR,
12133 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012134 frag_threshold);
12135 return -EINVAL;
12136 }
12137
12138 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
12139 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012140 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012141 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012142 hddLog(VOS_TRACE_LEVEL_ERROR,
12143 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012144 __func__, frag_threshold);
12145 return -EIO;
12146 }
12147
12148 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
12149 frag_threshold);
12150 }
12151
12152 if ((changed & WIPHY_PARAM_RETRY_SHORT)
12153 || (changed & WIPHY_PARAM_RETRY_LONG))
12154 {
12155 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
12156 wiphy->retry_short :
12157 wiphy->retry_long;
12158
12159 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
12160 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
12161 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012162 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012163 __func__, retry_value);
12164 return -EINVAL;
12165 }
12166
12167 if (changed & WIPHY_PARAM_RETRY_SHORT)
12168 {
12169 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
12170 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012171 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012172 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012173 hddLog(VOS_TRACE_LEVEL_ERROR,
12174 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012175 __func__, retry_value);
12176 return -EIO;
12177 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012178 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012179 __func__, retry_value);
12180 }
12181 else if (changed & WIPHY_PARAM_RETRY_SHORT)
12182 {
12183 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
12184 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012185 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012186 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012187 hddLog(VOS_TRACE_LEVEL_ERROR,
12188 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012189 __func__, retry_value);
12190 return -EIO;
12191 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012192 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012193 __func__, retry_value);
12194 }
12195 }
12196
12197 return 0;
12198}
12199
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012200static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
12201 u32 changed)
12202{
12203 int ret;
12204
12205 vos_ssr_protect(__func__);
12206 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
12207 vos_ssr_unprotect(__func__);
12208
12209 return ret;
12210}
12211
Jeff Johnson295189b2012-06-20 16:38:30 -070012212/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012213 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012214 * This function is used to set the txpower
12215 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012216static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012217#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12218 struct wireless_dev *wdev,
12219#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012220#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012221 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012222#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012223 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012224#endif
12225 int dbm)
12226{
12227 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012228 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012229 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12230 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012231 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012232
12233 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012234 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12235 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
12236 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012237 status = wlan_hdd_validate_context(pHddCtx);
12238
12239 if (0 != status)
12240 {
12241 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12242 "%s: HDD context is not valid", __func__);
12243 return status;
12244 }
12245
12246 hHal = pHddCtx->hHal;
12247
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012248 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
12249 dbm, ccmCfgSetCallback,
12250 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012251 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012252 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012253 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
12254 return -EIO;
12255 }
12256
12257 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
12258 dbm);
12259
12260 switch(type)
12261 {
12262 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
12263 /* Fall through */
12264 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
12265 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
12266 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012267 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
12268 __func__);
12269 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012270 }
12271 break;
12272 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012273 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012274 __func__);
12275 return -EOPNOTSUPP;
12276 break;
12277 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012278 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
12279 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070012280 return -EIO;
12281 }
12282
12283 return 0;
12284}
12285
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012286static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
12287#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12288 struct wireless_dev *wdev,
12289#endif
12290#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12291 enum tx_power_setting type,
12292#else
12293 enum nl80211_tx_power_setting type,
12294#endif
12295 int dbm)
12296{
12297 int ret;
12298 vos_ssr_protect(__func__);
12299 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
12300#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12301 wdev,
12302#endif
12303#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12304 type,
12305#else
12306 type,
12307#endif
12308 dbm);
12309 vos_ssr_unprotect(__func__);
12310
12311 return ret;
12312}
12313
Jeff Johnson295189b2012-06-20 16:38:30 -070012314/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012315 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012316 * This function is used to read the txpower
12317 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012318static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012319#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12320 struct wireless_dev *wdev,
12321#endif
12322 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070012323{
12324
12325 hdd_adapter_t *pAdapter;
12326 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012327 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012328
Jeff Johnsone7245742012-09-05 17:12:55 -070012329 ENTER();
12330
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012331 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012332
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012333 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012334 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012335 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12336 "%s: HDD context is not valid", __func__);
12337 *dbm = 0;
12338 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012339 }
12340
Jeff Johnson295189b2012-06-20 16:38:30 -070012341 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
12342 if (NULL == pAdapter)
12343 {
12344 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
12345 return -ENOENT;
12346 }
12347
12348 wlan_hdd_get_classAstats(pAdapter);
12349 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
12350
Jeff Johnsone7245742012-09-05 17:12:55 -070012351 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012352 return 0;
12353}
12354
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012355static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
12356#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12357 struct wireless_dev *wdev,
12358#endif
12359 int *dbm)
12360{
12361 int ret;
12362
12363 vos_ssr_protect(__func__);
12364 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
12365#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12366 wdev,
12367#endif
12368 dbm);
12369 vos_ssr_unprotect(__func__);
12370
12371 return ret;
12372}
12373
12374
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012375static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070012376 u8* mac, struct station_info *sinfo)
12377{
12378 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12379 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12380 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053012381 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070012382
12383 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
12384 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012385
12386 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
12387 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
12388 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
12389 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
12390 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
12391 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
12392 tANI_U16 maxRate = 0;
12393 tANI_U16 myRate;
12394 tANI_U16 currentRate = 0;
12395 tANI_U8 maxSpeedMCS = 0;
12396 tANI_U8 maxMCSIdx = 0;
12397 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053012398 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012399 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012400 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012401
Leo Chang6f8870f2013-03-26 18:11:36 -070012402#ifdef WLAN_FEATURE_11AC
12403 tANI_U32 vht_mcs_map;
12404 eDataRate11ACMaxMcs vhtMaxMcs;
12405#endif /* WLAN_FEATURE_11AC */
12406
Jeff Johnsone7245742012-09-05 17:12:55 -070012407 ENTER();
12408
Jeff Johnson295189b2012-06-20 16:38:30 -070012409 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
12410 (0 == ssidlen))
12411 {
12412 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
12413 " Invalid ssidlen, %d", __func__, ssidlen);
12414 /*To keep GUI happy*/
12415 return 0;
12416 }
12417
Mukul Sharma811205f2014-07-09 21:07:30 +053012418 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
12419 {
12420 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12421 "%s: Roaming in progress, so unable to proceed this request", __func__);
12422 return 0;
12423 }
12424
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012425 status = wlan_hdd_validate_context(pHddCtx);
12426
12427 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012428 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012429 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12430 "%s: HDD context is not valid", __func__);
12431 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012432 }
12433
Jeff Johnson295189b2012-06-20 16:38:30 -070012434
Kiet Lam3b17fc82013-09-27 05:24:08 +053012435 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
12436 sinfo->filled |= STATION_INFO_SIGNAL;
12437
c_hpothu09f19542014-05-30 21:53:31 +053012438 wlan_hdd_get_station_stats(pAdapter);
12439 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
12440
12441 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053012442 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
12443 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053012444 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053012445 {
12446 rate_flags = pAdapter->maxRateFlags;
12447 }
c_hpothu44ff4e02014-05-08 00:13:57 +053012448
Jeff Johnson295189b2012-06-20 16:38:30 -070012449 //convert to the UI units of 100kbps
12450 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
12451
12452#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070012453 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 -070012454 sinfo->signal,
12455 pCfg->reportMaxLinkSpeed,
12456 myRate,
12457 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012458 (int) pCfg->linkSpeedRssiMid,
12459 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070012460 (int) rate_flags,
12461 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012462#endif //LINKSPEED_DEBUG_ENABLED
12463
12464 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
12465 {
12466 // we do not want to necessarily report the current speed
12467 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
12468 {
12469 // report the max possible speed
12470 rssidx = 0;
12471 }
12472 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
12473 {
12474 // report the max possible speed with RSSI scaling
12475 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
12476 {
12477 // report the max possible speed
12478 rssidx = 0;
12479 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012480 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070012481 {
12482 // report middle speed
12483 rssidx = 1;
12484 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012485 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
12486 {
12487 // report middle speed
12488 rssidx = 2;
12489 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012490 else
12491 {
12492 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012493 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070012494 }
12495 }
12496 else
12497 {
12498 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
12499 hddLog(VOS_TRACE_LEVEL_ERROR,
12500 "%s: Invalid value for reportMaxLinkSpeed: %u",
12501 __func__, pCfg->reportMaxLinkSpeed);
12502 rssidx = 0;
12503 }
12504
12505 maxRate = 0;
12506
12507 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012508 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
12509 OperationalRates, &ORLeng))
12510 {
12511 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12512 /*To keep GUI happy*/
12513 return 0;
12514 }
12515
Jeff Johnson295189b2012-06-20 16:38:30 -070012516 for (i = 0; i < ORLeng; i++)
12517 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012518 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012519 {
12520 /* Validate Rate Set */
12521 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
12522 {
12523 currentRate = supported_data_rate[j].supported_rate[rssidx];
12524 break;
12525 }
12526 }
12527 /* Update MAX rate */
12528 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12529 }
12530
12531 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012532 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
12533 ExtendedRates, &ERLeng))
12534 {
12535 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12536 /*To keep GUI happy*/
12537 return 0;
12538 }
12539
Jeff Johnson295189b2012-06-20 16:38:30 -070012540 for (i = 0; i < ERLeng; i++)
12541 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012542 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012543 {
12544 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
12545 {
12546 currentRate = supported_data_rate[j].supported_rate[rssidx];
12547 break;
12548 }
12549 }
12550 /* Update MAX rate */
12551 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12552 }
c_hpothu79aab322014-07-14 21:11:01 +053012553
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012554 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053012555 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012556 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053012557 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070012558 {
c_hpothu79aab322014-07-14 21:11:01 +053012559 if (rate_flags & eHAL_TX_RATE_VHT80)
12560 mode = 2;
12561 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
12562 mode = 1;
12563 else
12564 mode = 0;
12565
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012566 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
12567 MCSRates, &MCSLeng))
12568 {
12569 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12570 /*To keep GUI happy*/
12571 return 0;
12572 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012573 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070012574#ifdef WLAN_FEATURE_11AC
12575 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012576 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070012577 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012578 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012579 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070012580 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070012581 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012582 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070012583 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012584 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070012585 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012586 maxMCSIdx = 7;
12587 }
12588 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
12589 {
12590 maxMCSIdx = 8;
12591 }
12592 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
12593 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012594 //VHT20 is supporting 0~8
12595 if (rate_flags & eHAL_TX_RATE_VHT20)
12596 maxMCSIdx = 8;
12597 else
12598 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070012599 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012600
c_hpothu79aab322014-07-14 21:11:01 +053012601 if (0 != rssidx)/*check for scaled */
12602 {
12603 //get middle rate MCS index if rssi=1/2
12604 for (i=0; i <= maxMCSIdx; i++)
12605 {
12606 if (sinfo->signal <= rssiMcsTbl[mode][i])
12607 {
12608 maxMCSIdx = i;
12609 break;
12610 }
12611 }
12612 }
12613
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012614 if (rate_flags & eHAL_TX_RATE_VHT80)
12615 {
12616 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
12617 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
12618 }
12619 else if (rate_flags & eHAL_TX_RATE_VHT40)
12620 {
12621 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
12622 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
12623 }
12624 else if (rate_flags & eHAL_TX_RATE_VHT20)
12625 {
12626 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
12627 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
12628 }
12629
Leo Chang6f8870f2013-03-26 18:11:36 -070012630 maxSpeedMCS = 1;
12631 if (currentRate > maxRate)
12632 {
12633 maxRate = currentRate;
12634 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012635
Leo Chang6f8870f2013-03-26 18:11:36 -070012636 }
12637 else
12638#endif /* WLAN_FEATURE_11AC */
12639 {
12640 if (rate_flags & eHAL_TX_RATE_HT40)
12641 {
12642 rateFlag |= 1;
12643 }
12644 if (rate_flags & eHAL_TX_RATE_SGI)
12645 {
12646 rateFlag |= 2;
12647 }
12648
Girish Gowli01abcee2014-07-31 20:18:55 +053012649 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053012650 if (rssidx == 1 || rssidx == 2)
12651 {
12652 //get middle rate MCS index if rssi=1/2
12653 for (i=0; i <= 7; i++)
12654 {
12655 if (sinfo->signal <= rssiMcsTbl[mode][i])
12656 {
12657 temp = i+1;
12658 break;
12659 }
12660 }
12661 }
c_hpothu79aab322014-07-14 21:11:01 +053012662
12663 for (i = 0; i < MCSLeng; i++)
12664 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012665 for (j = 0; j < temp; j++)
12666 {
12667 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
12668 {
12669 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
12670 break;
12671 }
12672 }
12673 if ((j < temp) && (currentRate > maxRate))
12674 {
12675 maxRate = currentRate;
12676 maxSpeedMCS = 1;
12677 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
12678 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012679 }
12680 }
12681 }
12682
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012683 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
12684 {
12685 maxRate = myRate;
12686 maxSpeedMCS = 1;
12687 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12688 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012689 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053012690 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070012691 {
12692 maxRate = myRate;
12693 if (rate_flags & eHAL_TX_RATE_LEGACY)
12694 {
12695 maxSpeedMCS = 0;
12696 }
12697 else
12698 {
12699 maxSpeedMCS = 1;
12700 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12701 }
12702 }
12703
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012704 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070012705 {
12706 sinfo->txrate.legacy = maxRate;
12707#ifdef LINKSPEED_DEBUG_ENABLED
12708 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
12709#endif //LINKSPEED_DEBUG_ENABLED
12710 }
12711 else
12712 {
12713 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070012714#ifdef WLAN_FEATURE_11AC
12715 sinfo->txrate.nss = 1;
12716 if (rate_flags & eHAL_TX_RATE_VHT80)
12717 {
12718 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012719 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070012720 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012721 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070012722 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012723 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12724 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12725 }
12726 else if (rate_flags & eHAL_TX_RATE_VHT20)
12727 {
12728 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12729 }
12730#endif /* WLAN_FEATURE_11AC */
12731 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
12732 {
12733 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12734 if (rate_flags & eHAL_TX_RATE_HT40)
12735 {
12736 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12737 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012738 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012739 if (rate_flags & eHAL_TX_RATE_SGI)
12740 {
12741 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12742 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012743
Jeff Johnson295189b2012-06-20 16:38:30 -070012744#ifdef LINKSPEED_DEBUG_ENABLED
12745 pr_info("Reporting MCS rate %d flags %x\n",
12746 sinfo->txrate.mcs,
12747 sinfo->txrate.flags );
12748#endif //LINKSPEED_DEBUG_ENABLED
12749 }
12750 }
12751 else
12752 {
12753 // report current rate instead of max rate
12754
12755 if (rate_flags & eHAL_TX_RATE_LEGACY)
12756 {
12757 //provide to the UI in units of 100kbps
12758 sinfo->txrate.legacy = myRate;
12759#ifdef LINKSPEED_DEBUG_ENABLED
12760 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
12761#endif //LINKSPEED_DEBUG_ENABLED
12762 }
12763 else
12764 {
12765 //must be MCS
12766 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070012767#ifdef WLAN_FEATURE_11AC
12768 sinfo->txrate.nss = 1;
12769 if (rate_flags & eHAL_TX_RATE_VHT80)
12770 {
12771 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12772 }
12773 else
12774#endif /* WLAN_FEATURE_11AC */
12775 {
12776 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12777 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012778 if (rate_flags & eHAL_TX_RATE_SGI)
12779 {
12780 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12781 }
12782 if (rate_flags & eHAL_TX_RATE_HT40)
12783 {
12784 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12785 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012786#ifdef WLAN_FEATURE_11AC
12787 else if (rate_flags & eHAL_TX_RATE_VHT80)
12788 {
12789 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
12790 }
12791#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070012792#ifdef LINKSPEED_DEBUG_ENABLED
12793 pr_info("Reporting actual MCS rate %d flags %x\n",
12794 sinfo->txrate.mcs,
12795 sinfo->txrate.flags );
12796#endif //LINKSPEED_DEBUG_ENABLED
12797 }
12798 }
12799 sinfo->filled |= STATION_INFO_TX_BITRATE;
12800
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012801 sinfo->tx_packets =
12802 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
12803 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
12804 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
12805 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
12806
12807 sinfo->tx_retries =
12808 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
12809 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
12810 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
12811 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
12812
12813 sinfo->tx_failed =
12814 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
12815 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
12816 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
12817 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
12818
12819 sinfo->filled |=
12820 STATION_INFO_TX_PACKETS |
12821 STATION_INFO_TX_RETRIES |
12822 STATION_INFO_TX_FAILED;
12823
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012824 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12825 TRACE_CODE_HDD_CFG80211_GET_STA,
12826 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012827 EXIT();
12828 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012829}
12830
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012831static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
12832 u8* mac, struct station_info *sinfo)
12833{
12834 int ret;
12835
12836 vos_ssr_protect(__func__);
12837 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
12838 vos_ssr_unprotect(__func__);
12839
12840 return ret;
12841}
12842
12843static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070012844 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070012845{
12846 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012847 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012848 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012849 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012850
Jeff Johnsone7245742012-09-05 17:12:55 -070012851 ENTER();
12852
Jeff Johnson295189b2012-06-20 16:38:30 -070012853 if (NULL == pAdapter)
12854 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012855 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012856 return -ENODEV;
12857 }
12858
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012859 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12860 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
12861 pAdapter->sessionId, timeout));
12862
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012863 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012864 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012865
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012866 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012867 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12869 "%s: HDD context is not valid", __func__);
12870 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012871 }
12872
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012873 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
12874 (TRUE == pHddCtx->hdd_wlan_suspended) &&
12875 (pHddCtx->cfg_ini->fhostArpOffload) &&
12876 (eConnectionState_Associated ==
12877 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12878 {
Amar Singhald53568e2013-09-26 11:03:45 -070012879
12880 hddLog(VOS_TRACE_LEVEL_INFO,
12881 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053012882 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012883 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12884 {
12885 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012886 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012887 __func__, vos_status);
12888 }
12889 }
12890
Jeff Johnson295189b2012-06-20 16:38:30 -070012891 /**The get power cmd from the supplicant gets updated by the nl only
12892 *on successful execution of the function call
12893 *we are oppositely mapped w.r.t mode in the driver
12894 **/
12895 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
12896
Jeff Johnsone7245742012-09-05 17:12:55 -070012897 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012898 if (VOS_STATUS_E_FAILURE == vos_status)
12899 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012900 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12901 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012902 return -EINVAL;
12903 }
12904 return 0;
12905}
12906
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012907static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
12908 struct net_device *dev, bool mode, int timeout)
12909{
12910 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012911
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012912 vos_ssr_protect(__func__);
12913 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
12914 vos_ssr_unprotect(__func__);
12915
12916 return ret;
12917}
Jeff Johnson295189b2012-06-20 16:38:30 -070012918#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012919static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
12920 struct net_device *netdev,
12921 u8 key_index)
12922{
12923 ENTER();
12924 return 0;
12925}
12926
Jeff Johnson295189b2012-06-20 16:38:30 -070012927static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012928 struct net_device *netdev,
12929 u8 key_index)
12930{
12931 int ret;
12932 vos_ssr_protect(__func__);
12933 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
12934 vos_ssr_unprotect(__func__);
12935 return ret;
12936}
12937#endif //LINUX_VERSION_CODE
12938
12939#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
12940static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
12941 struct net_device *dev,
12942 struct ieee80211_txq_params *params)
12943{
12944 ENTER();
12945 return 0;
12946}
12947#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12948static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
12949 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070012950{
Jeff Johnsone7245742012-09-05 17:12:55 -070012951 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012952 return 0;
12953}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012954#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070012955
12956#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
12957static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012958 struct net_device *dev,
12959 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070012960{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012961 int ret;
12962
12963 vos_ssr_protect(__func__);
12964 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
12965 vos_ssr_unprotect(__func__);
12966 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012967}
12968#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12969static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12970 struct ieee80211_txq_params *params)
12971{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012972 int ret;
12973
12974 vos_ssr_protect(__func__);
12975 ret = __wlan_hdd_set_txq_params(wiphy, params);
12976 vos_ssr_unprotect(__func__);
12977 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012978}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012979#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012980
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012981static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012982 struct net_device *dev,
12983 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070012984{
12985 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012986 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012987 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012988 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012989 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012990 v_CONTEXT_t pVosContext = NULL;
12991 ptSapContext pSapCtx = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070012992 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012993
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012994 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070012995 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012996 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012997 return -EINVAL;
12998 }
12999
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013000 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13001 TRACE_CODE_HDD_CFG80211_DEL_STA,
13002 pAdapter->sessionId, pAdapter->device_mode));
13003
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013004 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13005 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070013006
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013007 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013008 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13010 "%s: HDD context is not valid", __func__);
13011 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013012 }
13013
Jeff Johnson295189b2012-06-20 16:38:30 -070013014 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013015 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013016 )
13017 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013018 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13019 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13020 if(pSapCtx == NULL){
13021 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13022 FL("psapCtx is NULL"));
13023 return -ENOENT;
13024 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013025 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013026 {
13027 v_U16_t i;
13028 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13029 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013030 if ((pSapCtx->aStaInfo[i].isUsed) &&
13031 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070013032 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013033 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013034 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013035 ETHER_ADDR_LEN);
13036
Jeff Johnson295189b2012-06-20 16:38:30 -070013037 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013038 "%s: Delete STA with MAC::"
13039 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013040 __func__,
13041 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
13042 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013043 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013044 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013045 }
13046 }
13047 }
13048 else
13049 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013050
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013051 vos_status = hdd_softap_GetStaId(pAdapter,
13052 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013053 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13054 {
13055 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013056 "%s: Skip this DEL STA as this is not used::"
13057 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013058 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013059 return -ENOENT;
13060 }
13061
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013062 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013063 {
13064 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013065 "%s: Skip this DEL STA as deauth is in progress::"
13066 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013067 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013068 return -ENOENT;
13069 }
13070
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013071 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013072
Jeff Johnson295189b2012-06-20 16:38:30 -070013073 hddLog(VOS_TRACE_LEVEL_INFO,
13074 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013075 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013076 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013077 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013078
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013079 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013080 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13081 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013082 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013083 hddLog(VOS_TRACE_LEVEL_INFO,
13084 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013085 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013086 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013087 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013088 return -ENOENT;
13089 }
13090
Jeff Johnson295189b2012-06-20 16:38:30 -070013091 }
13092 }
13093
13094 EXIT();
13095
13096 return 0;
13097}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013098
13099#ifdef CFG80211_DEL_STA_V2
13100static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13101 struct net_device *dev,
13102 struct station_del_parameters *param)
13103#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013104static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13105 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013106#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013107{
13108 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013109 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070013110
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013111 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013112
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013113#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013114 if (NULL == param) {
13115 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013116 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013117 return -EINVAL;
13118 }
13119
13120 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
13121 param->subtype, &delStaParams);
13122
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013123#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053013124 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013125 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013126#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013127 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
13128
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013129 vos_ssr_unprotect(__func__);
13130
13131 return ret;
13132}
13133
13134static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013135 struct net_device *dev, u8 *mac, struct station_parameters *params)
13136{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013137 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013138 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013139#ifdef FEATURE_WLAN_TDLS
13140 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013141 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013142
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013143 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13144 TRACE_CODE_HDD_CFG80211_ADD_STA,
13145 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013146 mask = params->sta_flags_mask;
13147
13148 set = params->sta_flags_set;
13149
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013150#ifdef WLAN_FEATURE_TDLS_DEBUG
13151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13152 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
13153 __func__, mask, set, MAC_ADDR_ARRAY(mac));
13154#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013155
13156 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13157 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013158 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013159 }
13160 }
13161#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013162 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013163}
13164
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013165static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
13166 struct net_device *dev, u8 *mac, struct station_parameters *params)
13167{
13168 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013169
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013170 vos_ssr_protect(__func__);
13171 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
13172 vos_ssr_unprotect(__func__);
13173
13174 return ret;
13175}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013176#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070013177
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013178static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070013179 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013180{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013181 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13182 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013183 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013184 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013185 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013186 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070013187
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013188 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013189 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013190 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013191 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013192 return -EINVAL;
13193 }
13194
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013195 if (!pmksa) {
13196 hddLog(LOGE, FL("pmksa is NULL"));
13197 return -EINVAL;
13198 }
13199
13200 if (!pmksa->bssid || !pmksa->pmkid) {
13201 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
13202 pmksa->bssid, pmksa->pmkid);
13203 return -EINVAL;
13204 }
13205
13206 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
13207 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13208
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013209 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13210 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013211
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013212 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013213 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13215 "%s: HDD context is not valid", __func__);
13216 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013217 }
13218
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013219 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013220 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13221
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013222 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
13223 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013224
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013225 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013226 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013227 &pmk_id, 1, FALSE);
13228
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013229 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13230 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
13231 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013232
13233 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013234}
13235
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013236static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
13237 struct cfg80211_pmksa *pmksa)
13238{
13239 int ret;
13240
13241 vos_ssr_protect(__func__);
13242 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
13243 vos_ssr_unprotect(__func__);
13244
13245 return ret;
13246}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013247
Wilson Yang6507c4e2013-10-01 20:11:19 -070013248
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013249static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070013250 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013251{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013252 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13253 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013254 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013255 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013256
Wilson Yang6507c4e2013-10-01 20:11:19 -070013257 /* Validate pAdapter */
13258 if (NULL == pAdapter)
13259 {
13260 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
13261 return -EINVAL;
13262 }
13263
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013264 if (!pmksa) {
13265 hddLog(LOGE, FL("pmksa is NULL"));
13266 return -EINVAL;
13267 }
13268
13269 if (!pmksa->bssid) {
13270 hddLog(LOGE, FL("pmksa->bssid is NULL"));
13271 return -EINVAL;
13272 }
13273
Kiet Lam98c46a12014-10-31 15:34:57 -070013274 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
13275 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13276
Wilson Yang6507c4e2013-10-01 20:11:19 -070013277 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13278 status = wlan_hdd_validate_context(pHddCtx);
13279
13280 if (0 != status)
13281 {
13282 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13283 "%s: HDD context is not valid", __func__);
13284 return status;
13285 }
13286
13287 /*Retrieve halHandle*/
13288 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13289
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013290 /* Delete the PMKID CSR cache */
13291 if (eHAL_STATUS_SUCCESS !=
13292 sme_RoamDelPMKIDfromCache(halHandle,
13293 pAdapter->sessionId, pmksa->bssid, FALSE)) {
13294 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
13295 MAC_ADDR_ARRAY(pmksa->bssid));
13296 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013297 }
13298
Wilson Yangef657d32014-01-15 19:19:23 -080013299 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013300}
13301
Wilson Yang6507c4e2013-10-01 20:11:19 -070013302
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013303static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
13304 struct cfg80211_pmksa *pmksa)
13305{
13306 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013307
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013308 vos_ssr_protect(__func__);
13309 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
13310 vos_ssr_unprotect(__func__);
13311
13312 return ret;
13313
13314}
13315
13316static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013317{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013318 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13319 tHalHandle halHandle;
13320 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013321 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013322
13323 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
13324
13325 /* Validate pAdapter */
13326 if (NULL == pAdapter)
13327 {
13328 hddLog(VOS_TRACE_LEVEL_ERROR,
13329 "%s: Invalid Adapter" ,__func__);
13330 return -EINVAL;
13331 }
13332
13333 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13334 status = wlan_hdd_validate_context(pHddCtx);
13335
13336 if (0 != status)
13337 {
13338 hddLog(VOS_TRACE_LEVEL_ERROR,
13339 "%s: HDD context is not valid", __func__);
13340 return status;
13341 }
13342
13343 /*Retrieve halHandle*/
13344 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13345
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013346 /* Flush the PMKID cache in CSR */
13347 if (eHAL_STATUS_SUCCESS !=
13348 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
13349 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
13350 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013351 }
13352
Wilson Yangef657d32014-01-15 19:19:23 -080013353 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013354}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013355
13356static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
13357{
13358 int ret;
13359
13360 vos_ssr_protect(__func__);
13361 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
13362 vos_ssr_unprotect(__func__);
13363
13364 return ret;
13365}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013366#endif
13367
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013368#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013369static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13370 struct net_device *dev,
13371 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013372{
13373 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13374 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013375 hdd_context_t *pHddCtx;
13376 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013377
13378 if (NULL == pAdapter)
13379 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013380 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013381 return -ENODEV;
13382 }
13383
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013384 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13385 ret = wlan_hdd_validate_context(pHddCtx);
13386 if (0 != ret)
13387 {
13388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13389 "%s: HDD context is not valid", __func__);
13390 return ret;
13391 }
13392
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013393 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13394
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013395 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13396 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
13397 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013398 // Added for debug on reception of Re-assoc Req.
13399 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
13400 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013401 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013402 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080013403 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013404 }
13405
13406#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080013407 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013408 ftie->ie_len);
13409#endif
13410
13411 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013412 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13413 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013414 ftie->ie_len);
13415 return 0;
13416}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013417
13418static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13419 struct net_device *dev,
13420 struct cfg80211_update_ft_ies_params *ftie)
13421{
13422 int ret;
13423
13424 vos_ssr_protect(__func__);
13425 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
13426 vos_ssr_unprotect(__func__);
13427
13428 return ret;
13429}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013430#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013431
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013432#ifdef FEATURE_WLAN_SCAN_PNO
13433
13434void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
13435 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
13436{
13437 int ret;
13438 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
13439 hdd_context_t *pHddCtx;
13440
Nirav Shah80830bf2013-12-31 16:35:12 +053013441 ENTER();
13442
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013443 if (NULL == pAdapter)
13444 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013445 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013446 "%s: HDD adapter is Null", __func__);
13447 return ;
13448 }
13449
13450 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13451 if (NULL == pHddCtx)
13452 {
13453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13454 "%s: HDD context is Null!!!", __func__);
13455 return ;
13456 }
13457
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013458 spin_lock(&pHddCtx->schedScan_lock);
13459 if (TRUE == pHddCtx->isWiphySuspended)
13460 {
13461 pHddCtx->isSchedScanUpdatePending = TRUE;
13462 spin_unlock(&pHddCtx->schedScan_lock);
13463 hddLog(VOS_TRACE_LEVEL_INFO,
13464 "%s: Update cfg80211 scan database after it resume", __func__);
13465 return ;
13466 }
13467 spin_unlock(&pHddCtx->schedScan_lock);
13468
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013469 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
13470
13471 if (0 > ret)
13472 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
13473
13474 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013475 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13476 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013477}
13478
13479/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013480 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013481 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013482 */
13483static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
13484{
13485 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13486 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013487 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013488 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13489 int status = 0;
13490 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13491
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013492 /* The current firmware design does not allow PNO during any
13493 * active sessions. Hence, determine the active sessions
13494 * and return a failure.
13495 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013496 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
13497 {
13498 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013499 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013500
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013501 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
13502 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
13503 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
13504 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
13505 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053013506 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013507 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013508 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013509 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013510 }
13511 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13512 pAdapterNode = pNext;
13513 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013514 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013515}
13516
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013517void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
13518{
13519 hdd_adapter_t *pAdapter = callbackContext;
13520 hdd_context_t *pHddCtx;
13521
13522 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
13523 {
13524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13525 FL("Invalid adapter or adapter has invalid magic"));
13526 return;
13527 }
13528
13529 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13530 if (0 != wlan_hdd_validate_context(pHddCtx))
13531 {
13532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13533 FL("HDD context is not valid"));
13534 return;
13535 }
13536
c_hpothub53c45d2014-08-18 16:53:14 +053013537 if (VOS_STATUS_SUCCESS != status)
13538 {
13539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013540 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053013541 pHddCtx->isPnoEnable = FALSE;
13542 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013543
13544 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
13545 complete(&pAdapter->pno_comp_var);
13546}
13547
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013548/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013549 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
13550 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013551 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013552static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013553 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13554{
13555 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13556 tpSirPNOScanReq pPnoRequest = NULL;
13557 hdd_context_t *pHddCtx;
13558 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013559 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053013560 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
13561 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013562 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13563 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013564 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013565 hdd_config_t *pConfig = NULL;
13566 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013567
13568 if (NULL == pAdapter)
13569 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013571 "%s: HDD adapter is Null", __func__);
13572 return -ENODEV;
13573 }
13574
13575 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013576 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013577
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013578 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013579 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013580 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13581 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013582 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013583 }
13584
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013585 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013586 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13587 if (NULL == hHal)
13588 {
13589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13590 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013591 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013592 }
Sushant Kaushik2fe89932014-09-03 10:58:09 +053013593 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013594 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053013595 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013596 {
13597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13598 "%s: aborting the existing scan is unsuccessfull", __func__);
13599 return -EBUSY;
13600 }
13601
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013602 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013603 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013605 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013606 return -EBUSY;
13607 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013608
c_hpothu37f21312014-04-09 21:49:54 +053013609 if (TRUE == pHddCtx->isPnoEnable)
13610 {
13611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13612 FL("already PNO is enabled"));
13613 return -EBUSY;
13614 }
c_hpothu225aa7c2014-10-22 17:45:13 +053013615
13616 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
13617 {
13618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13619 "%s: abort ROC failed ", __func__);
13620 return -EBUSY;
13621 }
13622
c_hpothu37f21312014-04-09 21:49:54 +053013623 pHddCtx->isPnoEnable = TRUE;
13624
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013625 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13626 if (NULL == pPnoRequest)
13627 {
13628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13629 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053013630 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013631 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013632 }
13633
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053013634 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013635 pPnoRequest->enable = 1; /*Enable PNO */
13636 pPnoRequest->ucNetworksCount = request->n_match_sets;
13637
13638 if (( !pPnoRequest->ucNetworksCount ) ||
13639 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
13640 {
13641 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013642 "%s: Network input is not correct %d Max Network supported is %d",
13643 __func__, pPnoRequest->ucNetworksCount,
13644 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013645 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013646 goto error;
13647 }
13648
13649 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
13650 {
13651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013652 "%s: Incorrect number of channels %d",
13653 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013654 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013655 goto error;
13656 }
13657
13658 /* Framework provides one set of channels(all)
13659 * common for all saved profile */
13660 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13661 channels_allowed, &num_channels_allowed))
13662 {
13663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13664 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013665 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013666 goto error;
13667 }
13668 /* Checking each channel against allowed channel list */
13669 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053013670 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013671 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013672 char chList [(request->n_channels*5)+1];
13673 int len;
13674 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013675 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013676 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013677 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013678 if (request->channels[i]->hw_value == channels_allowed[indx])
13679 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013680 if ((!pConfig->enableDFSPnoChnlScan) &&
13681 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
13682 {
13683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13684 "%s : Dropping DFS channel : %d",
13685 __func__,channels_allowed[indx]);
13686 num_ignore_dfs_ch++;
13687 break;
13688 }
13689
Nirav Shah80830bf2013-12-31 16:35:12 +053013690 valid_ch[num_ch++] = request->channels[i]->hw_value;
13691 len += snprintf(chList+len, 5, "%d ",
13692 request->channels[i]->hw_value);
13693 break ;
13694 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013695 }
13696 }
Nirav Shah80830bf2013-12-31 16:35:12 +053013697 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013698
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013699 /*If all channels are DFS and dropped, then ignore the PNO request*/
13700 if (num_ignore_dfs_ch == request->n_channels)
13701 {
13702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13703 "%s : All requested channels are DFS channels", __func__);
13704 ret = -EINVAL;
13705 goto error;
13706 }
13707 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013708 /* Filling per profile params */
13709 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
13710 {
13711 pPnoRequest->aNetworks[i].ssId.length =
13712 request->match_sets[i].ssid.ssid_len;
13713
13714 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
13715 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
13716 {
13717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013718 "%s: SSID Len %d is not correct for network %d",
13719 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013720 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013721 goto error;
13722 }
13723
13724 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
13725 request->match_sets[i].ssid.ssid,
13726 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13728 "%s: SSID of network %d is %s ", __func__,
13729 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013730 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
13731 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
13732 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
13733
13734 /*Copying list of valid channel into request */
13735 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
13736 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
13737
13738 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
13739 }
13740
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013741 for (i = 0; i < request->n_ssids; i++)
13742 {
13743 j = 0;
13744 while (j < pPnoRequest->ucNetworksCount)
13745 {
13746 if ((pPnoRequest->aNetworks[j].ssId.length ==
13747 request->ssids[i].ssid_len) &&
13748 (0 == memcmp(pPnoRequest->aNetworks[j].ssId.ssId,
13749 request->ssids[i].ssid,
13750 pPnoRequest->aNetworks[j].ssId.length)))
13751 {
13752 pPnoRequest->aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
13753 break;
13754 }
13755 j++;
13756 }
13757 }
13758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13759 "Number of hidden networks being Configured = %d",
13760 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080013762 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013763 if ((0 < request->ie_len) && (NULL != request->ie))
13764 {
13765 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
13766 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
13767 pPnoRequest->us24GProbeTemplateLen);
13768
13769 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
13770 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
13771 pPnoRequest->us5GProbeTemplateLen);
13772 }
13773
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053013774 /* Driver gets only one time interval which is hardcoded in
13775 * supplicant for 10000ms. Taking power consumption into account 6 timers
13776 * will be used, Timervalue is increased exponentially i.e 10,20,40,
13777 * 80,160,320 secs. And number of scan cycle for each timer
13778 * is configurable through INI param gPNOScanTimerRepeatValue.
13779 * If it is set to 0 only one timer will be used and PNO scan cycle
13780 * will be repeated after each interval specified by supplicant
13781 * till PNO is disabled.
13782 */
13783 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
13784 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
13785 else
13786 pPnoRequest->scanTimers.ucScanTimersCount =
13787 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
13788
13789 tempInterval = (request->interval)/1000;
13790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13791 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
13792 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
13793 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
13794 {
13795 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
13796 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
13797 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
13798 tempInterval *= 2;
13799 }
13800 //Repeat last timer until pno disabled.
13801 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
13802
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053013803 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013804
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013805 INIT_COMPLETION(pAdapter->pno_comp_var);
13806 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
13807 pPnoRequest->callbackContext = pAdapter;
13808 pAdapter->pno_req_status = 0;
13809
Nirav Shah80830bf2013-12-31 16:35:12 +053013810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13811 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
13812 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
13813 pPnoRequest->scanTimers.ucScanTimersCount);
13814
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013815 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
13816 pPnoRequest, pAdapter->sessionId,
13817 hdd_cfg80211_sched_scan_done_callback, pAdapter);
13818 if (eHAL_STATUS_SUCCESS != status)
13819 {
13820 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013821 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013822 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013823 goto error;
13824 }
13825
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013826 ret = wait_for_completion_timeout(
13827 &pAdapter->pno_comp_var,
13828 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
13829 if (0 >= ret)
13830 {
13831 // Did not receive the response for PNO enable in time.
13832 // Assuming the PNO enable was success.
13833 // Returning error from here, because we timeout, results
13834 // in side effect of Wifi (Wifi Setting) not to work.
13835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13836 FL("Timed out waiting for PNO to be Enabled"));
13837 ret = 0;
13838 goto error;
13839 }
13840
c_hpothu3c986b22014-07-09 14:45:09 +053013841 vos_mem_free(pPnoRequest);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013842 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053013843 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013844
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013845error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13847 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013848 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053013849 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013850 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013851}
13852
13853/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013854 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
13855 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013856 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013857static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
13858 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13859{
13860 int ret;
13861
13862 vos_ssr_protect(__func__);
13863 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
13864 vos_ssr_unprotect(__func__);
13865
13866 return ret;
13867}
13868
13869/*
13870 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
13871 * Function to disable PNO
13872 */
13873static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013874 struct net_device *dev)
13875{
13876 eHalStatus status = eHAL_STATUS_FAILURE;
13877 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13878 hdd_context_t *pHddCtx;
13879 tHalHandle hHal;
13880 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013881 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013882
13883 ENTER();
13884
13885 if (NULL == pAdapter)
13886 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013888 "%s: HDD adapter is Null", __func__);
13889 return -ENODEV;
13890 }
13891
13892 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013893
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013894 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013895 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013897 "%s: HDD context is Null", __func__);
13898 return -ENODEV;
13899 }
13900
13901 /* The return 0 is intentional when isLogpInProgress and
13902 * isLoadUnloadInProgress. We did observe a crash due to a return of
13903 * failure in sched_scan_stop , especially for a case where the unload
13904 * of the happens at the same time. The function __cfg80211_stop_sched_scan
13905 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
13906 * success. If it returns a failure , then its next invocation due to the
13907 * clean up of the second interface will have the dev pointer corresponding
13908 * to the first one leading to a crash.
13909 */
13910 if (pHddCtx->isLogpInProgress)
13911 {
13912 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13913 "%s: LOGP in Progress. Ignore!!!", __func__);
13914 return ret;
13915 }
13916
Mihir Shete18156292014-03-11 15:38:30 +053013917 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013918 {
13919 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13920 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13921 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013922 }
13923
13924 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13925 if (NULL == hHal)
13926 {
13927 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13928 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013929 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013930 }
13931
13932 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13933 if (NULL == pPnoRequest)
13934 {
13935 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13936 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013937 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013938 }
13939
13940 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
13941 pPnoRequest->enable = 0; /* Disable PNO */
13942 pPnoRequest->ucNetworksCount = 0;
13943
13944 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
13945 pAdapter->sessionId,
13946 NULL, pAdapter);
13947 if (eHAL_STATUS_SUCCESS != status)
13948 {
13949 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13950 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013951 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013952 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013953 }
c_hpothu37f21312014-04-09 21:49:54 +053013954 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013955
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013956error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013958 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013959 vos_mem_free(pPnoRequest);
13960
13961 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013962 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013963}
13964
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013965/*
13966 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
13967 * NL interface to disable PNO
13968 */
13969static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
13970 struct net_device *dev)
13971{
13972 int ret;
13973
13974 vos_ssr_protect(__func__);
13975 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
13976 vos_ssr_unprotect(__func__);
13977
13978 return ret;
13979}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013980#endif /*FEATURE_WLAN_SCAN_PNO*/
13981
13982
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013983#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013984#if TDLS_MGMT_VERSION2
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013985static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013986 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013987 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
13988#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013989static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013990 u8 *peer, u8 action_code, u8 dialog_token,
13991 u16 status_code, const u8 *buf, size_t len)
13992#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013993{
13994
13995 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13996 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013997 u8 peerMac[6];
13998 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070013999 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080014000 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070014001 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014002 int ret;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014003#if !(TDLS_MGMT_VERSION2)
14004 u32 peer_capability = 0;
14005#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014006 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014007
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014008 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14009 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
14010 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014011 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014012 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014013 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014014 "Invalid arguments");
14015 return -EINVAL;
14016 }
14017
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014018 if (pHddCtx->isLogpInProgress)
14019 {
14020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14021 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053014022 wlan_hdd_tdls_set_link_status(pAdapter,
14023 peer,
14024 eTDLS_LINK_IDLE,
14025 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014026 return -EBUSY;
14027 }
14028
Hoonki Lee27511902013-03-14 18:19:06 -070014029 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014030 {
Hoonki Lee27511902013-03-14 18:19:06 -070014031 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
14032 "%s: TDLS mode is disabled OR not enabled in FW."
14033 MAC_ADDRESS_STR " action %d declined.",
14034 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014035 return -ENOTSUPP;
14036 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014037
Hoonki Lee27511902013-03-14 18:19:06 -070014038 /* other than teardown frame, other mgmt frames are not sent if disabled */
14039 if (SIR_MAC_TDLS_TEARDOWN != action_code)
14040 {
14041 /* if tdls_mode is disabled to respond to peer's request */
14042 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
14043 {
14044 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
14045 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014046 " TDLS mode is disabled. action %d declined.",
14047 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070014048
14049 return -ENOTSUPP;
14050 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014051
14052 if (vos_max_concurrent_connections_reached())
14053 {
14054 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14055 return -EINVAL;
14056 }
Hoonki Lee27511902013-03-14 18:19:06 -070014057 }
14058
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014059 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
14060 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014061 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014062 {
14063 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014064 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014065 " TDLS setup is ongoing. action %d declined.",
14066 __func__, MAC_ADDR_ARRAY(peer), action_code);
14067 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014068 }
14069 }
14070
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014071 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
14072 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080014073 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014074 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14075 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014076 {
14077 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
14078 we return error code at 'add_station()'. Hence we have this
14079 check again in addtion to add_station().
14080 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014081 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014082 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014083 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14084 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014085 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
14086 __func__, MAC_ADDR_ARRAY(peer), action_code,
14087 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053014088 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080014089 }
14090 else
14091 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014092 /* maximum reached. tweak to send error code to peer and return
14093 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014094 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14096 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014097 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
14098 __func__, MAC_ADDR_ARRAY(peer), status_code,
14099 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070014100 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014101 /* fall through to send setup resp with failure status
14102 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014103 }
14104 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014105 else
14106 {
14107 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014108 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014109 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014110 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014111 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014112 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
14113 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014114 return -EPERM;
14115 }
14116 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014117 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014118 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014119
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014120#ifdef WLAN_FEATURE_TDLS_DEBUG
14121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014122 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014123 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
14124 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014125#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014126
Hoonki Leea34dd892013-02-05 22:56:02 -080014127 /*Except teardown responder will not be used so just make 0*/
14128 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014129 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080014130 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014131
14132 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014133 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014134
14135 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
14136 responder = pTdlsPeer->is_responder;
14137 else
Hoonki Leea34dd892013-02-05 22:56:02 -080014138 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014140 "%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 -070014141 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
14142 dialog_token, status_code, len);
14143 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080014144 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014145 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014146
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014147 /* For explicit trigger of DIS_REQ come out of BMPS for
14148 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070014149 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014150 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
14151 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070014152 {
14153 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
14154 {
14155 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014156 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070014157 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
14158 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014159 if (SIR_MAC_TDLS_DIS_REQ != action_code)
14160 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070014161 }
14162
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014163 /* make sure doesn't call send_mgmt() while it is pending */
14164 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
14165 {
14166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014167 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014168 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014169 ret = -EBUSY;
14170 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014171 }
14172
14173 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014174 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
14175
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014176 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053014177 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014178
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014179 if (VOS_STATUS_SUCCESS != status)
14180 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014181 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14182 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014183 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014184 ret = -EINVAL;
14185 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014186 }
14187
Hoonki Leed37cbb32013-04-20 00:31:14 -070014188 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
14189 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
14190
14191 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014192 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070014193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014194 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070014195 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014196 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080014197
14198 if (pHddCtx->isLogpInProgress)
14199 {
14200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14201 "%s: LOGP in Progress. Ignore!!!", __func__);
14202 return -EAGAIN;
14203 }
14204
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014205 ret = -EINVAL;
14206 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014207 }
14208
Gopichand Nakkala05922802013-03-14 12:23:19 -070014209 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070014210 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014211 ret = max_sta_failed;
14212 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070014213 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014214
Hoonki Leea34dd892013-02-05 22:56:02 -080014215 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
14216 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014217 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080014218 }
14219 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
14220 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014221 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080014222 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014223
14224 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014225
14226tx_failed:
14227 /* add_station will be called before sending TDLS_SETUP_REQ and
14228 * TDLS_SETUP_RSP and as part of add_station driver will enable
14229 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
14230 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
14231 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
14232 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
14233 */
14234
14235 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
14236 (SIR_MAC_TDLS_SETUP_RSP == action_code))
14237 wlan_hdd_tdls_check_bmps(pAdapter);
14238 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014239}
14240
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014241#if TDLS_MGMT_VERSION2
14242static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14243 u8 *peer, u8 action_code, u8 dialog_token,
14244 u16 status_code, u32 peer_capability,
14245 const u8 *buf, size_t len)
14246#else
14247static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14248 u8 *peer, u8 action_code, u8 dialog_token,
14249 u16 status_code, const u8 *buf, size_t len)
14250#endif
14251{
14252 int ret;
14253
14254 vos_ssr_protect(__func__);
14255#if TDLS_MGMT_VERSION2
14256 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14257 status_code, peer_capability, buf, len);
14258#else
14259 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14260 status_code, buf, len);
14261#endif
14262 vos_ssr_unprotect(__func__);
14263
14264 return ret;
14265}
Atul Mittal115287b2014-07-08 13:26:33 +053014266
14267int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
14268 u8 *peer,
14269 cfg80211_exttdls_callback callback)
14270{
14271
14272 hddTdlsPeer_t *pTdlsPeer;
14273 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14274 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14275 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
14276 __func__, MAC_ADDR_ARRAY(peer));
14277
14278 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14279 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14280
14281 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14282 " %s TDLS External control and Implicit Trigger not enabled ",
14283 __func__);
14284 return -ENOTSUPP;
14285 }
14286
14287 /* To cater the requirement of establishing the TDLS link
14288 * irrespective of the data traffic , get an entry of TDLS peer.
14289 */
14290 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
14291 if (pTdlsPeer == NULL) {
14292 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14293 "%s: peer " MAC_ADDRESS_STR " not existing",
14294 __func__, MAC_ADDR_ARRAY(peer));
14295 return -EINVAL;
14296 }
14297
14298 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
14299
14300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14301 " %s TDLS Add Force Peer Failed",
14302 __func__);
14303 return -EINVAL;
14304 }
14305 /*EXT TDLS*/
14306
14307 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
14308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14309 " %s TDLS set callback Failed",
14310 __func__);
14311 return -EINVAL;
14312 }
14313
14314 return(0);
14315
14316}
14317
14318int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
14319{
14320
14321 hddTdlsPeer_t *pTdlsPeer;
14322 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14324 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
14325 __func__, MAC_ADDR_ARRAY(peer));
14326
14327 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14328 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14329
14330 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14331 " %s TDLS External control and Implicit Trigger not enabled ",
14332 __func__);
14333 return -ENOTSUPP;
14334 }
14335
14336
14337 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
14338
14339 if ( NULL == pTdlsPeer ) {
14340 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
14341 " peer not exsting",
14342 __func__, MAC_ADDR_ARRAY(peer));
14343 return -EINVAL;
14344 }
14345 else {
14346 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
14347 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
14348 }
14349
14350 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
14351 return -EINVAL;
14352
14353 /*EXT TDLS*/
14354
14355 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
14356
14357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14358 " %s TDLS set callback Failed",
14359 __func__);
14360 return -EINVAL;
14361 }
14362 return(0);
14363
14364}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014365static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014366 u8 *peer, enum nl80211_tdls_operation oper)
14367{
14368 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14369 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014370 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014371 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014372
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014373 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14374 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
14375 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014376 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014377 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014379 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014380 return -EINVAL;
14381 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014382
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014383 status = wlan_hdd_validate_context(pHddCtx);
14384
14385 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014386 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14388 "%s: HDD context is not valid", __func__);
14389 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014390 }
14391
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014392
14393 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014394 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014395 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014396 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014397 "TDLS Disabled in INI OR not enabled in FW. "
14398 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014399 return -ENOTSUPP;
14400 }
14401
14402 switch (oper) {
14403 case NL80211_TDLS_ENABLE_LINK:
14404 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014405 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014406 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014407 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053014408 WLAN_STADescType staDesc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014409
Sunil Dutt41de4e22013-11-14 18:09:02 +053014410 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053014411 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053014412 if ( NULL == pTdlsPeer ) {
14413 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
14414 " (oper %d) not exsting. ignored",
14415 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
14416 return -EINVAL;
14417 }
14418
14419 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14420 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
14421 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
14422 "NL80211_TDLS_ENABLE_LINK");
14423
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070014424 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
14425 {
14426 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
14427 MAC_ADDRESS_STR " failed",
14428 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
14429 return -EINVAL;
14430 }
14431
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014432 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014433 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014434 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053014435
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014436 if (0 != wlan_hdd_tdls_get_link_establish_params(
14437 pAdapter, peer,&tdlsLinkEstablishParams)) {
14438 return -EINVAL;
14439 }
14440 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014441
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014442 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
14443 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
14444 /* Send TDLS peer UAPSD capabilities to the firmware and
14445 * register with the TL on after the response for this operation
14446 * is received .
14447 */
14448 ret = wait_for_completion_interruptible_timeout(
14449 &pAdapter->tdls_link_establish_req_comp,
14450 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
14451 if (ret <= 0)
14452 {
14453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14454 "%s: Link Establish Request Faled Status %ld",
14455 __func__, ret);
14456 return -EINVAL;
14457 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014458 }
Atul Mittal115287b2014-07-08 13:26:33 +053014459 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
14460 eTDLS_LINK_CONNECTED,
14461 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053014462 staDesc.ucSTAId = pTdlsPeer->staId;
14463 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
14464 WLANTL_UpdateTdlsSTAClient(pHddCtx->pvosContext,
14465 &staDesc);
14466
14467
Gopichand Nakkala471708b2013-06-04 20:03:01 +053014468 /* Mark TDLS client Authenticated .*/
14469 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
14470 pTdlsPeer->staId,
14471 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014472 if (VOS_STATUS_SUCCESS == status)
14473 {
Hoonki Lee14621352013-04-16 17:51:19 -070014474 if (pTdlsPeer->is_responder == 0)
14475 {
14476 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
14477
14478 wlan_hdd_tdls_timer_restart(pAdapter,
14479 &pTdlsPeer->initiatorWaitTimeoutTimer,
14480 WAIT_TIME_TDLS_INITIATOR);
14481 /* suspend initiator TX until it receives direct packet from the
14482 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
14483 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
14484 &staId, NULL);
14485 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014486 wlan_hdd_tdls_increment_peer_count(pAdapter);
14487 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014488 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014489
14490 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053014491 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
14492 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014493 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053014494 int ac;
14495 uint8 ucAc[4] = { WLANTL_AC_VO,
14496 WLANTL_AC_VI,
14497 WLANTL_AC_BK,
14498 WLANTL_AC_BE };
14499 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
14500 for(ac=0; ac < 4; ac++)
14501 {
14502 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
14503 pTdlsPeer->staId, ucAc[ac],
14504 tlTid[ac], tlTid[ac], 0, 0,
14505 WLANTL_BI_DIR );
14506 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014507 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014508 }
14509
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014510 }
14511 break;
14512 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080014513 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053014514 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
14515
14516 if ( NULL == pTdlsPeer ) {
14517 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
14518 " (oper %d) not exsting. ignored",
14519 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
14520 return -EINVAL;
14521 }
14522
14523 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14524 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
14525 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
14526 "NL80211_TDLS_DISABLE_LINK");
14527
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014528 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080014529 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014530 long status;
14531
Atul Mittal271a7652014-09-12 13:18:22 +053014532
14533 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
14534 eTDLS_LINK_TEARING,
14535 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
14536 eTDLS_LINK_UNSPECIFIED:
14537 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014538 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
14539
Lee Hoonkic1262f22013-01-24 21:59:00 -080014540 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
14541 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014542
14543 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
14544 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053014545 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053014546 eTDLS_LINK_IDLE,
14547 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014548 if (status <= 0)
14549 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14551 "%s: Del station failed status %ld",
14552 __func__, status);
14553 return -EPERM;
14554 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014555 }
14556 else
14557 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014558 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14559 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080014560 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014561 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014562 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014563 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053014564 {
Atul Mittal115287b2014-07-08 13:26:33 +053014565 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053014566
Atul Mittal115287b2014-07-08 13:26:33 +053014567 if (0 != status)
14568 {
14569 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14570 "%s: Error in TDLS Teardown", __func__);
14571 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053014572 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053014573 break;
14574 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014575 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053014576 {
Atul Mittal115287b2014-07-08 13:26:33 +053014577 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
14578 peer,
14579 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053014580
Atul Mittal115287b2014-07-08 13:26:33 +053014581 if (0 != status)
14582 {
14583 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14584 "%s: Error in TDLS Setup", __func__);
14585 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053014586 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053014587 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053014588 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014589 case NL80211_TDLS_DISCOVERY_REQ:
14590 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14592 "%s: We don't support in-driver setup/teardown/discovery "
14593 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014594 return -ENOTSUPP;
14595 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14597 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014598 return -ENOTSUPP;
14599 }
14600 return 0;
14601}
Chilam NG571c65a2013-01-19 12:27:36 +053014602
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014603static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
14604 u8 *peer, enum nl80211_tdls_operation oper)
14605{
14606 int ret;
14607
14608 vos_ssr_protect(__func__);
14609 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
14610 vos_ssr_unprotect(__func__);
14611
14612 return ret;
14613}
14614
Chilam NG571c65a2013-01-19 12:27:36 +053014615int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
14616 struct net_device *dev, u8 *peer)
14617{
Arif Hussaina7c8e412013-11-20 11:06:42 -080014618 hddLog(VOS_TRACE_LEVEL_INFO,
14619 "tdls send discover req: "MAC_ADDRESS_STR,
14620 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053014621
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014622#if TDLS_MGMT_VERSION2
14623 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14624 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
14625#else
Chilam NG571c65a2013-01-19 12:27:36 +053014626 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14627 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014628#endif
Chilam NG571c65a2013-01-19 12:27:36 +053014629}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014630#endif
14631
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014632#ifdef WLAN_FEATURE_GTK_OFFLOAD
14633/*
14634 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
14635 * Callback rountine called upon receiving response for
14636 * get offload info
14637 */
14638void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
14639 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
14640{
14641
14642 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014643 tANI_U8 tempReplayCounter[8];
14644 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014645
14646 ENTER();
14647
14648 if (NULL == pAdapter)
14649 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014650 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014651 "%s: HDD adapter is Null", __func__);
14652 return ;
14653 }
14654
14655 if (NULL == pGtkOffloadGetInfoRsp)
14656 {
14657 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14658 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
14659 return ;
14660 }
14661
14662 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
14663 {
14664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14665 "%s: wlan Failed to get replay counter value",
14666 __func__);
14667 return ;
14668 }
14669
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014670 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14671 /* Update replay counter */
14672 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
14673 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14674
14675 {
14676 /* changing from little to big endian since supplicant
14677 * works on big endian format
14678 */
14679 int i;
14680 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14681
14682 for (i = 0; i < 8; i++)
14683 {
14684 tempReplayCounter[7-i] = (tANI_U8)p[i];
14685 }
14686 }
14687
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014688 /* Update replay counter to NL */
14689 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014690 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014691}
14692
14693/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014694 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014695 * This function is used to offload GTK rekeying job to the firmware.
14696 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014697int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014698 struct cfg80211_gtk_rekey_data *data)
14699{
14700 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14701 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14702 hdd_station_ctx_t *pHddStaCtx;
14703 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014704 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014705 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014706 eHalStatus status = eHAL_STATUS_FAILURE;
14707
14708 ENTER();
14709
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014710
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014711 if (NULL == pAdapter)
14712 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014714 "%s: HDD adapter is Null", __func__);
14715 return -ENODEV;
14716 }
14717
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014718 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14719 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
14720 pAdapter->sessionId, pAdapter->device_mode));
14721
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014722 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014723
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014724 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014725 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014726 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14727 "%s: HDD context is not valid", __func__);
14728 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014729 }
14730
14731 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14732 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14733 if (NULL == hHal)
14734 {
14735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14736 "%s: HAL context is Null!!!", __func__);
14737 return -EAGAIN;
14738 }
14739
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014740 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
14741 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
14742 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
14743 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014744 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014745 {
14746 /* changing from big to little endian since driver
14747 * works on little endian format
14748 */
14749 tANI_U8 *p =
14750 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
14751 int i;
14752
14753 for (i = 0; i < 8; i++)
14754 {
14755 p[7-i] = data->replay_ctr[i];
14756 }
14757 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014758
14759 if (TRUE == pHddCtx->hdd_wlan_suspended)
14760 {
14761 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014762 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
14763 sizeof (tSirGtkOffloadParams));
14764 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014765 pAdapter->sessionId);
14766
14767 if (eHAL_STATUS_SUCCESS != status)
14768 {
14769 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14770 "%s: sme_SetGTKOffload failed, returned %d",
14771 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053014772
14773 /* Need to clear any trace of key value in the memory.
14774 * Thus zero out the memory even though it is local
14775 * variable.
14776 */
14777 vos_mem_zero(&hddGtkOffloadReqParams,
14778 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014779 return status;
14780 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14782 "%s: sme_SetGTKOffload successfull", __func__);
14783 }
14784 else
14785 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014786 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14787 "%s: wlan not suspended GTKOffload request is stored",
14788 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014789 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014790
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053014791 /* Need to clear any trace of key value in the memory.
14792 * Thus zero out the memory even though it is local
14793 * variable.
14794 */
14795 vos_mem_zero(&hddGtkOffloadReqParams,
14796 sizeof(hddGtkOffloadReqParams));
14797
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014798 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014799}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014800
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014801int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
14802 struct cfg80211_gtk_rekey_data *data)
14803{
14804 int ret;
14805
14806 vos_ssr_protect(__func__);
14807 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
14808 vos_ssr_unprotect(__func__);
14809
14810 return ret;
14811}
14812#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014813/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014814 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014815 * This function is used to set access control policy
14816 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014817static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
14818 struct net_device *dev,
14819 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014820{
14821 int i;
14822 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14823 hdd_hostapd_state_t *pHostapdState;
14824 tsap_Config_t *pConfig;
14825 v_CONTEXT_t pVosContext = NULL;
14826 hdd_context_t *pHddCtx;
14827 int status;
14828
14829 ENTER();
14830
14831 if (NULL == pAdapter)
14832 {
14833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14834 "%s: HDD adapter is Null", __func__);
14835 return -ENODEV;
14836 }
14837
14838 if (NULL == params)
14839 {
14840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14841 "%s: params is Null", __func__);
14842 return -EINVAL;
14843 }
14844
14845 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14846 status = wlan_hdd_validate_context(pHddCtx);
14847
14848 if (0 != status)
14849 {
14850 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14851 "%s: HDD context is not valid", __func__);
14852 return status;
14853 }
14854
14855 pVosContext = pHddCtx->pvosContext;
14856 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
14857
14858 if (NULL == pHostapdState)
14859 {
14860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14861 "%s: pHostapdState is Null", __func__);
14862 return -EINVAL;
14863 }
14864
14865 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
14866 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
14867
14868 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
14869 {
14870 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
14871
14872 /* default value */
14873 pConfig->num_accept_mac = 0;
14874 pConfig->num_deny_mac = 0;
14875
14876 /**
14877 * access control policy
14878 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
14879 * listed in hostapd.deny file.
14880 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
14881 * listed in hostapd.accept file.
14882 */
14883 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
14884 {
14885 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
14886 }
14887 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
14888 {
14889 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
14890 }
14891 else
14892 {
14893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14894 "%s:Acl Policy : %d is not supported",
14895 __func__, params->acl_policy);
14896 return -ENOTSUPP;
14897 }
14898
14899 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
14900 {
14901 pConfig->num_accept_mac = params->n_acl_entries;
14902 for (i = 0; i < params->n_acl_entries; i++)
14903 {
14904 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14905 "** Add ACL MAC entry %i in WhiletList :"
14906 MAC_ADDRESS_STR, i,
14907 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14908
14909 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
14910 sizeof(qcmacaddr));
14911 }
14912 }
14913 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
14914 {
14915 pConfig->num_deny_mac = params->n_acl_entries;
14916 for (i = 0; i < params->n_acl_entries; i++)
14917 {
14918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14919 "** Add ACL MAC entry %i in BlackList :"
14920 MAC_ADDRESS_STR, i,
14921 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14922
14923 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
14924 sizeof(qcmacaddr));
14925 }
14926 }
14927
14928 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
14929 {
14930 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14931 "%s: SAP Set Mac Acl fail", __func__);
14932 return -EINVAL;
14933 }
14934 }
14935 else
14936 {
14937 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014938 "%s: Invalid device_mode = %s (%d)",
14939 __func__, hdd_device_modetoString(pAdapter->device_mode),
14940 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014941 return -EINVAL;
14942 }
14943
14944 return 0;
14945}
14946
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014947static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
14948 struct net_device *dev,
14949 const struct cfg80211_acl_data *params)
14950{
14951 int ret;
14952 vos_ssr_protect(__func__);
14953 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
14954 vos_ssr_unprotect(__func__);
14955
14956 return ret;
14957}
14958
Leo Chang9056f462013-08-01 19:21:11 -070014959#ifdef WLAN_NL80211_TESTMODE
14960#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070014961void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070014962(
14963 void *pAdapter,
14964 void *indCont
14965)
14966{
Leo Changd9df8aa2013-09-26 13:32:26 -070014967 tSirLPHBInd *lphbInd;
14968 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053014969 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070014970
14971 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014972 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070014973
c_hpothu73f35e62014-04-18 13:40:08 +053014974 if (pAdapter == NULL)
14975 {
14976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14977 "%s: pAdapter is NULL\n",__func__);
14978 return;
14979 }
14980
Leo Chang9056f462013-08-01 19:21:11 -070014981 if (NULL == indCont)
14982 {
14983 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014984 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070014985 return;
14986 }
14987
c_hpothu73f35e62014-04-18 13:40:08 +053014988 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070014989 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070014990 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053014991 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070014992 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070014993 GFP_ATOMIC);
14994 if (!skb)
14995 {
14996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14997 "LPHB timeout, NL buffer alloc fail");
14998 return;
14999 }
15000
Leo Changac3ba772013-10-07 09:47:04 -070015001 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070015002 {
15003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15004 "WLAN_HDD_TM_ATTR_CMD put fail");
15005 goto nla_put_failure;
15006 }
Leo Changac3ba772013-10-07 09:47:04 -070015007 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070015008 {
15009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15010 "WLAN_HDD_TM_ATTR_TYPE put fail");
15011 goto nla_put_failure;
15012 }
Leo Changac3ba772013-10-07 09:47:04 -070015013 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070015014 sizeof(tSirLPHBInd), lphbInd))
15015 {
15016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15017 "WLAN_HDD_TM_ATTR_DATA put fail");
15018 goto nla_put_failure;
15019 }
Leo Chang9056f462013-08-01 19:21:11 -070015020 cfg80211_testmode_event(skb, GFP_ATOMIC);
15021 return;
15022
15023nla_put_failure:
15024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15025 "NLA Put fail");
15026 kfree_skb(skb);
15027
15028 return;
15029}
15030#endif /* FEATURE_WLAN_LPHB */
15031
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015032static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070015033{
15034 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
15035 int err = 0;
15036#ifdef FEATURE_WLAN_LPHB
15037 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070015038 eHalStatus smeStatus;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015039 err = wlan_hdd_validate_context(pHddCtx);
15040 if (0 != err)
15041 {
15042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15043 "%s: HDD context is not valid", __func__);
15044 return err;
15045 }
Leo Chang9056f462013-08-01 19:21:11 -070015046#endif /* FEATURE_WLAN_LPHB */
15047
15048 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
15049 if (err)
15050 {
15051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15052 "%s Testmode INV ATTR", __func__);
15053 return err;
15054 }
15055
15056 if (!tb[WLAN_HDD_TM_ATTR_CMD])
15057 {
15058 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15059 "%s Testmode INV CMD", __func__);
15060 return -EINVAL;
15061 }
15062
15063 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
15064 {
15065#ifdef FEATURE_WLAN_LPHB
15066 /* Low Power Heartbeat configuration request */
15067 case WLAN_HDD_TM_CMD_WLAN_HB:
15068 {
15069 int buf_len;
15070 void *buf;
15071 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080015072 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070015073
15074 if (!tb[WLAN_HDD_TM_ATTR_DATA])
15075 {
15076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15077 "%s Testmode INV DATA", __func__);
15078 return -EINVAL;
15079 }
15080
15081 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
15082 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080015083
15084 hb_params_temp =(tSirLPHBReq *)buf;
15085 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
15086 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
15087 return -EINVAL;
15088
Leo Chang9056f462013-08-01 19:21:11 -070015089 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
15090 if (NULL == hb_params)
15091 {
15092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15093 "%s Request Buffer Alloc Fail", __func__);
15094 return -EINVAL;
15095 }
15096
15097 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070015098 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
15099 hb_params,
15100 wlan_hdd_cfg80211_lphb_ind_handler);
15101 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070015102 {
Leo Changd9df8aa2013-09-26 13:32:26 -070015103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15104 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070015105 vos_mem_free(hb_params);
15106 }
Leo Chang9056f462013-08-01 19:21:11 -070015107 return 0;
15108 }
15109#endif /* FEATURE_WLAN_LPHB */
15110 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015111 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15112 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070015113 return -EOPNOTSUPP;
15114 }
15115
15116 return err;
15117}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015118
15119static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
15120{
15121 int ret;
15122
15123 vos_ssr_protect(__func__);
15124 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
15125 vos_ssr_unprotect(__func__);
15126
15127 return ret;
15128}
Leo Chang9056f462013-08-01 19:21:11 -070015129#endif /* CONFIG_NL80211_TESTMODE */
15130
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015131static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015132 struct net_device *dev,
15133 int idx, struct survey_info *survey)
15134{
15135 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15136 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053015137 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015138 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053015139 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015140 v_S7_t snr,rssi;
15141 int status, i, j, filled = 0;
15142
15143 ENTER();
15144
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015145 if (NULL == pAdapter)
15146 {
15147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15148 "%s: HDD adapter is Null", __func__);
15149 return -ENODEV;
15150 }
15151
15152 if (NULL == wiphy)
15153 {
15154 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15155 "%s: wiphy is Null", __func__);
15156 return -ENODEV;
15157 }
15158
15159 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15160 status = wlan_hdd_validate_context(pHddCtx);
15161
15162 if (0 != status)
15163 {
15164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15165 "%s: HDD context is not valid", __func__);
15166 return status;
15167 }
15168
Mihir Sheted9072e02013-08-21 17:02:29 +053015169 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15170
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015171 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053015172 0 != pAdapter->survey_idx ||
15173 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015174 {
15175 /* The survey dump ops when implemented completely is expected to
15176 * return a survey of all channels and the ops is called by the
15177 * kernel with incremental values of the argument 'idx' till it
15178 * returns -ENONET. But we can only support the survey for the
15179 * operating channel for now. survey_idx is used to track
15180 * that the ops is called only once and then return -ENONET for
15181 * the next iteration
15182 */
15183 pAdapter->survey_idx = 0;
15184 return -ENONET;
15185 }
15186
15187 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15188
15189 wlan_hdd_get_snr(pAdapter, &snr);
15190 wlan_hdd_get_rssi(pAdapter, &rssi);
15191
15192 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
15193 hdd_wlan_get_freq(channel, &freq);
15194
15195
15196 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
15197 {
15198 if (NULL == wiphy->bands[i])
15199 {
15200 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
15201 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
15202 continue;
15203 }
15204
15205 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
15206 {
15207 struct ieee80211_supported_band *band = wiphy->bands[i];
15208
15209 if (band->channels[j].center_freq == (v_U16_t)freq)
15210 {
15211 survey->channel = &band->channels[j];
15212 /* The Rx BDs contain SNR values in dB for the received frames
15213 * while the supplicant expects noise. So we calculate and
15214 * return the value of noise (dBm)
15215 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
15216 */
15217 survey->noise = rssi - snr;
15218 survey->filled = SURVEY_INFO_NOISE_DBM;
15219 filled = 1;
15220 }
15221 }
15222 }
15223
15224 if (filled)
15225 pAdapter->survey_idx = 1;
15226 else
15227 {
15228 pAdapter->survey_idx = 0;
15229 return -ENONET;
15230 }
15231
15232 return 0;
15233}
15234
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015235static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
15236 struct net_device *dev,
15237 int idx, struct survey_info *survey)
15238{
15239 int ret;
15240
15241 vos_ssr_protect(__func__);
15242 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
15243 vos_ssr_unprotect(__func__);
15244
15245 return ret;
15246}
15247
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015248/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015249 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015250 * this is called when cfg80211 driver resume
15251 * driver updates latest sched_scan scan result(if any) to cfg80211 database
15252 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015253int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015254{
15255 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15256 hdd_adapter_t *pAdapter;
15257 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15258 VOS_STATUS status = VOS_STATUS_SUCCESS;
15259
15260 ENTER();
15261
15262 if ( NULL == pHddCtx )
15263 {
15264 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15265 "%s: HddCtx validation failed", __func__);
15266 return 0;
15267 }
15268
15269 if (pHddCtx->isLogpInProgress)
15270 {
15271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15272 "%s: LOGP in Progress. Ignore!!!", __func__);
15273 return 0;
15274 }
15275
Mihir Shete18156292014-03-11 15:38:30 +053015276 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015277 {
15278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15279 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15280 return 0;
15281 }
15282
15283 spin_lock(&pHddCtx->schedScan_lock);
15284 pHddCtx->isWiphySuspended = FALSE;
15285 if (TRUE != pHddCtx->isSchedScanUpdatePending)
15286 {
15287 spin_unlock(&pHddCtx->schedScan_lock);
15288 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15289 "%s: Return resume is not due to PNO indication", __func__);
15290 return 0;
15291 }
15292 // Reset flag to avoid updatating cfg80211 data old results again
15293 pHddCtx->isSchedScanUpdatePending = FALSE;
15294 spin_unlock(&pHddCtx->schedScan_lock);
15295
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015296
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015297 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15298
15299 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15300 {
15301 pAdapter = pAdapterNode->pAdapter;
15302 if ( (NULL != pAdapter) &&
15303 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
15304 {
15305 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015306 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15308 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015309 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015310 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015311 {
15312 /* Acquire wakelock to handle the case where APP's tries to
15313 * suspend immediately after updating the scan results. Whis
15314 * results in app's is in suspended state and not able to
15315 * process the connect request to AP
15316 */
15317 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015318 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015319 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015320
15321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15322 "%s : cfg80211 scan result database updated", __func__);
15323
15324 return 0;
15325
15326 }
15327 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15328 pAdapterNode = pNext;
15329 }
15330
15331 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15332 "%s: Failed to find Adapter", __func__);
15333 return 0;
15334}
15335
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015336int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
15337{
15338 int ret;
15339
15340 vos_ssr_protect(__func__);
15341 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
15342 vos_ssr_unprotect(__func__);
15343
15344 return ret;
15345}
15346
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015347/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015348 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015349 * this is called when cfg80211 driver suspends
15350 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015351int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015352 struct cfg80211_wowlan *wow)
15353{
15354 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015355 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015356
15357 ENTER();
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015358 ret = wlan_hdd_validate_context(pHddCtx);
15359 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015360 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15362 "%s: HDD context is not valid", __func__);
15363 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015364 }
15365
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015366
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015367 pHddCtx->isWiphySuspended = TRUE;
15368
15369 EXIT();
15370
15371 return 0;
15372}
15373
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015374int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
15375 struct cfg80211_wowlan *wow)
15376{
15377 int ret;
15378
15379 vos_ssr_protect(__func__);
15380 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
15381 vos_ssr_unprotect(__func__);
15382
15383 return ret;
15384}
Jeff Johnson295189b2012-06-20 16:38:30 -070015385/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015386static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070015387{
15388 .add_virtual_intf = wlan_hdd_add_virtual_intf,
15389 .del_virtual_intf = wlan_hdd_del_virtual_intf,
15390 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
15391 .change_station = wlan_hdd_change_station,
15392#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
15393 .add_beacon = wlan_hdd_cfg80211_add_beacon,
15394 .del_beacon = wlan_hdd_cfg80211_del_beacon,
15395 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015396#else
15397 .start_ap = wlan_hdd_cfg80211_start_ap,
15398 .change_beacon = wlan_hdd_cfg80211_change_beacon,
15399 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070015400#endif
15401 .change_bss = wlan_hdd_cfg80211_change_bss,
15402 .add_key = wlan_hdd_cfg80211_add_key,
15403 .get_key = wlan_hdd_cfg80211_get_key,
15404 .del_key = wlan_hdd_cfg80211_del_key,
15405 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015406#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070015407 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015408#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015409 .scan = wlan_hdd_cfg80211_scan,
15410 .connect = wlan_hdd_cfg80211_connect,
15411 .disconnect = wlan_hdd_cfg80211_disconnect,
15412 .join_ibss = wlan_hdd_cfg80211_join_ibss,
15413 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
15414 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
15415 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
15416 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070015417 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
15418 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053015419 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070015420#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15421 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
15422 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
15423 .set_txq_params = wlan_hdd_set_txq_params,
15424#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015425 .get_station = wlan_hdd_cfg80211_get_station,
15426 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
15427 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015428 .add_station = wlan_hdd_cfg80211_add_station,
15429#ifdef FEATURE_WLAN_LFR
15430 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
15431 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
15432 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
15433#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015434#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
15435 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
15436#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015437#ifdef FEATURE_WLAN_TDLS
15438 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
15439 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
15440#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015441#ifdef WLAN_FEATURE_GTK_OFFLOAD
15442 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
15443#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015444#ifdef FEATURE_WLAN_SCAN_PNO
15445 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
15446 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
15447#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015448 .resume = wlan_hdd_cfg80211_resume_wlan,
15449 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015450 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070015451#ifdef WLAN_NL80211_TESTMODE
15452 .testmode_cmd = wlan_hdd_cfg80211_testmode,
15453#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015454 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070015455};
15456