blob: 0fb491de15f547d099535c9f1f6c9e251b1cf88a [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);
7261
7262 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307263
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307264 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7265 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
7266 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307267 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7268 __func__, hdd_device_modetoString(pAdapter->device_mode),
7269 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007270
7271 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007272 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307273 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007274 {
7275 /* ap_isolate == -1 means that in change bss, upper layer doesn't
7276 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307277 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07007278 {
7279 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307280 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007281 }
7282
7283 EXIT();
7284 return 0;
7285}
7286
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307287static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
7288 struct net_device *dev,
7289 struct bss_parameters *params)
7290{
7291 int ret;
7292
7293 vos_ssr_protect(__func__);
7294 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
7295 vos_ssr_unprotect(__func__);
7296
7297 return ret;
7298}
Kiet Lam10841362013-11-01 11:36:50 +05307299/* FUNCTION: wlan_hdd_change_country_code_cd
7300* to wait for contry code completion
7301*/
7302void* wlan_hdd_change_country_code_cb(void *pAdapter)
7303{
7304 hdd_adapter_t *call_back_pAdapter = pAdapter;
7305 complete(&call_back_pAdapter->change_country_code);
7306 return NULL;
7307}
7308
Jeff Johnson295189b2012-06-20 16:38:30 -07007309/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307310 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07007311 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
7312 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307313int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007314 struct net_device *ndev,
7315 enum nl80211_iftype type,
7316 u32 *flags,
7317 struct vif_params *params
7318 )
7319{
7320 struct wireless_dev *wdev;
7321 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007322 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07007323 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007324 tCsrRoamProfile *pRoamProfile = NULL;
7325 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307326 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007327 eMib_dot11DesiredBssType connectedBssType;
7328 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307329 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007330
7331 ENTER();
7332
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307333 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007334 {
7335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7336 "%s: Adapter context is null", __func__);
7337 return VOS_STATUS_E_FAILURE;
7338 }
7339
7340 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7341 if (!pHddCtx)
7342 {
7343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7344 "%s: HDD context is null", __func__);
7345 return VOS_STATUS_E_FAILURE;
7346 }
7347
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307348 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7349 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
7350 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307351 status = wlan_hdd_validate_context(pHddCtx);
7352
7353 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007354 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307355 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7356 "%s: HDD context is not valid", __func__);
7357 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007358 }
7359
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307360 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7361 __func__, hdd_device_modetoString(pAdapter->device_mode),
7362 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007363
Agarwal Ashish51325b52014-06-16 16:50:49 +05307364 if (vos_max_concurrent_connections_reached()) {
7365 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7366 return -EINVAL;
7367 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307368 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007369 wdev = ndev->ieee80211_ptr;
7370
7371#ifdef WLAN_BTAMP_FEATURE
7372 if((NL80211_IFTYPE_P2P_CLIENT == type)||
7373 (NL80211_IFTYPE_ADHOC == type)||
7374 (NL80211_IFTYPE_AP == type)||
7375 (NL80211_IFTYPE_P2P_GO == type))
7376 {
7377 pHddCtx->isAmpAllowed = VOS_FALSE;
7378 // stop AMP traffic
7379 status = WLANBAP_StopAmp();
7380 if(VOS_STATUS_SUCCESS != status )
7381 {
7382 pHddCtx->isAmpAllowed = VOS_TRUE;
7383 hddLog(VOS_TRACE_LEVEL_FATAL,
7384 "%s: Failed to stop AMP", __func__);
7385 return -EINVAL;
7386 }
7387 }
7388#endif //WLAN_BTAMP_FEATURE
7389 /* Reset the current device mode bit mask*/
7390 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7391
7392 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007393 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07007394 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07007395 )
7396 {
7397 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007398 if (!pWextState)
7399 {
7400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7401 "%s: pWextState is null", __func__);
7402 return VOS_STATUS_E_FAILURE;
7403 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007404 pRoamProfile = &pWextState->roamProfile;
7405 LastBSSType = pRoamProfile->BSSType;
7406
7407 switch (type)
7408 {
7409 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007410 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007411 hddLog(VOS_TRACE_LEVEL_INFO,
7412 "%s: setting interface Type to INFRASTRUCTURE", __func__);
7413 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07007414#ifdef WLAN_FEATURE_11AC
7415 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
7416 {
7417 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
7418 }
7419#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307420 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07007421 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007422 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007423 //Check for sub-string p2p to confirm its a p2p interface
7424 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307425 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007426 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7427 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7428 }
7429 else
7430 {
7431 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007432 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007433 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007434 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05307435
Jeff Johnson295189b2012-06-20 16:38:30 -07007436 case NL80211_IFTYPE_ADHOC:
7437 hddLog(VOS_TRACE_LEVEL_INFO,
7438 "%s: setting interface Type to ADHOC", __func__);
7439 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
7440 pRoamProfile->phyMode =
7441 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07007442 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007443 wdev->iftype = type;
7444 break;
7445
7446 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007447 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007448 {
7449 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7450 "%s: setting interface Type to %s", __func__,
7451 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
7452
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007453 //Cancel any remain on channel for GO mode
7454 if (NL80211_IFTYPE_P2P_GO == type)
7455 {
7456 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
7457 }
Mohit Khanna0f232092012-09-11 14:46:08 -07007458 if (NL80211_IFTYPE_AP == type)
7459 {
7460 /* As Loading WLAN Driver one interface being created for p2p device
7461 * address. This will take one HW STA and the max number of clients
7462 * that can connect to softAP will be reduced by one. so while changing
7463 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
7464 * interface as it is not required in SoftAP mode.
7465 */
7466
7467 // Get P2P Adapter
7468 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
7469
7470 if (pP2pAdapter)
7471 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307472 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07007473 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
7474 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
7475 }
7476 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05307477 //Disable IMPS & BMPS for SAP/GO
7478 if(VOS_STATUS_E_FAILURE ==
7479 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
7480 {
7481 //Fail to Exit BMPS
7482 VOS_ASSERT(0);
7483 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05307484
7485 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
7486
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307487#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07007488
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307489 /* A Mutex Lock is introduced while changing the mode to
7490 * protect the concurrent access for the Adapters by TDLS
7491 * module.
7492 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307493 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307494#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007495 //De-init the adapter.
Jeff Johnson295189b2012-06-20 16:38:30 -07007496 hdd_deinit_adapter( pHddCtx, pAdapter );
7497 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07007498 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7499 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307500#ifdef FEATURE_WLAN_TDLS
7501 mutex_unlock(&pHddCtx->tdls_lock);
7502#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007503 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
7504 (pConfig->apRandomBssidEnabled))
7505 {
7506 /* To meet Android requirements create a randomized
7507 MAC address of the form 02:1A:11:Fx:xx:xx */
7508 get_random_bytes(&ndev->dev_addr[3], 3);
7509 ndev->dev_addr[0] = 0x02;
7510 ndev->dev_addr[1] = 0x1A;
7511 ndev->dev_addr[2] = 0x11;
7512 ndev->dev_addr[3] |= 0xF0;
7513 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
7514 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08007515 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
7516 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007517 }
7518
Jeff Johnson295189b2012-06-20 16:38:30 -07007519 hdd_set_ap_ops( pAdapter->dev );
7520
Kiet Lam10841362013-11-01 11:36:50 +05307521 /* This is for only SAP mode where users can
7522 * control country through ini.
7523 * P2P GO follows station country code
7524 * acquired during the STA scanning. */
7525 if((NL80211_IFTYPE_AP == type) &&
7526 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
7527 {
7528 int status = 0;
7529 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
7530 "%s: setting country code from INI ", __func__);
7531 init_completion(&pAdapter->change_country_code);
7532 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
7533 (void *)(tSmeChangeCountryCallback)
7534 wlan_hdd_change_country_code_cb,
7535 pConfig->apCntryCode, pAdapter,
7536 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05307537 eSIR_FALSE,
7538 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05307539 if (eHAL_STATUS_SUCCESS == status)
7540 {
7541 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307542 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05307543 &pAdapter->change_country_code,
7544 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307545 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05307546 {
7547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307548 FL("SME Timed out while setting country code %ld"),
7549 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08007550
7551 if (pHddCtx->isLogpInProgress)
7552 {
7553 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7554 "%s: LOGP in Progress. Ignore!!!", __func__);
7555 return -EAGAIN;
7556 }
Kiet Lam10841362013-11-01 11:36:50 +05307557 }
7558 }
7559 else
7560 {
7561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007562 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05307563 return -EINVAL;
7564 }
7565 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007566 status = hdd_init_ap_mode(pAdapter);
7567 if(status != VOS_STATUS_SUCCESS)
7568 {
7569 hddLog(VOS_TRACE_LEVEL_FATAL,
7570 "%s: Error initializing the ap mode", __func__);
7571 return -EINVAL;
7572 }
7573 hdd_set_conparam(1);
7574
Jeff Johnson295189b2012-06-20 16:38:30 -07007575 /*interface type changed update in wiphy structure*/
7576 if(wdev)
7577 {
7578 wdev->iftype = type;
7579 pHddCtx->change_iface = type;
7580 }
7581 else
7582 {
7583 hddLog(VOS_TRACE_LEVEL_ERROR,
7584 "%s: ERROR !!!! Wireless dev is NULL", __func__);
7585 return -EINVAL;
7586 }
7587 goto done;
7588 }
7589
7590 default:
7591 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7592 __func__);
7593 return -EOPNOTSUPP;
7594 }
7595 }
7596 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007597 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007598 )
7599 {
7600 switch(type)
7601 {
7602 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007603 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007604 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05307605
7606 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307607#ifdef FEATURE_WLAN_TDLS
7608
7609 /* A Mutex Lock is introduced while changing the mode to
7610 * protect the concurrent access for the Adapters by TDLS
7611 * module.
7612 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307613 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307614#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07007615 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007616 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007617 //Check for sub-string p2p to confirm its a p2p interface
7618 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007619 {
7620 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7621 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7622 }
7623 else
7624 {
7625 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007626 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007627 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007628 hdd_set_conparam(0);
7629 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007630 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
7631 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307632#ifdef FEATURE_WLAN_TDLS
7633 mutex_unlock(&pHddCtx->tdls_lock);
7634#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05307635 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007636 if( VOS_STATUS_SUCCESS != status )
7637 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07007638 /* In case of JB, for P2P-GO, only change interface will be called,
7639 * This is the right place to enable back bmps_imps()
7640 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307641 if (pHddCtx->hdd_wlan_suspended)
7642 {
7643 hdd_set_pwrparams(pHddCtx);
7644 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007645 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007646 goto done;
7647 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007648 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007649 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007650 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7651 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007652 goto done;
7653 default:
7654 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7655 __func__);
7656 return -EOPNOTSUPP;
7657
7658 }
7659
7660 }
7661 else
7662 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307663 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
7664 __func__, hdd_device_modetoString(pAdapter->device_mode),
7665 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007666 return -EOPNOTSUPP;
7667 }
7668
7669
7670 if(pRoamProfile)
7671 {
7672 if ( LastBSSType != pRoamProfile->BSSType )
7673 {
7674 /*interface type changed update in wiphy structure*/
7675 wdev->iftype = type;
7676
7677 /*the BSS mode changed, We need to issue disconnect
7678 if connected or in IBSS disconnect state*/
7679 if ( hdd_connGetConnectedBssType(
7680 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
7681 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
7682 {
7683 /*need to issue a disconnect to CSR.*/
7684 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7685 if( eHAL_STATUS_SUCCESS ==
7686 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
7687 pAdapter->sessionId,
7688 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
7689 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307690 ret = wait_for_completion_interruptible_timeout(
7691 &pAdapter->disconnect_comp_var,
7692 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7693 if (ret <= 0)
7694 {
7695 hddLog(VOS_TRACE_LEVEL_ERROR,
7696 FL("wait on disconnect_comp_var failed %ld"), ret);
7697 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007698 }
7699 }
7700 }
7701 }
7702
7703done:
7704 /*set bitmask based on updated value*/
7705 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07007706
7707 /* Only STA mode support TM now
7708 * all other mode, TM feature should be disabled */
7709 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
7710 (~VOS_STA & pHddCtx->concurrency_mode) )
7711 {
7712 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
7713 }
7714
Jeff Johnson295189b2012-06-20 16:38:30 -07007715#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307716 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05307717 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07007718 {
7719 //we are ok to do AMP
7720 pHddCtx->isAmpAllowed = VOS_TRUE;
7721 }
7722#endif //WLAN_BTAMP_FEATURE
7723 EXIT();
7724 return 0;
7725}
7726
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307727/*
7728 * FUNCTION: wlan_hdd_cfg80211_change_iface
7729 * wrapper function to protect the actual implementation from SSR.
7730 */
7731int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
7732 struct net_device *ndev,
7733 enum nl80211_iftype type,
7734 u32 *flags,
7735 struct vif_params *params
7736 )
7737{
7738 int ret;
7739
7740 vos_ssr_protect(__func__);
7741 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
7742 vos_ssr_unprotect(__func__);
7743
7744 return ret;
7745}
7746
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007747#ifdef FEATURE_WLAN_TDLS
7748static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
7749 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
7750{
7751 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7752 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7753 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007754 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307755 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307756 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007757
7758 ENTER();
7759
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307760 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007761 {
7762 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7763 "Invalid arguments");
7764 return -EINVAL;
7765 }
Hoonki Lee27511902013-03-14 18:19:06 -07007766
7767 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
7768 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
7769 {
7770 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7771 "%s: TDLS mode is disabled OR not enabled in FW."
7772 MAC_ADDRESS_STR " Request declined.",
7773 __func__, MAC_ADDR_ARRAY(mac));
7774 return -ENOTSUPP;
7775 }
7776
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007777 if (pHddCtx->isLogpInProgress)
7778 {
7779 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7780 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05307781 wlan_hdd_tdls_set_link_status(pAdapter,
7782 mac,
7783 eTDLS_LINK_IDLE,
7784 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007785 return -EBUSY;
7786 }
7787
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05307788 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007789
7790 if ( NULL == pTdlsPeer ) {
7791 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7792 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
7793 __func__, MAC_ADDR_ARRAY(mac), update);
7794 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007795 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007796
7797 /* in add station, we accept existing valid staId if there is */
7798 if ((0 == update) &&
7799 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
7800 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007801 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007802 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007803 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007804 " link_status %d. staId %d. add station ignored.",
7805 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
7806 return 0;
7807 }
7808 /* in change station, we accept only when staId is valid */
7809 if ((1 == update) &&
7810 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
7811 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
7812 {
7813 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7814 "%s: " MAC_ADDRESS_STR
7815 " link status %d. staId %d. change station %s.",
7816 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
7817 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
7818 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007819 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007820
7821 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307822 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007823 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7825 "%s: " MAC_ADDRESS_STR
7826 " TDLS setup is ongoing. Request declined.",
7827 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07007828 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007829 }
7830
7831 /* first to check if we reached to maximum supported TDLS peer.
7832 TODO: for now, return -EPERM looks working fine,
7833 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307834 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
7835 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007836 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007837 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7838 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307839 " TDLS Max peer already connected. Request declined."
7840 " Num of peers (%d), Max allowed (%d).",
7841 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
7842 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007843 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007844 }
7845 else
7846 {
7847 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307848 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007849 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007850 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007851 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7852 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
7853 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007854 return -EPERM;
7855 }
7856 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007857 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05307858 wlan_hdd_tdls_set_link_status(pAdapter,
7859 mac,
7860 eTDLS_LINK_CONNECTING,
7861 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007862
Jeff Johnsond75fe012013-04-06 10:53:06 -07007863 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307864 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007865 {
7866 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7867 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007868 if(StaParams->htcap_present)
7869 {
7870 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7871 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
7872 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7873 "ht_capa->extended_capabilities: %0x",
7874 StaParams->HTCap.extendedHtCapInfo);
7875 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007876 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7877 "params->capability: %0x",StaParams->capability);
7878 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007879 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007880 if(StaParams->vhtcap_present)
7881 {
7882 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7883 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
7884 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
7885 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
7886 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007887 {
7888 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007890 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
7891 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7892 "[%d]: %x ", i, StaParams->supported_rates[i]);
7893 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07007894 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307895 else if ((1 == update) && (NULL == StaParams))
7896 {
7897 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7898 "%s : update is true, but staParams is NULL. Error!", __func__);
7899 return -EPERM;
7900 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007901
7902 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
7903
7904 if (!update)
7905 {
7906 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7907 pAdapter->sessionId, mac);
7908 }
7909 else
7910 {
7911 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7912 pAdapter->sessionId, mac, StaParams);
7913 }
7914
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307915 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007916 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
7917
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307918 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007919 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007920 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307921 "%s: timeout waiting for tdls add station indication %ld",
7922 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007923 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007924 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307925
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007926 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
7927 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007929 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007930 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007931 }
7932
7933 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007934
7935error:
Atul Mittal115287b2014-07-08 13:26:33 +05307936 wlan_hdd_tdls_set_link_status(pAdapter,
7937 mac,
7938 eTDLS_LINK_IDLE,
7939 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007940 return -EPERM;
7941
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007942}
7943#endif
7944
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307945static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007946 struct net_device *dev,
7947 u8 *mac,
7948 struct station_parameters *params)
7949{
7950 VOS_STATUS status = VOS_STATUS_SUCCESS;
7951 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05307952 hdd_context_t *pHddCtx;
7953 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007954 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007955#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007956 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007957 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307958 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007959#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007960 ENTER();
7961
Gopichand Nakkala29149562013-05-10 21:43:41 +05307962 if ((NULL == pAdapter))
7963 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307964 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05307965 "invalid adapter ");
7966 return -EINVAL;
7967 }
7968
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307969 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7970 TRACE_CODE_HDD_CHANGE_STATION,
7971 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05307972 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7973 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7974
7975 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
7976 {
7977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7978 "invalid HDD state or HDD station context");
7979 return -EINVAL;
7980 }
7981
7982 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007983 {
7984 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7985 "%s:LOGP in Progress. Ignore!!!", __func__);
7986 return -EAGAIN;
7987 }
7988
Jeff Johnson295189b2012-06-20 16:38:30 -07007989 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
7990
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007991 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
7992 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07007993 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007994 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07007995 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307996 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07007997 WLANTL_STA_AUTHENTICATED);
7998
Gopichand Nakkala29149562013-05-10 21:43:41 +05307999 if (status != VOS_STATUS_SUCCESS)
8000 {
8001 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8002 "%s: Not able to change TL state to AUTHENTICATED", __func__);
8003 return -EINVAL;
8004 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008005 }
8006 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07008007 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8008 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308009#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008010 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8011 StaParams.capability = params->capability;
8012 StaParams.uapsd_queues = params->uapsd_queues;
8013 StaParams.max_sp = params->max_sp;
8014
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308015 /* Convert (first channel , number of channels) tuple to
8016 * the total list of channels. This goes with the assumption
8017 * that if the first channel is < 14, then the next channels
8018 * are an incremental of 1 else an incremental of 4 till the number
8019 * of channels.
8020 */
8021 if (0 != params->supported_channels_len) {
8022 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
8023 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
8024 {
8025 int wifi_chan_index;
8026 StaParams.supported_channels[j] = params->supported_channels[i];
8027 wifi_chan_index =
8028 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
8029 no_of_channels = params->supported_channels[i+1];
8030 for(k=1; k <= no_of_channels; k++)
8031 {
8032 StaParams.supported_channels[j+1] =
8033 StaParams.supported_channels[j] + wifi_chan_index;
8034 j+=1;
8035 }
8036 }
8037 StaParams.supported_channels_len = j;
8038 }
8039 vos_mem_copy(StaParams.supported_oper_classes,
8040 params->supported_oper_classes,
8041 params->supported_oper_classes_len);
8042 StaParams.supported_oper_classes_len =
8043 params->supported_oper_classes_len;
8044
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008045 if (0 != params->ext_capab_len)
8046 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
8047 sizeof(StaParams.extn_capability));
8048
8049 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008050 {
8051 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008052 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008053 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008054
8055 StaParams.supported_rates_len = params->supported_rates_len;
8056
8057 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
8058 * The supported_rates array , for all the structures propogating till Add Sta
8059 * to the firmware has to be modified , if the supplicant (ieee80211) is
8060 * modified to send more rates.
8061 */
8062
8063 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
8064 */
8065 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
8066 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
8067
8068 if (0 != StaParams.supported_rates_len) {
8069 int i = 0;
8070 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
8071 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008072 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008073 "Supported Rates with Length %d", StaParams.supported_rates_len);
8074 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008076 "[%d]: %0x", i, StaParams.supported_rates[i]);
8077 }
8078
8079 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008080 {
8081 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008082 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008083 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008084
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008085 if (0 != params->ext_capab_len ) {
8086 /*Define A Macro : TODO Sunil*/
8087 if ((1<<4) & StaParams.extn_capability[3]) {
8088 isBufSta = 1;
8089 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308090 /* TDLS Channel Switching Support */
8091 if ((1<<6) & StaParams.extn_capability[3]) {
8092 isOffChannelSupported = 1;
8093 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008094 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308095 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
8096 &StaParams, isBufSta,
8097 isOffChannelSupported);
8098
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308099 if (VOS_STATUS_SUCCESS != status) {
8100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8101 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
8102 return -EINVAL;
8103 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008104 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
8105
8106 if (VOS_STATUS_SUCCESS != status) {
8107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8108 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
8109 return -EINVAL;
8110 }
8111 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008112#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05308113 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008114 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008115 return status;
8116}
8117
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308118static int wlan_hdd_change_station(struct wiphy *wiphy,
8119 struct net_device *dev,
8120 u8 *mac,
8121 struct station_parameters *params)
8122{
8123 int ret;
8124
8125 vos_ssr_protect(__func__);
8126 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
8127 vos_ssr_unprotect(__func__);
8128
8129 return ret;
8130}
8131
Jeff Johnson295189b2012-06-20 16:38:30 -07008132/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308133 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008134 * This function is used to initialize the key information
8135 */
8136#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308137static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008138 struct net_device *ndev,
8139 u8 key_index, bool pairwise,
8140 const u8 *mac_addr,
8141 struct key_params *params
8142 )
8143#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308144static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008145 struct net_device *ndev,
8146 u8 key_index, const u8 *mac_addr,
8147 struct key_params *params
8148 )
8149#endif
8150{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008151 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07008152 tCsrRoamSetKey setKey;
8153 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308154 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008155 v_U32_t roamId= 0xFF;
8156 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008157 hdd_hostapd_state_t *pHostapdState;
8158 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008159 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308160 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008161
8162 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308163
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308164 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8165 TRACE_CODE_HDD_CFG80211_ADD_KEY,
8166 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308167 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8168 status = wlan_hdd_validate_context(pHddCtx);
8169
8170 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008171 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8173 "%s: HDD context is not valid", __func__);
8174 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008175 }
8176
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308177 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8178 __func__, hdd_device_modetoString(pAdapter->device_mode),
8179 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008180
8181 if (CSR_MAX_NUM_KEY <= key_index)
8182 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008183 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008184 key_index);
8185
8186 return -EINVAL;
8187 }
8188
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008189 if (CSR_MAX_KEY_LEN < params->key_len)
8190 {
8191 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
8192 params->key_len);
8193
8194 return -EINVAL;
8195 }
8196
8197 hddLog(VOS_TRACE_LEVEL_INFO,
8198 "%s: called with key index = %d & key length %d",
8199 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008200
8201 /*extract key idx, key len and key*/
8202 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8203 setKey.keyId = key_index;
8204 setKey.keyLength = params->key_len;
8205 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
8206
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008207 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07008208 {
8209 case WLAN_CIPHER_SUITE_WEP40:
8210 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
8211 break;
8212
8213 case WLAN_CIPHER_SUITE_WEP104:
8214 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
8215 break;
8216
8217 case WLAN_CIPHER_SUITE_TKIP:
8218 {
8219 u8 *pKey = &setKey.Key[0];
8220 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
8221
8222 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
8223
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008224 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07008225
8226 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008227 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008228 |--------------|----------|----------|
8229 <---16bytes---><--8bytes--><--8bytes-->
8230
8231 */
8232 /*Sme expects the 32 bytes key to be in the below order
8233
8234 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008235 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008236 |--------------|----------|----------|
8237 <---16bytes---><--8bytes--><--8bytes-->
8238 */
8239 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008240 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07008241
8242 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008243 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008244
8245 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008246 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008247
8248
8249 break;
8250 }
8251
8252 case WLAN_CIPHER_SUITE_CCMP:
8253 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
8254 break;
8255
8256#ifdef FEATURE_WLAN_WAPI
8257 case WLAN_CIPHER_SUITE_SMS4:
8258 {
8259 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8260 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
8261 params->key, params->key_len);
8262 return 0;
8263 }
8264#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008265
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008266#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07008267 case WLAN_CIPHER_SUITE_KRK:
8268 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
8269 break;
8270#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008271
8272#ifdef WLAN_FEATURE_11W
8273 case WLAN_CIPHER_SUITE_AES_CMAC:
8274 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07008275 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07008276#endif
8277
Jeff Johnson295189b2012-06-20 16:38:30 -07008278 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008279 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07008280 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308281 status = -EOPNOTSUPP;
8282 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008283 }
8284
8285 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
8286 __func__, setKey.encType);
8287
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008288 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07008289#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8290 (!pairwise)
8291#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008292 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07008293#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008294 )
8295 {
8296 /* set group key*/
8297 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8298 "%s- %d: setting Broadcast key",
8299 __func__, __LINE__);
8300 setKey.keyDirection = eSIR_RX_ONLY;
8301 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8302 }
8303 else
8304 {
8305 /* set pairwise key*/
8306 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8307 "%s- %d: setting pairwise key",
8308 __func__, __LINE__);
8309 setKey.keyDirection = eSIR_TX_RX;
8310 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8311 }
8312 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
8313 {
8314 setKey.keyDirection = eSIR_TX_RX;
8315 /*Set the group key*/
8316 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8317 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07008318
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008319 if ( 0 != status )
8320 {
8321 hddLog(VOS_TRACE_LEVEL_ERROR,
8322 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308323 status = -EINVAL;
8324 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008325 }
8326 /*Save the keys here and call sme_RoamSetKey for setting
8327 the PTK after peer joins the IBSS network*/
8328 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
8329 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308330 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008331 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05308332 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
8333 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
8334 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008335 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008336 if( pHostapdState->bssState == BSS_START )
8337 {
c_hpothu7c55da62014-01-23 18:34:02 +05308338 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8339 vos_status = wlan_hdd_check_ula_done(pAdapter);
8340
8341 if ( vos_status != VOS_STATUS_SUCCESS )
8342 {
8343 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8344 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8345 __LINE__, vos_status );
8346
8347 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8348
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308349 status = -EINVAL;
8350 goto end;
c_hpothu7c55da62014-01-23 18:34:02 +05308351 }
8352
Jeff Johnson295189b2012-06-20 16:38:30 -07008353 status = WLANSAP_SetKeySta( pVosContext, &setKey);
8354
8355 if ( status != eHAL_STATUS_SUCCESS )
8356 {
8357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8358 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8359 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308360 status = -EINVAL;
8361 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008362 }
8363 }
8364
8365 /* Saving WEP keys */
8366 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
8367 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
8368 {
8369 //Save the wep key in ap context. Issue setkey after the BSS is started.
8370 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8371 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
8372 }
8373 else
8374 {
8375 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008376 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008377 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
8378 }
8379 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008380 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
8381 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008382 {
8383 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8384 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8385
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308386#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8387 if (!pairwise)
8388#else
8389 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8390#endif
8391 {
8392 /* set group key*/
8393 if (pHddStaCtx->roam_info.deferKeyComplete)
8394 {
8395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8396 "%s- %d: Perform Set key Complete",
8397 __func__, __LINE__);
8398 hdd_PerformRoamSetKeyComplete(pAdapter);
8399 }
8400 }
8401
Jeff Johnson295189b2012-06-20 16:38:30 -07008402 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
8403
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08008404 pWextState->roamProfile.Keys.defaultIndex = key_index;
8405
8406
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008407 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008408 params->key, params->key_len);
8409
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308410
Jeff Johnson295189b2012-06-20 16:38:30 -07008411 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8412
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308413 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008414 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308415 __func__, setKey.peerMac[0], setKey.peerMac[1],
8416 setKey.peerMac[2], setKey.peerMac[3],
8417 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008418 setKey.keyDirection);
8419
8420 vos_status = wlan_hdd_check_ula_done(pAdapter);
8421
8422 if ( vos_status != VOS_STATUS_SUCCESS )
8423 {
8424 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8425 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8426 __LINE__, vos_status );
8427
8428 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8429
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308430 status = -EINVAL;
8431 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008432
8433 }
8434
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008435#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308436 /* The supplicant may attempt to set the PTK once pre-authentication
8437 is done. Save the key in the UMAC and include it in the ADD BSS
8438 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008439 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308440 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008441 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308442 hddLog(VOS_TRACE_LEVEL_INFO_MED,
8443 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308444 status = 0;
8445 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308446 }
8447 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
8448 {
8449 hddLog(VOS_TRACE_LEVEL_ERROR,
8450 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308451 status = -EINVAL;
8452 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008453 }
8454#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07008455
8456 /* issue set key request to SME*/
8457 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8458 pAdapter->sessionId, &setKey, &roamId );
8459
8460 if ( 0 != status )
8461 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308462 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008463 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
8464 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308465 status = -EINVAL;
8466 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008467 }
8468
8469
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308470 /* in case of IBSS as there was no information available about WEP keys during
8471 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07008472 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308473 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
8474 !( ( IW_AUTH_KEY_MGMT_802_1X
8475 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07008476 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
8477 )
8478 &&
8479 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
8480 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
8481 )
8482 )
8483 {
8484 setKey.keyDirection = eSIR_RX_ONLY;
8485 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8486
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308487 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008488 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308489 __func__, setKey.peerMac[0], setKey.peerMac[1],
8490 setKey.peerMac[2], setKey.peerMac[3],
8491 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008492 setKey.keyDirection);
8493
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308494 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008495 pAdapter->sessionId, &setKey, &roamId );
8496
8497 if ( 0 != status )
8498 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308499 hddLog(VOS_TRACE_LEVEL_ERROR,
8500 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008501 __func__, status);
8502 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308503 status = -EINVAL;
8504 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008505 }
8506 }
8507 }
8508
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308509end:
8510 /* Need to clear any trace of key value in the memory.
8511 * Thus zero out the memory even though it is local
8512 * variable.
8513 */
8514 vos_mem_zero(&setKey, sizeof(setKey));
8515
8516 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008517}
8518
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308519#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8520static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8521 struct net_device *ndev,
8522 u8 key_index, bool pairwise,
8523 const u8 *mac_addr,
8524 struct key_params *params
8525 )
8526#else
8527static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8528 struct net_device *ndev,
8529 u8 key_index, const u8 *mac_addr,
8530 struct key_params *params
8531 )
8532#endif
8533{
8534 int ret;
8535 vos_ssr_protect(__func__);
8536#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8537 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
8538 mac_addr, params);
8539#else
8540 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
8541 params);
8542#endif
8543 vos_ssr_unprotect(__func__);
8544
8545 return ret;
8546}
8547
Jeff Johnson295189b2012-06-20 16:38:30 -07008548/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308549 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008550 * This function is used to get the key information
8551 */
8552#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308553static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308554 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008555 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308556 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008557 const u8 *mac_addr, void *cookie,
8558 void (*callback)(void *cookie, struct key_params*)
8559 )
8560#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308561static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308562 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008563 struct net_device *ndev,
8564 u8 key_index, const u8 *mac_addr, void *cookie,
8565 void (*callback)(void *cookie, struct key_params*)
8566 )
8567#endif
8568{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308569 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308570 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8571 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Jeff Johnson295189b2012-06-20 16:38:30 -07008572 struct key_params params;
8573
8574 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308575
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308576 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8577 __func__, hdd_device_modetoString(pAdapter->device_mode),
8578 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308579
Jeff Johnson295189b2012-06-20 16:38:30 -07008580 memset(&params, 0, sizeof(params));
8581
8582 if (CSR_MAX_NUM_KEY <= key_index)
8583 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308584 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07008585 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308586 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008587
8588 switch(pRoamProfile->EncryptionType.encryptionType[0])
8589 {
8590 case eCSR_ENCRYPT_TYPE_NONE:
8591 params.cipher = IW_AUTH_CIPHER_NONE;
8592 break;
8593
8594 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
8595 case eCSR_ENCRYPT_TYPE_WEP40:
8596 params.cipher = WLAN_CIPHER_SUITE_WEP40;
8597 break;
8598
8599 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
8600 case eCSR_ENCRYPT_TYPE_WEP104:
8601 params.cipher = WLAN_CIPHER_SUITE_WEP104;
8602 break;
8603
8604 case eCSR_ENCRYPT_TYPE_TKIP:
8605 params.cipher = WLAN_CIPHER_SUITE_TKIP;
8606 break;
8607
8608 case eCSR_ENCRYPT_TYPE_AES:
8609 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
8610 break;
8611
8612 default:
8613 params.cipher = IW_AUTH_CIPHER_NONE;
8614 break;
8615 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308616
c_hpothuaaf19692014-05-17 17:01:48 +05308617 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8618 TRACE_CODE_HDD_CFG80211_GET_KEY,
8619 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308620
Jeff Johnson295189b2012-06-20 16:38:30 -07008621 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
8622 params.seq_len = 0;
8623 params.seq = NULL;
8624 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
8625 callback(cookie, &params);
8626 return 0;
8627}
8628
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308629#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8630static int wlan_hdd_cfg80211_get_key(
8631 struct wiphy *wiphy,
8632 struct net_device *ndev,
8633 u8 key_index, bool pairwise,
8634 const u8 *mac_addr, void *cookie,
8635 void (*callback)(void *cookie, struct key_params*)
8636 )
8637#else
8638static int wlan_hdd_cfg80211_get_key(
8639 struct wiphy *wiphy,
8640 struct net_device *ndev,
8641 u8 key_index, const u8 *mac_addr, void *cookie,
8642 void (*callback)(void *cookie, struct key_params*)
8643 )
8644#endif
8645{
8646 int ret;
8647
8648 vos_ssr_protect(__func__);
8649#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8650 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
8651 mac_addr, cookie, callback);
8652#else
8653 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
8654 callback);
8655#endif
8656 vos_ssr_unprotect(__func__);
8657
8658 return ret;
8659}
8660
Jeff Johnson295189b2012-06-20 16:38:30 -07008661/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308662 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008663 * This function is used to delete the key information
8664 */
8665#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308666static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008667 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308668 u8 key_index,
8669 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008670 const u8 *mac_addr
8671 )
8672#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308673static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008674 struct net_device *ndev,
8675 u8 key_index,
8676 const u8 *mac_addr
8677 )
8678#endif
8679{
8680 int status = 0;
8681
8682 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308683 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07008684 //it is observed that this is invalidating peer
8685 //key index whenever re-key is done. This is affecting data link.
8686 //It should be ok to ignore del_key.
8687#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308688 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
8689 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008690 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
8691 tCsrRoamSetKey setKey;
8692 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308693
Jeff Johnson295189b2012-06-20 16:38:30 -07008694 ENTER();
8695
8696 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
8697 __func__,pAdapter->device_mode);
8698
8699 if (CSR_MAX_NUM_KEY <= key_index)
8700 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308701 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008702 key_index);
8703
8704 return -EINVAL;
8705 }
8706
8707 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8708 setKey.keyId = key_index;
8709
8710 if (mac_addr)
8711 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8712 else
8713 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
8714
8715 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
8716
8717 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008718 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308719 )
8720 {
8721
8722 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07008723 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8724 if( pHostapdState->bssState == BSS_START)
8725 {
8726 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308727
Jeff Johnson295189b2012-06-20 16:38:30 -07008728 if ( status != eHAL_STATUS_SUCCESS )
8729 {
8730 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8731 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8732 __LINE__, status );
8733 }
8734 }
8735 }
8736 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308737 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07008738 )
8739 {
8740 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8741
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308742 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8743
8744 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008745 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308746 __func__, setKey.peerMac[0], setKey.peerMac[1],
8747 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07008748 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308749 if(pAdapter->sessionCtx.station.conn_info.connState ==
8750 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07008751 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308752 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008753 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308754
Jeff Johnson295189b2012-06-20 16:38:30 -07008755 if ( 0 != status )
8756 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308757 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008758 "%s: sme_RoamSetKey failure, returned %d",
8759 __func__, status);
8760 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8761 return -EINVAL;
8762 }
8763 }
8764 }
8765#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008766 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008767 return status;
8768}
8769
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308770#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8771static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
8772 struct net_device *ndev,
8773 u8 key_index,
8774 bool pairwise,
8775 const u8 *mac_addr
8776 )
8777#else
8778static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
8779 struct net_device *ndev,
8780 u8 key_index,
8781 const u8 *mac_addr
8782 )
8783#endif
8784{
8785 int ret;
8786
8787 vos_ssr_protect(__func__);
8788#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8789 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
8790 mac_addr);
8791#else
8792 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
8793#endif
8794 vos_ssr_unprotect(__func__);
8795
8796 return ret;
8797}
8798
Jeff Johnson295189b2012-06-20 16:38:30 -07008799/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308800 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008801 * This function is used to set the default tx key index
8802 */
8803#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308804static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008805 struct net_device *ndev,
8806 u8 key_index,
8807 bool unicast, bool multicast)
8808#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308809static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008810 struct net_device *ndev,
8811 u8 key_index)
8812#endif
8813{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308814 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308815 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308816 hdd_wext_state_t *pWextState;
8817 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308818 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008819
8820 ENTER();
8821
Gopichand Nakkala29149562013-05-10 21:43:41 +05308822 if ((NULL == pAdapter))
8823 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308825 "invalid adapter");
8826 return -EINVAL;
8827 }
8828
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308829 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8830 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
8831 pAdapter->sessionId, key_index));
8832
Gopichand Nakkala29149562013-05-10 21:43:41 +05308833 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8834 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8835
8836 if ((NULL == pWextState) || (NULL == pHddStaCtx))
8837 {
8838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8839 "invalid Wext state or HDD context");
8840 return -EINVAL;
8841 }
8842
Arif Hussain6d2a3322013-11-17 19:50:10 -08008843 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008844 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308845
Jeff Johnson295189b2012-06-20 16:38:30 -07008846 if (CSR_MAX_NUM_KEY <= key_index)
8847 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308848 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008849 key_index);
8850
8851 return -EINVAL;
8852 }
8853
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308854 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8855 status = wlan_hdd_validate_context(pHddCtx);
8856
8857 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008858 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308859 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8860 "%s: HDD context is not valid", __func__);
8861 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008862 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308863
Jeff Johnson295189b2012-06-20 16:38:30 -07008864 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008865 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308866 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008867 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308868 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08008869 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308870 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08008871 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07008872 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308873 {
8874 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07008875 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308876
Jeff Johnson295189b2012-06-20 16:38:30 -07008877 tCsrRoamSetKey setKey;
8878 v_U32_t roamId= 0xFF;
8879 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308880
8881 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008882 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308883
Jeff Johnson295189b2012-06-20 16:38:30 -07008884 Keys->defaultIndex = (u8)key_index;
8885 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8886 setKey.keyId = key_index;
8887 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308888
8889 vos_mem_copy(&setKey.Key[0],
8890 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008891 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308892
Gopichand Nakkala29149562013-05-10 21:43:41 +05308893 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308894
8895 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07008896 &pHddStaCtx->conn_info.bssId[0],
8897 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308898
Gopichand Nakkala29149562013-05-10 21:43:41 +05308899 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
8900 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
8901 eCSR_ENCRYPT_TYPE_WEP104)
8902 {
8903 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
8904 even though ap is configured for WEP-40 encryption. In this canse the key length
8905 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
8906 type(104) and switching encryption type to 40*/
8907 pWextState->roamProfile.EncryptionType.encryptionType[0] =
8908 eCSR_ENCRYPT_TYPE_WEP40;
8909 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
8910 eCSR_ENCRYPT_TYPE_WEP40;
8911 }
8912
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308913 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07008914 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308915
Jeff Johnson295189b2012-06-20 16:38:30 -07008916 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308917 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008918 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308919
Jeff Johnson295189b2012-06-20 16:38:30 -07008920 if ( 0 != status )
8921 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308922 hddLog(VOS_TRACE_LEVEL_ERROR,
8923 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008924 status);
8925 return -EINVAL;
8926 }
8927 }
8928 }
8929
8930 /* In SoftAp mode setting key direction for default mode */
8931 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
8932 {
8933 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
8934 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
8935 (eCSR_ENCRYPT_TYPE_AES !=
8936 pWextState->roamProfile.EncryptionType.encryptionType[0])
8937 )
8938 {
8939 /* Saving key direction for default key index to TX default */
8940 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8941 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
8942 }
8943 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308944
Jeff Johnson295189b2012-06-20 16:38:30 -07008945 return status;
8946}
8947
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308948#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8949static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8950 struct net_device *ndev,
8951 u8 key_index,
8952 bool unicast, bool multicast)
8953#else
8954static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8955 struct net_device *ndev,
8956 u8 key_index)
8957#endif
8958{
8959 int ret;
8960 vos_ssr_protect(__func__);
8961#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8962 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
8963 multicast);
8964#else
8965 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
8966#endif
8967 vos_ssr_unprotect(__func__);
8968
8969 return ret;
8970}
8971
Jeff Johnson295189b2012-06-20 16:38:30 -07008972/*
8973 * FUNCTION: wlan_hdd_cfg80211_inform_bss
8974 * This function is used to inform the BSS details to nl80211 interface.
8975 */
8976static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
8977 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
8978{
8979 struct net_device *dev = pAdapter->dev;
8980 struct wireless_dev *wdev = dev->ieee80211_ptr;
8981 struct wiphy *wiphy = wdev->wiphy;
8982 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
8983 int chan_no;
8984 int ie_length;
8985 const char *ie;
8986 unsigned int freq;
8987 struct ieee80211_channel *chan;
8988 int rssi = 0;
8989 struct cfg80211_bss *bss = NULL;
8990
8991 ENTER();
8992
8993 if( NULL == pBssDesc )
8994 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008995 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008996 return bss;
8997 }
8998
8999 chan_no = pBssDesc->channelId;
9000 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
9001 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
9002
9003 if( NULL == ie )
9004 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009005 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009006 return bss;
9007 }
9008
9009#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9010 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9011 {
9012 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9013 }
9014 else
9015 {
9016 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9017 }
9018#else
9019 freq = ieee80211_channel_to_frequency(chan_no);
9020#endif
9021
9022 chan = __ieee80211_get_channel(wiphy, freq);
9023
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05309024 if (!chan) {
9025 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
9026 return NULL;
9027 }
9028
Abhishek Singhaee43942014-06-16 18:55:47 +05309029 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07009030
Abhishek Singhaee43942014-06-16 18:55:47 +05309031 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309032 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07009033 pBssDesc->capabilityInfo,
9034 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05309035 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07009036}
9037
9038
9039
9040/*
9041 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
9042 * This function is used to inform the BSS details to nl80211 interface.
9043 */
9044struct cfg80211_bss*
9045wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
9046 tSirBssDescription *bss_desc
9047 )
9048{
9049 /*
9050 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
9051 already exists in bss data base of cfg80211 for that particular BSS ID.
9052 Using cfg80211_inform_bss_frame to update the bss entry instead of
9053 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
9054 now there is no possibility to get the mgmt(probe response) frame from PE,
9055 converting bss_desc to ieee80211_mgmt(probe response) and passing to
9056 cfg80211_inform_bss_frame.
9057 */
9058 struct net_device *dev = pAdapter->dev;
9059 struct wireless_dev *wdev = dev->ieee80211_ptr;
9060 struct wiphy *wiphy = wdev->wiphy;
9061 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009062#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9063 qcom_ie_age *qie_age = NULL;
9064 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
9065#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009066 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009067#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009068 const char *ie =
9069 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
9070 unsigned int freq;
9071 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309072 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009073 struct cfg80211_bss *bss_status = NULL;
9074 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
9075 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07009076 hdd_context_t *pHddCtx;
9077 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07009078#ifdef WLAN_OPEN_SOURCE
9079 struct timespec ts;
9080#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009081
Wilson Yangf80a0542013-10-07 13:02:37 -07009082 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9083 status = wlan_hdd_validate_context(pHddCtx);
9084
9085 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309086 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009087 {
9088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9089 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9090 return NULL;
9091 }
9092
9093
9094 if (0 != status)
9095 {
9096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9097 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009098 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009099 }
9100
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309101 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07009102 if (!mgmt)
9103 {
9104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9105 "%s: memory allocation failed ", __func__);
9106 return NULL;
9107 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009108
Jeff Johnson295189b2012-06-20 16:38:30 -07009109 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07009110
9111#ifdef WLAN_OPEN_SOURCE
9112 /* Android does not want the timestamp from the frame.
9113 Instead it wants a monotonic increasing value */
9114 get_monotonic_boottime(&ts);
9115 mgmt->u.probe_resp.timestamp =
9116 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
9117#else
9118 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009119 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
9120 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07009121
9122#endif
9123
Jeff Johnson295189b2012-06-20 16:38:30 -07009124 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
9125 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009126
9127#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9128 /* GPS Requirement: need age ie per entry. Using vendor specific. */
9129 /* Assuming this is the last IE, copy at the end */
9130 ie_length -=sizeof(qcom_ie_age);
9131 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
9132 qie_age->element_id = QCOM_VENDOR_IE_ID;
9133 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
9134 qie_age->oui_1 = QCOM_OUI1;
9135 qie_age->oui_2 = QCOM_OUI2;
9136 qie_age->oui_3 = QCOM_OUI3;
9137 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
9138 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
9139#endif
9140
Jeff Johnson295189b2012-06-20 16:38:30 -07009141 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05309142 if (bss_desc->fProbeRsp)
9143 {
9144 mgmt->frame_control |=
9145 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
9146 }
9147 else
9148 {
9149 mgmt->frame_control |=
9150 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
9151 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009152
9153#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309154 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009155 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
9156 {
9157 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9158 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309159 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009160 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
9161
9162 {
9163 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9164 }
9165 else
9166 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309167 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
9168 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07009169 kfree(mgmt);
9170 return NULL;
9171 }
9172#else
9173 freq = ieee80211_channel_to_frequency(chan_no);
9174#endif
9175 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009176 /*when the band is changed on the fly using the GUI, three things are done
9177 * 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)
9178 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
9179 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
9180 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
9181 * and discards the channels correponding to previous band and calls back with zero bss results.
9182 * 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
9183 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
9184 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
9185 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
9186 * So drop the bss and continue to next bss.
9187 */
9188 if(chan == NULL)
9189 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309190 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07009191 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009192 return NULL;
9193 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009194 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309195 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07009196 * */
9197 if (( eConnectionState_Associated ==
9198 pAdapter->sessionCtx.station.conn_info.connState ) &&
9199 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
9200 pAdapter->sessionCtx.station.conn_info.bssId,
9201 WNI_CFG_BSSID_LEN)))
9202 {
9203 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
9204 rssi = (pAdapter->rssi * 100);
9205 }
9206 else
9207 {
9208 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
9209 }
9210
Nirav Shah20ac06f2013-12-12 18:14:06 +05309211 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
9212 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
9213 chan->center_freq, (int)(rssi/100));
9214
Jeff Johnson295189b2012-06-20 16:38:30 -07009215 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
9216 frame_len, rssi, GFP_KERNEL);
9217 kfree(mgmt);
9218 return bss_status;
9219}
9220
9221/*
9222 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
9223 * This function is used to update the BSS data base of CFG8011
9224 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309225struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009226 tCsrRoamInfo *pRoamInfo
9227 )
9228{
9229 tCsrRoamConnectedProfile roamProfile;
9230 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9231 struct cfg80211_bss *bss = NULL;
9232
9233 ENTER();
9234
9235 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
9236 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
9237
9238 if (NULL != roamProfile.pBssDesc)
9239 {
Girish Gowlif4b68022014-08-28 23:18:57 +05309240 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9241 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009242
9243 if (NULL == bss)
9244 {
9245 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
9246 __func__);
9247 }
9248
9249 sme_RoamFreeConnectProfile(hHal, &roamProfile);
9250 }
9251 else
9252 {
9253 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
9254 __func__);
9255 }
9256 return bss;
9257}
9258
9259/*
9260 * FUNCTION: wlan_hdd_cfg80211_update_bss
9261 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309262static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
9263 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07009264 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309265{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309266 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009267 tCsrScanResultInfo *pScanResult;
9268 eHalStatus status = 0;
9269 tScanResultHandle pResult;
9270 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009271 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009272
9273 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309274
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309275 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9276 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
9277 NO_SESSION, pAdapter->sessionId));
9278
Wilson Yangf80a0542013-10-07 13:02:37 -07009279 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9280
9281 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009282 {
Wilson Yangf80a0542013-10-07 13:02:37 -07009283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9284 "%s:LOGP in Progress. Ignore!!!",__func__);
9285 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009286 }
9287
Wilson Yangf80a0542013-10-07 13:02:37 -07009288
9289 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309290 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009291 {
9292 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9293 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9294 return VOS_STATUS_E_PERM;
9295 }
9296
9297
Jeff Johnson295189b2012-06-20 16:38:30 -07009298 /*
9299 * start getting scan results and populate cgf80211 BSS database
9300 */
9301 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
9302
9303 /* no scan results */
9304 if (NULL == pResult)
9305 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309306 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
9307 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009308 return status;
9309 }
9310
9311 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
9312
9313 while (pScanResult)
9314 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309315 /*
9316 * cfg80211_inform_bss() is not updating ie field of bss entry, if
9317 * entry already exists in bss data base of cfg80211 for that
9318 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
9319 * bss entry instead of cfg80211_inform_bss, But this call expects
9320 * mgmt packet as input. As of now there is no possibility to get
9321 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07009322 * ieee80211_mgmt(probe response) and passing to c
9323 * fg80211_inform_bss_frame.
9324 * */
9325
9326 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9327 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309328
Jeff Johnson295189b2012-06-20 16:38:30 -07009329
9330 if (NULL == bss_status)
9331 {
9332 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009333 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009334 }
9335 else
9336 {
Yue Maf49ba872013-08-19 12:04:25 -07009337 cfg80211_put_bss(
9338#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
9339 wiphy,
9340#endif
9341 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009342 }
9343
9344 pScanResult = sme_ScanResultGetNext(hHal, pResult);
9345 }
9346
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309347 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07009348
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309349 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009350}
9351
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009352void
9353hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
9354{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309355 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08009356 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009357} /****** end hddPrintMacAddr() ******/
9358
9359void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009360hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009361{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309362 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009363 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009364 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
9365 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
9366 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009367} /****** end hddPrintPmkId() ******/
9368
9369//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
9370//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
9371
9372//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
9373//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
9374
9375#define dump_bssid(bssid) \
9376 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009377 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
9378 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009379 }
9380
9381#define dump_pmkid(pMac, pmkid) \
9382 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009383 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
9384 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009385 }
9386
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009387#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009388/*
9389 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
9390 * This function is used to notify the supplicant of a new PMKSA candidate.
9391 */
9392int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309393 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009394 int index, bool preauth )
9395{
Jeff Johnsone7245742012-09-05 17:12:55 -07009396#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009397 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009398 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009399
9400 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07009401 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009402
9403 if( NULL == pRoamInfo )
9404 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009405 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009406 return -EINVAL;
9407 }
9408
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009409 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
9410 {
9411 dump_bssid(pRoamInfo->bssid);
9412 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009413 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009414 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009415#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309416 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009417}
9418#endif //FEATURE_WLAN_LFR
9419
Yue Maef608272013-04-08 23:09:17 -07009420#ifdef FEATURE_WLAN_LFR_METRICS
9421/*
9422 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
9423 * 802.11r/LFR metrics reporting function to report preauth initiation
9424 *
9425 */
9426#define MAX_LFR_METRICS_EVENT_LENGTH 100
9427VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
9428 tCsrRoamInfo *pRoamInfo)
9429{
9430 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9431 union iwreq_data wrqu;
9432
9433 ENTER();
9434
9435 if (NULL == pAdapter)
9436 {
9437 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9438 return VOS_STATUS_E_FAILURE;
9439 }
9440
9441 /* create the event */
9442 memset(&wrqu, 0, sizeof(wrqu));
9443 memset(metrics_notification, 0, sizeof(metrics_notification));
9444
9445 wrqu.data.pointer = metrics_notification;
9446 wrqu.data.length = scnprintf(metrics_notification,
9447 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
9448 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9449
9450 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9451
9452 EXIT();
9453
9454 return VOS_STATUS_SUCCESS;
9455}
9456
9457/*
9458 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
9459 * 802.11r/LFR metrics reporting function to report preauth completion
9460 * or failure
9461 */
9462VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
9463 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
9464{
9465 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9466 union iwreq_data wrqu;
9467
9468 ENTER();
9469
9470 if (NULL == pAdapter)
9471 {
9472 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9473 return VOS_STATUS_E_FAILURE;
9474 }
9475
9476 /* create the event */
9477 memset(&wrqu, 0, sizeof(wrqu));
9478 memset(metrics_notification, 0, sizeof(metrics_notification));
9479
9480 scnprintf(metrics_notification, sizeof(metrics_notification),
9481 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
9482 MAC_ADDR_ARRAY(pRoamInfo->bssid));
9483
9484 if (1 == preauth_status)
9485 strncat(metrics_notification, " TRUE", 5);
9486 else
9487 strncat(metrics_notification, " FALSE", 6);
9488
9489 wrqu.data.pointer = metrics_notification;
9490 wrqu.data.length = strlen(metrics_notification);
9491
9492 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9493
9494 EXIT();
9495
9496 return VOS_STATUS_SUCCESS;
9497}
9498
9499/*
9500 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
9501 * 802.11r/LFR metrics reporting function to report handover initiation
9502 *
9503 */
9504VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
9505 tCsrRoamInfo *pRoamInfo)
9506{
9507 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9508 union iwreq_data wrqu;
9509
9510 ENTER();
9511
9512 if (NULL == pAdapter)
9513 {
9514 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9515 return VOS_STATUS_E_FAILURE;
9516 }
9517
9518 /* create the event */
9519 memset(&wrqu, 0, sizeof(wrqu));
9520 memset(metrics_notification, 0, sizeof(metrics_notification));
9521
9522 wrqu.data.pointer = metrics_notification;
9523 wrqu.data.length = scnprintf(metrics_notification,
9524 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
9525 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9526
9527 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9528
9529 EXIT();
9530
9531 return VOS_STATUS_SUCCESS;
9532}
9533#endif
9534
Jeff Johnson295189b2012-06-20 16:38:30 -07009535/*
9536 * FUNCTION: hdd_cfg80211_scan_done_callback
9537 * scanning callback function, called after finishing scan
9538 *
9539 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309540static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07009541 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
9542{
9543 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309544 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009545 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009546 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9547 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07009548 struct cfg80211_scan_request *req = NULL;
9549 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309550 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309551 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +05309552 tANI_U8 i;
Jeff Johnson295189b2012-06-20 16:38:30 -07009553
9554 ENTER();
9555
9556 hddLog(VOS_TRACE_LEVEL_INFO,
9557 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08009558 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009559 __func__, halHandle, pContext, (int) scanId, (int) status);
9560
Kiet Lamac06e2c2013-10-23 16:25:07 +05309561 pScanInfo->mScanPendingCounter = 0;
9562
Jeff Johnson295189b2012-06-20 16:38:30 -07009563 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309564 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009565 &pScanInfo->scan_req_completion_event,
9566 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309567 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009568 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309569 hddLog(VOS_TRACE_LEVEL_ERROR,
9570 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07009571 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009572 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009573 }
9574
Yue Maef608272013-04-08 23:09:17 -07009575 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07009576 {
9577 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009578 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009579 }
9580
9581 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309582 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07009583 {
9584 hddLog(VOS_TRACE_LEVEL_INFO,
9585 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009586 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07009587 (int) scanId);
9588 }
9589
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309590 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009591 pAdapter);
9592
9593 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309594 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009595
9596
9597 /* If any client wait scan result through WEXT
9598 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009599 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07009600 {
9601 /* The other scan request waiting for current scan finish
9602 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009603 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009604 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009605 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07009606 }
9607 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009608 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009609 {
9610 struct net_device *dev = pAdapter->dev;
9611 union iwreq_data wrqu;
9612 int we_event;
9613 char *msg;
9614
9615 memset(&wrqu, '\0', sizeof(wrqu));
9616 we_event = SIOCGIWSCAN;
9617 msg = NULL;
9618 wireless_send_event(dev, we_event, &wrqu, msg);
9619 }
9620 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009621 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009622
9623 /* Get the Scan Req */
9624 req = pAdapter->request;
9625
9626 if (!req)
9627 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009628 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009629 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07009630 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009631 }
9632
Jeff Johnson295189b2012-06-20 16:38:30 -07009633 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009634 /* Scan is no longer pending */
9635 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009636
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +05309637 /* last_scan_timestamp is used to decide if new scan
9638 * is needed or not on station interface. If last station
9639 * scan time and new station scan time is less then
9640 * last_scan_timestamp ; driver will return cached scan.
9641 */
9642 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
9643 {
9644 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
9645
9646 if ( req->n_channels )
9647 {
9648 for (i = 0; i < req->n_channels ; i++ )
9649 {
9650 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
9651 }
9652 /* store no of channel scanned */
9653 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
9654 }
9655
9656 }
9657
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07009658 /*
9659 * cfg80211_scan_done informing NL80211 about completion
9660 * of scanning
9661 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309662 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
9663 {
9664 aborted = true;
9665 }
9666 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009667 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07009668
Siddharth Bhal76972212014-10-15 16:22:51 +05309669 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
9670 /* Generate new random mac addr for next scan */
9671 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
9672 hdd_processSpoofMacAddrRequest(pHddCtx);
9673 }
9674
Jeff Johnsone7245742012-09-05 17:12:55 -07009675allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009676 /* release the wake lock at the end of the scan*/
9677 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009678
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009679 /* Acquire wakelock to handle the case where APP's tries to suspend
9680 * immediatly after the driver gets connect request(i.e after scan)
9681 * from supplicant, this result in app's is suspending and not able
9682 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309683 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009684
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009685#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05309686 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
9687 {
9688 wlan_hdd_tdls_scan_done_callback(pAdapter);
9689 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009690#endif
9691
Jeff Johnson295189b2012-06-20 16:38:30 -07009692 EXIT();
9693 return 0;
9694}
9695
9696/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05309697 * FUNCTION: hdd_isConnectionInProgress
9698 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009699 *
9700 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +05309701v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009702{
9703 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9704 hdd_station_ctx_t *pHddStaCtx = NULL;
9705 hdd_adapter_t *pAdapter = NULL;
9706 VOS_STATUS status = 0;
9707 v_U8_t staId = 0;
9708 v_U8_t *staMac = NULL;
9709
c_hpothu9b781ba2013-12-30 20:57:45 +05309710 if (TRUE == pHddCtx->btCoexModeSet)
9711 {
9712 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05309713 FL("BTCoex Mode operation in progress"));
9714 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05309715 }
9716
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009717 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9718
9719 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9720 {
9721 pAdapter = pAdapterNode->pAdapter;
9722
9723 if( pAdapter )
9724 {
9725 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309726 "%s: Adapter with device mode %s (%d) exists",
9727 __func__, hdd_device_modetoString(pAdapter->device_mode),
9728 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +05309729 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +05309730 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9731 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
9732 (eConnectionState_Connecting ==
9733 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
9734 {
9735 hddLog(VOS_TRACE_LEVEL_ERROR,
9736 "%s: %p(%d) Connection is in progress", __func__,
9737 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
9738 return VOS_TRUE;
9739 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +05309740 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
9741 smeNeighborRoamIsHandoffInProgress(WLAN_HDD_GET_HAL_CTX(pAdapter)))
9742 {
9743 hddLog(VOS_TRACE_LEVEL_ERROR,
9744 "%s: %p(%d) Reassociation is in progress", __func__,
9745 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
9746 return VOS_TRUE;
9747 }
9748 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309749 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9750 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009751 {
9752 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9753 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309754 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009755 {
9756 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
9757 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009758 "%s: client " MAC_ADDRESS_STR
9759 " is in the middle of WPS/EAPOL exchange.", __func__,
9760 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309761 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009762 }
9763 }
9764 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
9765 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
9766 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05309767 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9768 ptSapContext pSapCtx = NULL;
9769 pSapCtx = VOS_GET_SAP_CB(pVosContext);
9770 if(pSapCtx == NULL){
9771 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9772 FL("psapCtx is NULL"));
9773 return VOS_FALSE;
9774 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009775 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
9776 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05309777 if ((pSapCtx->aStaInfo[staId].isUsed) &&
9778 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009779 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05309780 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009781
9782 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009783 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
9784 "middle of WPS/EAPOL exchange.", __func__,
9785 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309786 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009787 }
9788 }
9789 }
9790 }
9791 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9792 pAdapterNode = pNext;
9793 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05309794 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309795}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009796
9797/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309798 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07009799 * this scan respond to scan trigger and update cfg80211 scan database
9800 * later, scan dump command can be used to recieve scan results
9801 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309802int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009803#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9804 struct net_device *dev,
9805#endif
9806 struct cfg80211_scan_request *request)
9807{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309808 hdd_adapter_t *pAdapter = NULL;
9809 hdd_context_t *pHddCtx = NULL;
9810 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309811 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009812 tCsrScanRequest scanRequest;
9813 tANI_U8 *channelList = NULL, i;
9814 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309815 int status;
9816 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009817 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +05309818 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009819
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309820#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
9821 struct net_device *dev = NULL;
9822 if (NULL == request)
9823 {
9824 hddLog(VOS_TRACE_LEVEL_ERROR,
9825 "%s: scan req param null", __func__);
9826 return -EINVAL;
9827 }
9828 dev = request->wdev->netdev;
9829#endif
9830
9831 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
9832 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9833 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9834
Jeff Johnson295189b2012-06-20 16:38:30 -07009835 ENTER();
9836
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309837
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309838 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9839 __func__, hdd_device_modetoString(pAdapter->device_mode),
9840 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309841
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309842 status = wlan_hdd_validate_context(pHddCtx);
9843
9844 if (0 != status)
9845 {
9846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9847 "%s: HDD context is not valid", __func__);
9848 return status;
9849 }
9850
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309851 if (NULL == pwextBuf)
9852 {
9853 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
9854 __func__);
9855 return -EIO;
9856 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309857 cfg_param = pHddCtx->cfg_ini;
9858 pScanInfo = &pHddCtx->scan_info;
9859
Jeff Johnson295189b2012-06-20 16:38:30 -07009860#ifdef WLAN_BTAMP_FEATURE
9861 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009862 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07009863 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009864 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009865 "%s: No scanning when AMP is on", __func__);
9866 return -EOPNOTSUPP;
9867 }
9868#endif
9869 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009870 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009871 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009872 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309873 "%s: Not scanning on device_mode = %s (%d)",
9874 __func__, hdd_device_modetoString(pAdapter->device_mode),
9875 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009876 return -EOPNOTSUPP;
9877 }
9878
9879 if (TRUE == pScanInfo->mScanPending)
9880 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309881 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
9882 {
9883 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
9884 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009885 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009886 }
9887
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309888 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07009889 //Channel and action frame is pending
9890 //Otherwise Cancel Remain On Channel and allow Scan
9891 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009892 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07009893 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309894 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009895 return -EBUSY;
9896 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009897#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009898 /* if tdls disagree scan right now, return immediately.
9899 tdls will schedule the scan when scan is allowed. (return SUCCESS)
9900 or will reject the scan if any TDLS is in progress. (return -EBUSY)
9901 */
9902 status = wlan_hdd_tdls_scan_callback (pAdapter,
9903 wiphy,
9904#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9905 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07009906#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009907 request);
9908 if(status <= 0)
9909 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309910 if(!status)
9911 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
9912 "scan rejected %d", __func__, status);
9913 else
9914 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
9915 __func__, status);
9916
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009917 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009918 }
9919#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07009920
Jeff Johnson295189b2012-06-20 16:38:30 -07009921 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
9922 {
9923 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08009924 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009925 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309926 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009927 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
9928 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309929 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009930 "%s: MAX TM Level Scan not allowed", __func__);
9931 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309932 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009933 }
9934 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
9935
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009936 /* Check if scan is allowed at this point of time.
9937 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +05309938 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009939 {
9940 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
9941 return -EBUSY;
9942 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309943
Jeff Johnson295189b2012-06-20 16:38:30 -07009944 vos_mem_zero( &scanRequest, sizeof(scanRequest));
9945
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309946 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
9947 (int)request->n_ssids);
9948
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +05309949
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309950 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
9951 * Becasue of this, driver is assuming that this is not wildcard scan and so
9952 * is not aging out the scan results.
9953 */
9954 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07009955 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309956 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009957 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309958
9959 if ((request->ssids) && (0 < request->n_ssids))
9960 {
9961 tCsrSSIDInfo *SsidInfo;
9962 int j;
9963 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
9964 /* Allocate num_ssid tCsrSSIDInfo structure */
9965 SsidInfo = scanRequest.SSIDs.SSIDList =
9966 ( tCsrSSIDInfo *)vos_mem_malloc(
9967 request->n_ssids*sizeof(tCsrSSIDInfo));
9968
9969 if(NULL == scanRequest.SSIDs.SSIDList)
9970 {
9971 hddLog(VOS_TRACE_LEVEL_ERROR,
9972 "%s: memory alloc failed SSIDInfo buffer", __func__);
9973 return -ENOMEM;
9974 }
9975
9976 /* copy all the ssid's and their length */
9977 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
9978 {
9979 /* get the ssid length */
9980 SsidInfo->SSID.length = request->ssids[j].ssid_len;
9981 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
9982 SsidInfo->SSID.length);
9983 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
9984 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
9985 j, SsidInfo->SSID.ssId);
9986 }
9987 /* set the scan type to active */
9988 scanRequest.scanType = eSIR_ACTIVE_SCAN;
9989 }
9990 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07009991 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309992 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9993 TRACE_CODE_HDD_CFG80211_SCAN,
9994 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07009995 /* set the scan type to active */
9996 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009997 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309998 else
9999 {
10000 /*Set the scan type to default type, in this case it is ACTIVE*/
10001 scanRequest.scanType = pScanInfo->scan_mode;
10002 }
10003 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
10004 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070010005
10006 /* set BSSType to default type */
10007 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
10008
10009 /*TODO: scan the requested channels only*/
10010
10011 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010012 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070010013 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010014 hddLog(VOS_TRACE_LEVEL_WARN,
10015 "No of Scan Channels exceeded limit: %d", request->n_channels);
10016 request->n_channels = MAX_CHANNEL;
10017 }
10018
10019 hddLog(VOS_TRACE_LEVEL_INFO,
10020 "No of Scan Channels: %d", request->n_channels);
10021
10022
10023 if( request->n_channels )
10024 {
10025 char chList [(request->n_channels*5)+1];
10026 int len;
10027 channelList = vos_mem_malloc( request->n_channels );
10028 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053010029 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010030 hddLog(VOS_TRACE_LEVEL_ERROR,
10031 "%s: memory alloc failed channelList", __func__);
10032 status = -ENOMEM;
10033 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053010034 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010035
10036 for( i = 0, len = 0; i < request->n_channels ; i++ )
10037 {
10038 channelList[i] = request->channels[i]->hw_value;
10039 len += snprintf(chList+len, 5, "%d ", channelList[i]);
10040 }
10041
Nirav Shah20ac06f2013-12-12 18:14:06 +053010042 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010043 "Channel-List: %s ", chList);
10044 }
c_hpothu53512302014-04-15 18:49:53 +053010045
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010046 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
10047 scanRequest.ChannelInfo.ChannelList = channelList;
10048
10049 /* set requestType to full scan */
10050 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10051
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010052 /* if there is back to back scan happening in driver with in
10053 * nDeferScanTimeInterval interval driver should defer new scan request
10054 * and should provide last cached scan results instead of new channel list.
10055 * This rule is not applicable if scan is p2p scan.
10056 * This condition will work only in case when last request no of channels
10057 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053010058 * This should be done only in connected state
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010059 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010060
Agarwal Ashish57e84372014-12-05 18:26:53 +053010061 if ((VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
10062 {
10063 if ( pScanInfo->last_scan_timestamp !=0 &&
10064 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
10065 {
10066 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
10067 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
10068 vos_mem_compare(pScanInfo->last_scan_channelList,
10069 channelList, pScanInfo->last_scan_numChannels))
10070 {
10071 hddLog(VOS_TRACE_LEVEL_WARN,
10072 " New and old station scan time differ is less then %u",
10073 pHddCtx->cfg_ini->nDeferScanTimeInterval);
10074
10075 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010076 pAdapter);
10077
Agarwal Ashish57e84372014-12-05 18:26:53 +053010078 hddLog(VOS_TRACE_LEVEL_WARN,
10079 "Return old cached scan as all channels"
10080 "and no of channles are same");
10081 if (0 > ret)
10082 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010083
Agarwal Ashish57e84372014-12-05 18:26:53 +053010084 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
10085 return eHAL_STATUS_SUCCESS ;
10086 }
10087 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010088 }
10089
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010090 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10091 * search (Flush on both full scan and social scan but not on single
10092 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10093 */
10094
10095 /* Supplicant does single channel scan after 8-way handshake
10096 * and in that case driver shoudnt flush scan results. If
10097 * driver flushes the scan results here and unfortunately if
10098 * the AP doesnt respond to our probe req then association
10099 * fails which is not desired
10100 */
10101
10102 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
10103 {
10104 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
10105 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
10106 pAdapter->sessionId );
10107 }
10108
10109 if( request->ie_len )
10110 {
10111 /* save this for future association (join requires this) */
10112 /*TODO: Array needs to be converted to dynamic allocation,
10113 * as multiple ie.s can be sent in cfg80211_scan_request structure
10114 * CR 597966
10115 */
10116 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
10117 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
10118 pScanInfo->scanAddIE.length = request->ie_len;
10119
10120 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10121 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10122 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010123 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010124 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070010125 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010126 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
10127 memcpy( pwextBuf->roamProfile.addIEScan,
10128 request->ie, request->ie_len);
10129 }
10130 else
10131 {
10132 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
10133 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070010134 }
10135
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010136 }
10137 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
10138 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
10139
10140 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
10141 request->ie_len);
10142 if (pP2pIe != NULL)
10143 {
10144#ifdef WLAN_FEATURE_P2P_DEBUG
10145 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
10146 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
10147 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053010148 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010149 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
10150 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10151 "Go nego completed to Connection is started");
10152 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10153 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053010154 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010155 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
10156 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010157 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010158 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
10159 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10160 "Disconnected state to Connection is started");
10161 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10162 "for 4way Handshake");
10163 }
10164#endif
10165
10166 /* no_cck will be set during p2p find to disable 11b rates */
10167 if(TRUE == request->no_cck)
10168 {
10169 hddLog(VOS_TRACE_LEVEL_INFO,
10170 "%s: This is a P2P Search", __func__);
10171 scanRequest.p2pSearch = 1;
10172
10173 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053010174 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010175 /* set requestType to P2P Discovery */
10176 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
10177 }
10178
10179 /*
10180 Skip Dfs Channel in case of P2P Search
10181 if it is set in ini file
10182 */
10183 if(cfg_param->skipDfsChnlInP2pSearch)
10184 {
10185 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010186 }
10187 else
10188 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010189 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010190 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010191
Agarwal Ashish4f616132013-12-30 23:32:50 +053010192 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010193 }
10194 }
10195
10196 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
10197
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010198 /* acquire the wakelock to avoid the apps suspend during the scan. To
10199 * address the following issues.
10200 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
10201 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
10202 * for long time, this result in apps running at full power for long time.
10203 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
10204 * be stuck in full power because of resume BMPS
10205 */
10206 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -070010207
Nirav Shah20ac06f2013-12-12 18:14:06 +053010208 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10209 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010210 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
10211 scanRequest.requestType, scanRequest.scanType,
10212 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053010213 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
10214
Siddharth Bhal76972212014-10-15 16:22:51 +053010215 if (pHddCtx->spoofMacAddr.isEnabled)
10216 {
10217 hddLog(VOS_TRACE_LEVEL_INFO,
10218 "%s: MAC Spoofing enabled for current scan", __func__);
10219 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
10220 * to fill TxBds for probe request during current scan
10221 */
10222 WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
10223 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
10224 }
10225
Jeff Johnsone7245742012-09-05 17:12:55 -070010226 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010227 pAdapter->sessionId, &scanRequest, &scanId,
10228 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070010229
Jeff Johnson295189b2012-06-20 16:38:30 -070010230 if (eHAL_STATUS_SUCCESS != status)
10231 {
10232 hddLog(VOS_TRACE_LEVEL_ERROR,
10233 "%s: sme_ScanRequest returned error %d", __func__, status);
10234 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010235 if(eHAL_STATUS_RESOURCES == status)
10236 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010237 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
10238 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010239 status = -EBUSY;
10240 } else {
10241 status = -EIO;
10242 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010243 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -070010244 goto free_mem;
10245 }
10246
10247 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010248 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070010249 pAdapter->request = request;
10250 pScanInfo->scanId = scanId;
10251
10252 complete(&pScanInfo->scan_req_completion_event);
10253
10254free_mem:
10255 if( scanRequest.SSIDs.SSIDList )
10256 {
10257 vos_mem_free(scanRequest.SSIDs.SSIDList);
10258 }
10259
10260 if( channelList )
10261 vos_mem_free( channelList );
10262
10263 EXIT();
10264
10265 return status;
10266}
10267
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010268int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
10269#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10270 struct net_device *dev,
10271#endif
10272 struct cfg80211_scan_request *request)
10273{
10274 int ret;
10275
10276 vos_ssr_protect(__func__);
10277 ret = __wlan_hdd_cfg80211_scan(wiphy,
10278#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10279 dev,
10280#endif
10281 request);
10282 vos_ssr_unprotect(__func__);
10283
10284 return ret;
10285}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010286
10287void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
10288{
10289 v_U8_t iniDot11Mode =
10290 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
10291 eHddDot11Mode hddDot11Mode = iniDot11Mode;
10292
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010293 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
10294 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010295 switch ( iniDot11Mode )
10296 {
10297 case eHDD_DOT11_MODE_AUTO:
10298 case eHDD_DOT11_MODE_11ac:
10299 case eHDD_DOT11_MODE_11ac_ONLY:
10300#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053010301 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
10302 sme_IsFeatureSupportedByFW(DOT11AC) )
10303 hddDot11Mode = eHDD_DOT11_MODE_11ac;
10304 else
10305 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010306#else
10307 hddDot11Mode = eHDD_DOT11_MODE_11n;
10308#endif
10309 break;
10310 case eHDD_DOT11_MODE_11n:
10311 case eHDD_DOT11_MODE_11n_ONLY:
10312 hddDot11Mode = eHDD_DOT11_MODE_11n;
10313 break;
10314 default:
10315 hddDot11Mode = iniDot11Mode;
10316 break;
10317 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010318#ifdef WLAN_FEATURE_AP_HT40_24G
10319 if (operationChannel > SIR_11B_CHANNEL_END)
10320#endif
10321 {
10322 /* This call decides required channel bonding mode */
10323 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010324 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
10325 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010326 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010327}
10328
Jeff Johnson295189b2012-06-20 16:38:30 -070010329/*
10330 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010331 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010332 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010333int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010334 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010335{
10336 int status = 0;
10337 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080010338 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010339 v_U32_t roamId;
10340 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070010341 eCsrAuthType RSNAuthType;
10342
10343 ENTER();
10344
10345 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080010346 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10347
10348 status = wlan_hdd_validate_context(pHddCtx);
10349 if (status)
10350 {
10351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10352 "%s: HDD context is not valid!", __func__);
10353 return status;
10354 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010355
Jeff Johnson295189b2012-06-20 16:38:30 -070010356 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
10357 {
10358 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
10359 return -EINVAL;
10360 }
10361
10362 pRoamProfile = &pWextState->roamProfile;
10363
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010364 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070010365 {
Jeff Johnsone7245742012-09-05 17:12:55 -070010366 hdd_station_ctx_t *pHddStaCtx;
10367 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010368
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010369 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070010370 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
10371 {
10372 /*QoS not enabled in cfg file*/
10373 pRoamProfile->uapsd_mask = 0;
10374 }
10375 else
10376 {
10377 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010378 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070010379 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
10380 }
10381
10382 pRoamProfile->SSIDs.numOfSSIDs = 1;
10383 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
10384 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010385 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070010386 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
10387 ssid, ssid_len);
10388
10389 if (bssid)
10390 {
10391 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
10392 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
10393 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010394 /* Save BSSID in seperate variable as well, as RoamProfile
10395 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070010396 case of join failure we should send valid BSSID to supplicant
10397 */
10398 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
10399 WNI_CFG_BSSID_LEN);
10400 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070010401 else
10402 {
10403 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
10404 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010405
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010406 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
10407 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010408 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
10409 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010410 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010411 /*set gen ie*/
10412 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
10413 /*set auth*/
10414 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
10415 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010416#ifdef FEATURE_WLAN_WAPI
10417 if (pAdapter->wapi_info.nWapiMode)
10418 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010419 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010420 switch (pAdapter->wapi_info.wapiAuthMode)
10421 {
10422 case WAPI_AUTH_MODE_PSK:
10423 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010424 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010425 pAdapter->wapi_info.wapiAuthMode);
10426 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
10427 break;
10428 }
10429 case WAPI_AUTH_MODE_CERT:
10430 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010431 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010432 pAdapter->wapi_info.wapiAuthMode);
10433 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
10434 break;
10435 }
10436 } // End of switch
10437 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
10438 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
10439 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010440 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010441 pRoamProfile->AuthType.numEntries = 1;
10442 pRoamProfile->EncryptionType.numEntries = 1;
10443 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10444 pRoamProfile->mcEncryptionType.numEntries = 1;
10445 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10446 }
10447 }
10448#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010449#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010450 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010451 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10452 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
10453 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010454 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
10455 sizeof (tSirGtkOffloadParams));
10456 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010457 }
10458#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010459 pRoamProfile->csrPersona = pAdapter->device_mode;
10460
Jeff Johnson32d95a32012-09-10 13:15:23 -070010461 if( operatingChannel )
10462 {
10463 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
10464 pRoamProfile->ChannelInfo.numOfChannels = 1;
10465 }
Chet Lanctot186b5732013-03-18 10:26:30 -070010466 else
10467 {
10468 pRoamProfile->ChannelInfo.ChannelList = NULL;
10469 pRoamProfile->ChannelInfo.numOfChannels = 0;
10470 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010471 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
10472 {
10473 hdd_select_cbmode(pAdapter,operatingChannel);
10474 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010475
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010476 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
10477 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010478 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010479 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010480 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
10481 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010482 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10483 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053010484 {
10485 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10486 "%s: Set HDD connState to eConnectionState_Connecting",
10487 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010488 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
10489 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053010490 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010491 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010492 pAdapter->sessionId, pRoamProfile, &roamId);
10493
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010494 if ((eHAL_STATUS_SUCCESS != status) &&
10495 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10496 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010497
10498 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010499 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
10500 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
10501 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010502 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010503 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010504 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010505
10506 pRoamProfile->ChannelInfo.ChannelList = NULL;
10507 pRoamProfile->ChannelInfo.numOfChannels = 0;
10508
Jeff Johnson295189b2012-06-20 16:38:30 -070010509 }
10510 else
10511 {
10512 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
10513 return -EINVAL;
10514 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010515 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010516 return status;
10517}
10518
10519/*
10520 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
10521 * This function is used to set the authentication type (OPEN/SHARED).
10522 *
10523 */
10524static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
10525 enum nl80211_auth_type auth_type)
10526{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010527 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010528 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10529
10530 ENTER();
10531
10532 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010533 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070010534 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010535 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010536 hddLog(VOS_TRACE_LEVEL_INFO,
10537 "%s: set authentication type to AUTOSWITCH", __func__);
10538 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
10539 break;
10540
10541 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010542#ifdef WLAN_FEATURE_VOWIFI_11R
10543 case NL80211_AUTHTYPE_FT:
10544#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010545 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010546 "%s: set authentication type to OPEN", __func__);
10547 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
10548 break;
10549
10550 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010551 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010552 "%s: set authentication type to SHARED", __func__);
10553 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
10554 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010555#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010556 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010557 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010558 "%s: set authentication type to CCKM WPA", __func__);
10559 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
10560 break;
10561#endif
10562
10563
10564 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010565 hddLog(VOS_TRACE_LEVEL_ERROR,
10566 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010567 auth_type);
10568 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
10569 return -EINVAL;
10570 }
10571
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010572 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010573 pHddStaCtx->conn_info.authType;
10574 return 0;
10575}
10576
10577/*
10578 * FUNCTION: wlan_hdd_set_akm_suite
10579 * This function is used to set the key mgmt type(PSK/8021x).
10580 *
10581 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010582static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010583 u32 key_mgmt
10584 )
10585{
10586 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10587 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053010588 /* Should be in ieee802_11_defs.h */
10589#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
10590#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070010591 /*set key mgmt type*/
10592 switch(key_mgmt)
10593 {
10594 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053010595 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010596#ifdef WLAN_FEATURE_VOWIFI_11R
10597 case WLAN_AKM_SUITE_FT_PSK:
10598#endif
10599 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070010600 __func__);
10601 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
10602 break;
10603
10604 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053010605 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010606#ifdef WLAN_FEATURE_VOWIFI_11R
10607 case WLAN_AKM_SUITE_FT_8021X:
10608#endif
10609 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070010610 __func__);
10611 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10612 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010613#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010614#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
10615#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
10616 case WLAN_AKM_SUITE_CCKM:
10617 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
10618 __func__);
10619 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
10620 break;
10621#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070010622#ifndef WLAN_AKM_SUITE_OSEN
10623#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
10624 case WLAN_AKM_SUITE_OSEN:
10625 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
10626 __func__);
10627 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10628 break;
10629#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010630
10631 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010632 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010633 __func__, key_mgmt);
10634 return -EINVAL;
10635
10636 }
10637 return 0;
10638}
10639
10640/*
10641 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010642 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070010643 * (NONE/WEP40/WEP104/TKIP/CCMP).
10644 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010645static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
10646 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070010647 bool ucast
10648 )
10649{
10650 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010651 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010652 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10653
10654 ENTER();
10655
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010656 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010657 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010658 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070010659 __func__, cipher);
10660 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10661 }
10662 else
10663 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010664
Jeff Johnson295189b2012-06-20 16:38:30 -070010665 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010666 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010667 {
10668 case IW_AUTH_CIPHER_NONE:
10669 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10670 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010671
Jeff Johnson295189b2012-06-20 16:38:30 -070010672 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010673 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070010674 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010675
Jeff Johnson295189b2012-06-20 16:38:30 -070010676 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010677 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070010678 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010679
Jeff Johnson295189b2012-06-20 16:38:30 -070010680 case WLAN_CIPHER_SUITE_TKIP:
10681 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
10682 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010683
Jeff Johnson295189b2012-06-20 16:38:30 -070010684 case WLAN_CIPHER_SUITE_CCMP:
10685 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10686 break;
10687#ifdef FEATURE_WLAN_WAPI
10688 case WLAN_CIPHER_SUITE_SMS4:
10689 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
10690 break;
10691#endif
10692
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010693#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010694 case WLAN_CIPHER_SUITE_KRK:
10695 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
10696 break;
10697#endif
10698 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010699 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010700 __func__, cipher);
10701 return -EOPNOTSUPP;
10702 }
10703 }
10704
10705 if (ucast)
10706 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010707 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010708 __func__, encryptionType);
10709 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10710 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010711 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010712 encryptionType;
10713 }
10714 else
10715 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010716 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010717 __func__, encryptionType);
10718 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
10719 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
10720 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
10721 }
10722
10723 return 0;
10724}
10725
10726
10727/*
10728 * FUNCTION: wlan_hdd_cfg80211_set_ie
10729 * This function is used to parse WPA/RSN IE's.
10730 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010731int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
10732 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070010733 size_t ie_len
10734 )
10735{
10736 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10737 u8 *genie = ie;
10738 v_U16_t remLen = ie_len;
10739#ifdef FEATURE_WLAN_WAPI
10740 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
10741 u16 *tmp;
10742 v_U16_t akmsuiteCount;
10743 int *akmlist;
10744#endif
10745 ENTER();
10746
10747 /* clear previous assocAddIE */
10748 pWextState->assocAddIE.length = 0;
10749 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010750 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010751
10752 while (remLen >= 2)
10753 {
10754 v_U16_t eLen = 0;
10755 v_U8_t elementId;
10756 elementId = *genie++;
10757 eLen = *genie++;
10758 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010759
Arif Hussain6d2a3322013-11-17 19:50:10 -080010760 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070010761 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010762
10763 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070010764 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010765 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010766 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 -070010767 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010768 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010769 "%s: Invalid WPA IE", __func__);
10770 return -EINVAL;
10771 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010772 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070010773 {
10774 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010775 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010776 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010777
Jeff Johnson295189b2012-06-20 16:38:30 -070010778 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10779 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010780 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
10781 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010782 VOS_ASSERT(0);
10783 return -ENOMEM;
10784 }
10785 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10786 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10787 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010788
Jeff Johnson295189b2012-06-20 16:38:30 -070010789 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
10790 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10791 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10792 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010793 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
10794 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010795 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
10796 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10797 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
10798 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
10799 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
10800 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010801 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053010802 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010803 {
10804 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010805 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010806 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010807
Jeff Johnson295189b2012-06-20 16:38:30 -070010808 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10809 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010810 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10811 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010812 VOS_ASSERT(0);
10813 return -ENOMEM;
10814 }
10815 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10816 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10817 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010818
Jeff Johnson295189b2012-06-20 16:38:30 -070010819 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10820 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10821 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010822#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010823 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
10824 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010825 /*Consider WFD IE, only for P2P Client */
10826 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10827 {
10828 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010829 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010830 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010831
Jeff Johnson295189b2012-06-20 16:38:30 -070010832 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10833 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010834 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10835 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010836 VOS_ASSERT(0);
10837 return -ENOMEM;
10838 }
10839 // WFD IE is saved to Additional IE ; it should be accumulated to handle
10840 // WPS IE + P2P IE + WFD IE
10841 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10842 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010843
Jeff Johnson295189b2012-06-20 16:38:30 -070010844 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10845 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10846 }
10847#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010848 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010849 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010850 HS20_OUI_TYPE_SIZE)) )
10851 {
10852 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010853 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010854 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010855
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010856 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10857 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010858 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10859 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010860 VOS_ASSERT(0);
10861 return -ENOMEM;
10862 }
10863 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10864 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010865
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010866 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10867 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10868 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010869 /* Appending OSEN Information Element in Assiciation Request */
10870 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
10871 OSEN_OUI_TYPE_SIZE)) )
10872 {
10873 v_U16_t curAddIELen = pWextState->assocAddIE.length;
10874 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
10875 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010876
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010877 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10878 {
10879 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10880 "Need bigger buffer space");
10881 VOS_ASSERT(0);
10882 return -ENOMEM;
10883 }
10884 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10885 pWextState->assocAddIE.length += eLen + 2;
10886
10887 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
10888 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10889 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10890 }
10891
10892 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070010893 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
10894
10895 /* populating as ADDIE in beacon frames */
10896 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10897 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
10898 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
10899 {
10900 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10901 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10902 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10903 {
10904 hddLog(LOGE,
10905 "Coldn't pass "
10906 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
10907 }
10908 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
10909 else
10910 hddLog(LOGE,
10911 "Could not pass on "
10912 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
10913
10914 /* IBSS mode doesn't contain params->proberesp_ies still
10915 beaconIE's need to be populated in probe response frames */
10916 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
10917 {
10918 u16 rem_probe_resp_ie_len = eLen + 2;
10919 u8 probe_rsp_ie_len[3] = {0};
10920 u8 counter = 0;
10921
10922 /* Check Probe Resp Length if it is greater then 255 then
10923 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
10924 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
10925 not able Store More then 255 bytes into One Variable */
10926
10927 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
10928 {
10929 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
10930 {
10931 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
10932 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
10933 }
10934 else
10935 {
10936 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
10937 rem_probe_resp_ie_len = 0;
10938 }
10939 }
10940
10941 rem_probe_resp_ie_len = 0;
10942
10943 if (probe_rsp_ie_len[0] > 0)
10944 {
10945 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10946 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
10947 (tANI_U8*)(genie - 2),
10948 probe_rsp_ie_len[0], NULL,
10949 eANI_BOOLEAN_FALSE)
10950 == eHAL_STATUS_FAILURE)
10951 {
10952 hddLog(LOGE,
10953 "Could not pass"
10954 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
10955 }
10956 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10957 }
10958
10959 if (probe_rsp_ie_len[1] > 0)
10960 {
10961 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10962 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
10963 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10964 probe_rsp_ie_len[1], NULL,
10965 eANI_BOOLEAN_FALSE)
10966 == eHAL_STATUS_FAILURE)
10967 {
10968 hddLog(LOGE,
10969 "Could not pass"
10970 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
10971 }
10972 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10973 }
10974
10975 if (probe_rsp_ie_len[2] > 0)
10976 {
10977 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10978 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
10979 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10980 probe_rsp_ie_len[2], NULL,
10981 eANI_BOOLEAN_FALSE)
10982 == eHAL_STATUS_FAILURE)
10983 {
10984 hddLog(LOGE,
10985 "Could not pass"
10986 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
10987 }
10988 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10989 }
10990
10991 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10992 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10993 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10994 {
10995 hddLog(LOGE,
10996 "Could not pass"
10997 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
10998 }
10999 }
11000 else
11001 {
11002 // Reset WNI_CFG_PROBE_RSP Flags
11003 wlan_hdd_reset_prob_rspies(pAdapter);
11004
11005 hddLog(VOS_TRACE_LEVEL_INFO,
11006 "%s: No Probe Response IE received in set beacon",
11007 __func__);
11008 }
11009 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011010 break;
11011 case DOT11F_EID_RSN:
11012 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
11013 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11014 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
11015 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
11016 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
11017 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011018 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
11019 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011020 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011021 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011022 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011023 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011024
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011025 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11026 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011027 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11028 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011029 VOS_ASSERT(0);
11030 return -ENOMEM;
11031 }
11032 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11033 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011034
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011035 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11036 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11037 break;
11038 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011039#ifdef FEATURE_WLAN_WAPI
11040 case WLAN_EID_WAPI:
11041 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011042 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011043 pAdapter->wapi_info.nWapiMode);
11044 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011045 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070011046 akmsuiteCount = WPA_GET_LE16(tmp);
11047 tmp = tmp + 1;
11048 akmlist = (int *)(tmp);
11049 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
11050 {
11051 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
11052 }
11053 else
11054 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011055 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070011056 VOS_ASSERT(0);
11057 return -EINVAL;
11058 }
11059
11060 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
11061 {
11062 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011063 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011064 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011065 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011066 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011067 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011068 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011069 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011070 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
11071 }
11072 break;
11073#endif
11074 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011075 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011076 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011077 /* when Unknown IE is received we should break and continue
11078 * to the next IE in the buffer instead we were returning
11079 * so changing this to break */
11080 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011081 }
11082 genie += eLen;
11083 remLen -= eLen;
11084 }
11085 EXIT();
11086 return 0;
11087}
11088
11089/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053011090 * FUNCTION: hdd_isWPAIEPresent
11091 * Parse the received IE to find the WPA IE
11092 *
11093 */
11094static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
11095{
11096 v_U8_t eLen = 0;
11097 v_U16_t remLen = ie_len;
11098 v_U8_t elementId = 0;
11099
11100 while (remLen >= 2)
11101 {
11102 elementId = *ie++;
11103 eLen = *ie++;
11104 remLen -= 2;
11105 if (eLen > remLen)
11106 {
11107 hddLog(VOS_TRACE_LEVEL_ERROR,
11108 "%s: IE length is wrong %d", __func__, eLen);
11109 return FALSE;
11110 }
11111 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
11112 {
11113 /* OUI - 0x00 0X50 0XF2
11114 WPA Information Element - 0x01
11115 WPA version - 0x01*/
11116 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
11117 return TRUE;
11118 }
11119 ie += eLen;
11120 remLen -= eLen;
11121 }
11122 return FALSE;
11123}
11124
11125/*
Jeff Johnson295189b2012-06-20 16:38:30 -070011126 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011127 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011128 * parameters during connect operation.
11129 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011130int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011131 struct cfg80211_connect_params *req
11132 )
11133{
11134 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011135 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011136 ENTER();
11137
11138 /*set wpa version*/
11139 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
11140
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011141 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011142 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053011143 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011144 {
11145 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11146 }
11147 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
11148 {
11149 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11150 }
11151 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011152
11153 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011154 pWextState->wpaVersion);
11155
11156 /*set authentication type*/
11157 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
11158
11159 if (0 > status)
11160 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011161 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011162 "%s: failed to set authentication type ", __func__);
11163 return status;
11164 }
11165
11166 /*set key mgmt type*/
11167 if (req->crypto.n_akm_suites)
11168 {
11169 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
11170 if (0 > status)
11171 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011172 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070011173 __func__);
11174 return status;
11175 }
11176 }
11177
11178 /*set pairwise cipher type*/
11179 if (req->crypto.n_ciphers_pairwise)
11180 {
11181 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
11182 req->crypto.ciphers_pairwise[0], true);
11183 if (0 > status)
11184 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011185 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011186 "%s: failed to set unicast cipher type", __func__);
11187 return status;
11188 }
11189 }
11190 else
11191 {
11192 /*Reset previous cipher suite to none*/
11193 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
11194 if (0 > status)
11195 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011196 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011197 "%s: failed to set unicast cipher type", __func__);
11198 return status;
11199 }
11200 }
11201
11202 /*set group cipher type*/
11203 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
11204 false);
11205
11206 if (0 > status)
11207 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011208 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070011209 __func__);
11210 return status;
11211 }
11212
Chet Lanctot186b5732013-03-18 10:26:30 -070011213#ifdef WLAN_FEATURE_11W
11214 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
11215#endif
11216
Jeff Johnson295189b2012-06-20 16:38:30 -070011217 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
11218 if (req->ie_len)
11219 {
11220 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
11221 if ( 0 > status)
11222 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011223 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011224 __func__);
11225 return status;
11226 }
11227 }
11228
11229 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011230 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011231 {
11232 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
11233 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
11234 )
11235 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011236 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070011237 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
11238 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011239 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011240 __func__);
11241 return -EOPNOTSUPP;
11242 }
11243 else
11244 {
11245 u8 key_len = req->key_len;
11246 u8 key_idx = req->key_idx;
11247
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011248 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011249 && (CSR_MAX_NUM_KEY > key_idx)
11250 )
11251 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011252 hddLog(VOS_TRACE_LEVEL_INFO,
11253 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011254 __func__, key_idx, key_len);
11255 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011256 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011257 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011258 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011259 (u8)key_len;
11260 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
11261 }
11262 }
11263 }
11264 }
11265
11266 return status;
11267}
11268
11269/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011270 * FUNCTION: wlan_hdd_try_disconnect
11271 * This function is used to disconnect from previous
11272 * connection
11273 */
11274static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
11275{
11276 long ret = 0;
11277 hdd_station_ctx_t *pHddStaCtx;
11278 eMib_dot11DesiredBssType connectedBssType;
11279
11280 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11281
11282 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
11283
11284 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
11285 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
11286 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
11287 {
11288 /* Issue disconnect to CSR */
11289 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11290 if( eHAL_STATUS_SUCCESS ==
11291 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11292 pAdapter->sessionId,
11293 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11294 {
11295 ret = wait_for_completion_interruptible_timeout(
11296 &pAdapter->disconnect_comp_var,
11297 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11298 if (0 >= ret)
11299 {
11300 hddLog(LOGE, FL("Failed to receive disconnect event"));
11301 return -EALREADY;
11302 }
11303 }
11304 }
11305 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
11306 {
11307 ret = wait_for_completion_interruptible_timeout(
11308 &pAdapter->disconnect_comp_var,
11309 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11310 if (0 >= ret)
11311 {
11312 hddLog(LOGE, FL("Failed to receive disconnect event"));
11313 return -EALREADY;
11314 }
11315 }
11316
11317 return 0;
11318}
11319
11320/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053011321 * FUNCTION: __wlan_hdd_cfg80211_connect
11322 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011323 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011324static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011325 struct net_device *ndev,
11326 struct cfg80211_connect_params *req
11327 )
11328{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011329 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011330 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011331 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053011332 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011333
11334 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011335
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011336 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11337 TRACE_CODE_HDD_CFG80211_CONNECT,
11338 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011339 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011340 "%s: device_mode = %s (%d)", __func__,
11341 hdd_device_modetoString(pAdapter->device_mode),
11342 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011343
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011344 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011345 if (!pHddCtx)
11346 {
11347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11348 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011349 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011350 }
11351
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011352 status = wlan_hdd_validate_context(pHddCtx);
11353
11354 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011355 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11357 "%s: HDD context is not valid", __func__);
11358 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011359 }
11360
Agarwal Ashish51325b52014-06-16 16:50:49 +053011361 if (vos_max_concurrent_connections_reached()) {
11362 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11363 return -ECONNREFUSED;
11364 }
11365
Jeff Johnson295189b2012-06-20 16:38:30 -070011366#ifdef WLAN_BTAMP_FEATURE
11367 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011368 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070011369 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011370 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011371 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011372 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070011373 }
11374#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011375
11376 //If Device Mode is Station Concurrent Sessions Exit BMps
11377 //P2P Mode will be taken care in Open/close adapter
11378 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011379 (vos_concurrent_open_sessions_running())) {
11380 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
11381 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011382 }
11383
11384 /*Try disconnecting if already in connected state*/
11385 status = wlan_hdd_try_disconnect(pAdapter);
11386 if ( 0 > status)
11387 {
11388 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11389 " connection"));
11390 return -EALREADY;
11391 }
11392
Jeff Johnson295189b2012-06-20 16:38:30 -070011393 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011394 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070011395
11396 if ( 0 > status)
11397 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011398 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070011399 __func__);
11400 return status;
11401 }
Mohit Khanna765234a2012-09-11 15:08:35 -070011402 if ( req->channel )
11403 {
11404 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
11405 req->ssid_len, req->bssid,
11406 req->channel->hw_value);
11407 }
11408 else
11409 {
11410 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011411 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070011412 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011413
11414 if (0 > status)
11415 {
11416 //ReEnable BMPS if disabled
11417 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
11418 (NULL != pHddCtx))
11419 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011420 if (pHddCtx->hdd_wlan_suspended)
11421 {
11422 hdd_set_pwrparams(pHddCtx);
11423 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011424 //ReEnable Bmps and Imps back
11425 hdd_enable_bmps_imps(pHddCtx);
11426 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011427 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011428 return status;
11429 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011430 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011431 EXIT();
11432 return status;
11433}
11434
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011435static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
11436 struct net_device *ndev,
11437 struct cfg80211_connect_params *req)
11438{
11439 int ret;
11440 vos_ssr_protect(__func__);
11441 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
11442 vos_ssr_unprotect(__func__);
11443
11444 return ret;
11445}
Jeff Johnson295189b2012-06-20 16:38:30 -070011446
11447/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011448 * FUNCTION: wlan_hdd_disconnect
11449 * This function is used to issue a disconnect request to SME
11450 */
11451int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
11452{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011453 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011454 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011455 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011456 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011457
11458 status = wlan_hdd_validate_context(pHddCtx);
11459
11460 if (0 != status)
11461 {
11462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11463 "%s: HDD context is not valid", __func__);
11464 return status;
11465 }
11466
11467 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011468
Agarwal Ashish47d18112014-08-04 19:55:07 +053011469 /* Need to apply spin lock before decreasing active sessions
11470 * as there can be chance for double decrement if context switch
11471 * Calls hdd_DisConnectHandler.
11472 */
11473
11474 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011475 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11476 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011477 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11478 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053011479 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
11480 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011481
Abhishek Singhf4669da2014-05-26 15:07:49 +053011482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053011483 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
11484
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011485 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011486
Mihir Shete182a0b22014-08-18 16:08:48 +053011487 /*
11488 * stop tx queues before deleting STA/BSS context from the firmware.
11489 * tx has to be disabled because the firmware can get busy dropping
11490 * the tx frames after BSS/STA has been deleted and will not send
11491 * back a response resulting in WDI timeout
11492 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053011493 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053011494 netif_tx_disable(pAdapter->dev);
11495 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011496
Mihir Shete182a0b22014-08-18 16:08:48 +053011497 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011498 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11499 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011500 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
11501 {
11502 hddLog(VOS_TRACE_LEVEL_INFO,
11503 FL("status = %d, already disconnected"),
11504 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011505
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011506 }
11507 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011508 {
11509 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011510 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011511 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011512 result = -EINVAL;
11513 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011514 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011515 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011516 &pAdapter->disconnect_comp_var,
11517 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011518 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011519 {
11520 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011521 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011522 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011523 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011524 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011525 {
11526 hddLog(VOS_TRACE_LEVEL_ERROR,
11527 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011528 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011529 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011530disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011531 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11532 FL("Set HDD connState to eConnectionState_NotConnected"));
11533 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
11534
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011535 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011536}
11537
11538
11539/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011540 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070011541 * This function is used to issue a disconnect request to SME
11542 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011543static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011544 struct net_device *dev,
11545 u16 reason
11546 )
11547{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011548 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011549 tCsrRoamProfile *pRoamProfile =
11550 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011551 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011552 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11553 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011554#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011555 tANI_U8 staIdx;
11556#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011557
Jeff Johnson295189b2012-06-20 16:38:30 -070011558 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011559
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011560 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11561 TRACE_CODE_HDD_CFG80211_DISCONNECT,
11562 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011563 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
11564 __func__, hdd_device_modetoString(pAdapter->device_mode),
11565 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011566
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011567 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
11568 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070011569
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011570 status = wlan_hdd_validate_context(pHddCtx);
11571
11572 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011573 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11575 "%s: HDD context is not valid", __func__);
11576 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011577 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011578
Jeff Johnson295189b2012-06-20 16:38:30 -070011579 if (NULL != pRoamProfile)
11580 {
11581 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011582 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
11583 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070011584 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011585 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070011586 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011587 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070011588 switch(reason)
11589 {
11590 case WLAN_REASON_MIC_FAILURE:
11591 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
11592 break;
11593
11594 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
11595 case WLAN_REASON_DISASSOC_AP_BUSY:
11596 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
11597 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
11598 break;
11599
11600 case WLAN_REASON_PREV_AUTH_NOT_VALID:
11601 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053011602 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070011603 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
11604 break;
11605
Jeff Johnson295189b2012-06-20 16:38:30 -070011606 default:
11607 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
11608 break;
11609 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011610 pScanInfo = &pHddCtx->scan_info;
11611 if (pScanInfo->mScanPending)
11612 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011613 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011614 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011615 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011616 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011617 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011618
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011619#ifdef FEATURE_WLAN_TDLS
11620 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011621 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011622 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011623 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
11624 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011625 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011626 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011627 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011628 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011629 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011630 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011631 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011632 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011633 pAdapter->sessionId,
11634 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011635 }
11636 }
11637#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011638 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011639 status = wlan_hdd_disconnect(pAdapter, reasonCode);
11640 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070011641 {
11642 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011643 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011644 __func__, (int)status );
11645 return -EINVAL;
11646 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011647 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011648 else
11649 {
11650 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
11651 "called while in %d state", __func__,
11652 pHddStaCtx->conn_info.connState);
11653 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011654 }
11655 else
11656 {
11657 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
11658 }
11659
11660 return status;
11661}
11662
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011663static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
11664 struct net_device *dev,
11665 u16 reason
11666 )
11667{
11668 int ret;
11669 vos_ssr_protect(__func__);
11670 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
11671 vos_ssr_unprotect(__func__);
11672
11673 return ret;
11674}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011675
Jeff Johnson295189b2012-06-20 16:38:30 -070011676/*
11677 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011678 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011679 * settings in IBSS mode.
11680 */
11681static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011682 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011683 struct cfg80211_ibss_params *params
11684 )
11685{
11686 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011687 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011688 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11689 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011690
Jeff Johnson295189b2012-06-20 16:38:30 -070011691 ENTER();
11692
11693 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070011694 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070011695
11696 if (params->ie_len && ( NULL != params->ie) )
11697 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011698 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11699 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011700 {
11701 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11702 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11703 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011704 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011705 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011706 tDot11fIEWPA dot11WPAIE;
11707 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011708 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011709
Wilson Yang00256342013-10-10 23:13:38 -070011710 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011711 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11712 params->ie_len, DOT11F_EID_WPA);
11713 if ( NULL != ie )
11714 {
11715 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11716 // Unpack the WPA IE
11717 //Skip past the EID byte and length byte - and four byte WiFi OUI
11718 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
11719 &ie[2+4],
11720 ie[1] - 4,
11721 &dot11WPAIE);
11722 /*Extract the multicast cipher, the encType for unicast
11723 cipher for wpa-none is none*/
11724 encryptionType =
11725 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
11726 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011727 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011728
Jeff Johnson295189b2012-06-20 16:38:30 -070011729 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
11730
11731 if (0 > status)
11732 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011733 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011734 __func__);
11735 return status;
11736 }
11737 }
11738
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011739 pWextState->roamProfile.AuthType.authType[0] =
11740 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011741 eCSR_AUTH_TYPE_OPEN_SYSTEM;
11742
11743 if (params->privacy)
11744 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011745 /* Security enabled IBSS, At this time there is no information available
11746 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070011747 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011748 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070011749 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011750 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070011751 *enable privacy bit in beacons */
11752
11753 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11754 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011755 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
11756 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070011757 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11758 pWextState->roamProfile.EncryptionType.numEntries = 1;
11759 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070011760 return status;
11761}
11762
11763/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011764 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011765 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011766 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011767static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011768 struct net_device *dev,
11769 struct cfg80211_ibss_params *params
11770 )
11771{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011772 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011773 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11774 tCsrRoamProfile *pRoamProfile;
11775 int status;
krunal sonie9002db2013-11-25 14:24:17 -080011776 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011777 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11778 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011779
11780 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011781
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011782 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11783 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
11784 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011785 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011786 "%s: device_mode = %s (%d)", __func__,
11787 hdd_device_modetoString(pAdapter->device_mode),
11788 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011789
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011790 status = wlan_hdd_validate_context(pHddCtx);
11791
11792 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011793 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011794 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11795 "%s: HDD context is not valid", __func__);
11796 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011797 }
11798
11799 if (NULL == pWextState)
11800 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011801 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011802 __func__);
11803 return -EIO;
11804 }
11805
Agarwal Ashish51325b52014-06-16 16:50:49 +053011806 if (vos_max_concurrent_connections_reached()) {
11807 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11808 return -ECONNREFUSED;
11809 }
11810
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011811 /*Try disconnecting if already in connected state*/
11812 status = wlan_hdd_try_disconnect(pAdapter);
11813 if ( 0 > status)
11814 {
11815 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11816 " IBSS connection"));
11817 return -EALREADY;
11818 }
11819
Jeff Johnson295189b2012-06-20 16:38:30 -070011820 pRoamProfile = &pWextState->roamProfile;
11821
11822 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
11823 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011824 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011825 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011826 return -EINVAL;
11827 }
11828
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011829 /* BSSID is provided by upper layers hence no need to AUTO generate */
11830 if (NULL != params->bssid) {
11831 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11832 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
11833 hddLog (VOS_TRACE_LEVEL_ERROR,
11834 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11835 return -EIO;
11836 }
11837 }
krunal sonie9002db2013-11-25 14:24:17 -080011838 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
11839 {
11840 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11841 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
11842 {
11843 hddLog (VOS_TRACE_LEVEL_ERROR,
11844 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11845 return -EIO;
11846 }
11847 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
11848 if (!params->bssid)
11849 {
11850 hddLog (VOS_TRACE_LEVEL_ERROR,
11851 "%s:Failed memory allocation", __func__);
11852 return -EIO;
11853 }
11854 vos_mem_copy((v_U8_t *)params->bssid,
11855 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
11856 VOS_MAC_ADDR_SIZE);
11857 alloc_bssid = VOS_TRUE;
11858 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011859
Jeff Johnson295189b2012-06-20 16:38:30 -070011860 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070011861 if (NULL !=
11862#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11863 params->chandef.chan)
11864#else
11865 params->channel)
11866#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011867 {
11868 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011869 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
11870 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
11871 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
11872 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011873
11874 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011875 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070011876 ieee80211_frequency_to_channel(
11877#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11878 params->chandef.chan->center_freq);
11879#else
11880 params->channel->center_freq);
11881#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011882
11883 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
11884 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070011885 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011886 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
11887 __func__);
11888 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070011889 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011890
11891 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011892 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011893 if (channelNum == validChan[indx])
11894 {
11895 break;
11896 }
11897 }
11898 if (indx >= numChans)
11899 {
11900 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011901 __func__, channelNum);
11902 return -EINVAL;
11903 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011904 /* Set the Operational Channel */
11905 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
11906 channelNum);
11907 pRoamProfile->ChannelInfo.numOfChannels = 1;
11908 pHddStaCtx->conn_info.operationChannel = channelNum;
11909 pRoamProfile->ChannelInfo.ChannelList =
11910 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070011911 }
11912
11913 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011914 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070011915 if (status < 0)
11916 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011917 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070011918 __func__);
11919 return status;
11920 }
11921
11922 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011923 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011924 params->ssid_len, params->bssid,
11925 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011926
11927 if (0 > status)
11928 {
11929 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
11930 return status;
11931 }
11932
krunal sonie9002db2013-11-25 14:24:17 -080011933 if (NULL != params->bssid &&
11934 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
11935 alloc_bssid == VOS_TRUE)
11936 {
11937 vos_mem_free(params->bssid);
11938 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011939 return 0;
11940}
11941
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011942static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
11943 struct net_device *dev,
11944 struct cfg80211_ibss_params *params
11945 )
11946{
11947 int ret = 0;
11948
11949 vos_ssr_protect(__func__);
11950 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
11951 vos_ssr_unprotect(__func__);
11952
11953 return ret;
11954}
11955
Jeff Johnson295189b2012-06-20 16:38:30 -070011956/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011957 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011958 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011959 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011960static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011961 struct net_device *dev
11962 )
11963{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011964 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011965 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11966 tCsrRoamProfile *pRoamProfile;
11967 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011968 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011969
11970 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011971
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011972 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11973 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
11974 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011975 status = wlan_hdd_validate_context(pHddCtx);
11976
11977 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011978 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011979 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11980 "%s: HDD context is not valid", __func__);
11981 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011982 }
11983
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011984 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
11985 hdd_device_modetoString(pAdapter->device_mode),
11986 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011987 if (NULL == pWextState)
11988 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011989 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011990 __func__);
11991 return -EIO;
11992 }
11993
11994 pRoamProfile = &pWextState->roamProfile;
11995
11996 /* Issue disconnect only if interface type is set to IBSS */
11997 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
11998 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011999 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070012000 __func__);
12001 return -EINVAL;
12002 }
12003
12004 /* Issue Disconnect request */
12005 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12006 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12007 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
12008
12009 return 0;
12010}
12011
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012012static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
12013 struct net_device *dev
12014 )
12015{
12016 int ret = 0;
12017
12018 vos_ssr_protect(__func__);
12019 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
12020 vos_ssr_unprotect(__func__);
12021
12022 return ret;
12023}
12024
Jeff Johnson295189b2012-06-20 16:38:30 -070012025/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012026 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070012027 * This function is used to set the phy parameters
12028 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
12029 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012030static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012031 u32 changed)
12032{
12033 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
12034 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012035 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012036
12037 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012038 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12039 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
12040 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012041 status = wlan_hdd_validate_context(pHddCtx);
12042
12043 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012044 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012045 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12046 "%s: HDD context is not valid", __func__);
12047 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012048 }
12049
Jeff Johnson295189b2012-06-20 16:38:30 -070012050 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
12051 {
12052 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
12053 WNI_CFG_RTS_THRESHOLD_STAMAX :
12054 wiphy->rts_threshold;
12055
12056 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012057 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070012058 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012059 hddLog(VOS_TRACE_LEVEL_ERROR,
12060 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012061 __func__, rts_threshold);
12062 return -EINVAL;
12063 }
12064
12065 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
12066 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012067 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012068 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012069 hddLog(VOS_TRACE_LEVEL_ERROR,
12070 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012071 __func__, rts_threshold);
12072 return -EIO;
12073 }
12074
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012075 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012076 rts_threshold);
12077 }
12078
12079 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
12080 {
12081 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
12082 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
12083 wiphy->frag_threshold;
12084
12085 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012086 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012087 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012088 hddLog(VOS_TRACE_LEVEL_ERROR,
12089 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012090 frag_threshold);
12091 return -EINVAL;
12092 }
12093
12094 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
12095 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012096 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012097 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012098 hddLog(VOS_TRACE_LEVEL_ERROR,
12099 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012100 __func__, frag_threshold);
12101 return -EIO;
12102 }
12103
12104 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
12105 frag_threshold);
12106 }
12107
12108 if ((changed & WIPHY_PARAM_RETRY_SHORT)
12109 || (changed & WIPHY_PARAM_RETRY_LONG))
12110 {
12111 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
12112 wiphy->retry_short :
12113 wiphy->retry_long;
12114
12115 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
12116 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
12117 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012118 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012119 __func__, retry_value);
12120 return -EINVAL;
12121 }
12122
12123 if (changed & WIPHY_PARAM_RETRY_SHORT)
12124 {
12125 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
12126 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012127 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012128 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012129 hddLog(VOS_TRACE_LEVEL_ERROR,
12130 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012131 __func__, retry_value);
12132 return -EIO;
12133 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012134 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012135 __func__, retry_value);
12136 }
12137 else if (changed & WIPHY_PARAM_RETRY_SHORT)
12138 {
12139 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
12140 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012141 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012142 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012143 hddLog(VOS_TRACE_LEVEL_ERROR,
12144 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012145 __func__, retry_value);
12146 return -EIO;
12147 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012148 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012149 __func__, retry_value);
12150 }
12151 }
12152
12153 return 0;
12154}
12155
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012156static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
12157 u32 changed)
12158{
12159 int ret;
12160
12161 vos_ssr_protect(__func__);
12162 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
12163 vos_ssr_unprotect(__func__);
12164
12165 return ret;
12166}
12167
Jeff Johnson295189b2012-06-20 16:38:30 -070012168/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012169 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012170 * This function is used to set the txpower
12171 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012172static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012173#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12174 struct wireless_dev *wdev,
12175#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012176#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012177 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012178#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012179 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012180#endif
12181 int dbm)
12182{
12183 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012184 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012185 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12186 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012187 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012188
12189 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012190 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12191 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
12192 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012193 status = wlan_hdd_validate_context(pHddCtx);
12194
12195 if (0 != status)
12196 {
12197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12198 "%s: HDD context is not valid", __func__);
12199 return status;
12200 }
12201
12202 hHal = pHddCtx->hHal;
12203
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012204 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
12205 dbm, ccmCfgSetCallback,
12206 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012207 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012208 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012209 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
12210 return -EIO;
12211 }
12212
12213 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
12214 dbm);
12215
12216 switch(type)
12217 {
12218 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
12219 /* Fall through */
12220 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
12221 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
12222 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012223 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
12224 __func__);
12225 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012226 }
12227 break;
12228 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012229 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012230 __func__);
12231 return -EOPNOTSUPP;
12232 break;
12233 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012234 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
12235 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070012236 return -EIO;
12237 }
12238
12239 return 0;
12240}
12241
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012242static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
12243#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12244 struct wireless_dev *wdev,
12245#endif
12246#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12247 enum tx_power_setting type,
12248#else
12249 enum nl80211_tx_power_setting type,
12250#endif
12251 int dbm)
12252{
12253 int ret;
12254 vos_ssr_protect(__func__);
12255 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
12256#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12257 wdev,
12258#endif
12259#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12260 type,
12261#else
12262 type,
12263#endif
12264 dbm);
12265 vos_ssr_unprotect(__func__);
12266
12267 return ret;
12268}
12269
Jeff Johnson295189b2012-06-20 16:38:30 -070012270/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012271 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012272 * This function is used to read the txpower
12273 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012274static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012275#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12276 struct wireless_dev *wdev,
12277#endif
12278 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070012279{
12280
12281 hdd_adapter_t *pAdapter;
12282 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012283 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012284
Jeff Johnsone7245742012-09-05 17:12:55 -070012285 ENTER();
12286
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012287 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012288
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012289 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012290 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12292 "%s: HDD context is not valid", __func__);
12293 *dbm = 0;
12294 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012295 }
12296
Jeff Johnson295189b2012-06-20 16:38:30 -070012297 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
12298 if (NULL == pAdapter)
12299 {
12300 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
12301 return -ENOENT;
12302 }
12303
12304 wlan_hdd_get_classAstats(pAdapter);
12305 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
12306
Jeff Johnsone7245742012-09-05 17:12:55 -070012307 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012308 return 0;
12309}
12310
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012311static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
12312#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12313 struct wireless_dev *wdev,
12314#endif
12315 int *dbm)
12316{
12317 int ret;
12318
12319 vos_ssr_protect(__func__);
12320 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
12321#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12322 wdev,
12323#endif
12324 dbm);
12325 vos_ssr_unprotect(__func__);
12326
12327 return ret;
12328}
12329
12330
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012331static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070012332 u8* mac, struct station_info *sinfo)
12333{
12334 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12335 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12336 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053012337 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070012338
12339 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
12340 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012341
12342 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
12343 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
12344 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
12345 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
12346 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
12347 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
12348 tANI_U16 maxRate = 0;
12349 tANI_U16 myRate;
12350 tANI_U16 currentRate = 0;
12351 tANI_U8 maxSpeedMCS = 0;
12352 tANI_U8 maxMCSIdx = 0;
12353 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053012354 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012355 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012356 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012357
Leo Chang6f8870f2013-03-26 18:11:36 -070012358#ifdef WLAN_FEATURE_11AC
12359 tANI_U32 vht_mcs_map;
12360 eDataRate11ACMaxMcs vhtMaxMcs;
12361#endif /* WLAN_FEATURE_11AC */
12362
Jeff Johnsone7245742012-09-05 17:12:55 -070012363 ENTER();
12364
Jeff Johnson295189b2012-06-20 16:38:30 -070012365 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
12366 (0 == ssidlen))
12367 {
12368 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
12369 " Invalid ssidlen, %d", __func__, ssidlen);
12370 /*To keep GUI happy*/
12371 return 0;
12372 }
12373
Mukul Sharma811205f2014-07-09 21:07:30 +053012374 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
12375 {
12376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12377 "%s: Roaming in progress, so unable to proceed this request", __func__);
12378 return 0;
12379 }
12380
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012381 status = wlan_hdd_validate_context(pHddCtx);
12382
12383 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012384 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012385 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12386 "%s: HDD context is not valid", __func__);
12387 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012388 }
12389
Jeff Johnson295189b2012-06-20 16:38:30 -070012390
Kiet Lam3b17fc82013-09-27 05:24:08 +053012391 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
12392 sinfo->filled |= STATION_INFO_SIGNAL;
12393
c_hpothu09f19542014-05-30 21:53:31 +053012394 wlan_hdd_get_station_stats(pAdapter);
12395 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
12396
12397 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053012398 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
12399 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053012400 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053012401 {
12402 rate_flags = pAdapter->maxRateFlags;
12403 }
c_hpothu44ff4e02014-05-08 00:13:57 +053012404
Jeff Johnson295189b2012-06-20 16:38:30 -070012405 //convert to the UI units of 100kbps
12406 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
12407
12408#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070012409 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 -070012410 sinfo->signal,
12411 pCfg->reportMaxLinkSpeed,
12412 myRate,
12413 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012414 (int) pCfg->linkSpeedRssiMid,
12415 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070012416 (int) rate_flags,
12417 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012418#endif //LINKSPEED_DEBUG_ENABLED
12419
12420 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
12421 {
12422 // we do not want to necessarily report the current speed
12423 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
12424 {
12425 // report the max possible speed
12426 rssidx = 0;
12427 }
12428 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
12429 {
12430 // report the max possible speed with RSSI scaling
12431 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
12432 {
12433 // report the max possible speed
12434 rssidx = 0;
12435 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012436 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070012437 {
12438 // report middle speed
12439 rssidx = 1;
12440 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012441 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
12442 {
12443 // report middle speed
12444 rssidx = 2;
12445 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012446 else
12447 {
12448 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012449 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070012450 }
12451 }
12452 else
12453 {
12454 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
12455 hddLog(VOS_TRACE_LEVEL_ERROR,
12456 "%s: Invalid value for reportMaxLinkSpeed: %u",
12457 __func__, pCfg->reportMaxLinkSpeed);
12458 rssidx = 0;
12459 }
12460
12461 maxRate = 0;
12462
12463 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012464 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
12465 OperationalRates, &ORLeng))
12466 {
12467 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12468 /*To keep GUI happy*/
12469 return 0;
12470 }
12471
Jeff Johnson295189b2012-06-20 16:38:30 -070012472 for (i = 0; i < ORLeng; i++)
12473 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012474 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012475 {
12476 /* Validate Rate Set */
12477 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
12478 {
12479 currentRate = supported_data_rate[j].supported_rate[rssidx];
12480 break;
12481 }
12482 }
12483 /* Update MAX rate */
12484 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12485 }
12486
12487 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012488 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
12489 ExtendedRates, &ERLeng))
12490 {
12491 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12492 /*To keep GUI happy*/
12493 return 0;
12494 }
12495
Jeff Johnson295189b2012-06-20 16:38:30 -070012496 for (i = 0; i < ERLeng; i++)
12497 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012498 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012499 {
12500 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
12501 {
12502 currentRate = supported_data_rate[j].supported_rate[rssidx];
12503 break;
12504 }
12505 }
12506 /* Update MAX rate */
12507 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12508 }
c_hpothu79aab322014-07-14 21:11:01 +053012509
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012510 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053012511 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012512 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053012513 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070012514 {
c_hpothu79aab322014-07-14 21:11:01 +053012515 if (rate_flags & eHAL_TX_RATE_VHT80)
12516 mode = 2;
12517 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
12518 mode = 1;
12519 else
12520 mode = 0;
12521
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012522 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
12523 MCSRates, &MCSLeng))
12524 {
12525 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12526 /*To keep GUI happy*/
12527 return 0;
12528 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012529 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070012530#ifdef WLAN_FEATURE_11AC
12531 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012532 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070012533 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012534 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012535 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070012536 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070012537 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012538 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070012539 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012540 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070012541 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012542 maxMCSIdx = 7;
12543 }
12544 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
12545 {
12546 maxMCSIdx = 8;
12547 }
12548 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
12549 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012550 //VHT20 is supporting 0~8
12551 if (rate_flags & eHAL_TX_RATE_VHT20)
12552 maxMCSIdx = 8;
12553 else
12554 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070012555 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012556
c_hpothu79aab322014-07-14 21:11:01 +053012557 if (0 != rssidx)/*check for scaled */
12558 {
12559 //get middle rate MCS index if rssi=1/2
12560 for (i=0; i <= maxMCSIdx; i++)
12561 {
12562 if (sinfo->signal <= rssiMcsTbl[mode][i])
12563 {
12564 maxMCSIdx = i;
12565 break;
12566 }
12567 }
12568 }
12569
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012570 if (rate_flags & eHAL_TX_RATE_VHT80)
12571 {
12572 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
12573 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
12574 }
12575 else if (rate_flags & eHAL_TX_RATE_VHT40)
12576 {
12577 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
12578 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
12579 }
12580 else if (rate_flags & eHAL_TX_RATE_VHT20)
12581 {
12582 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
12583 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
12584 }
12585
Leo Chang6f8870f2013-03-26 18:11:36 -070012586 maxSpeedMCS = 1;
12587 if (currentRate > maxRate)
12588 {
12589 maxRate = currentRate;
12590 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012591
Leo Chang6f8870f2013-03-26 18:11:36 -070012592 }
12593 else
12594#endif /* WLAN_FEATURE_11AC */
12595 {
12596 if (rate_flags & eHAL_TX_RATE_HT40)
12597 {
12598 rateFlag |= 1;
12599 }
12600 if (rate_flags & eHAL_TX_RATE_SGI)
12601 {
12602 rateFlag |= 2;
12603 }
12604
Girish Gowli01abcee2014-07-31 20:18:55 +053012605 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053012606 if (rssidx == 1 || rssidx == 2)
12607 {
12608 //get middle rate MCS index if rssi=1/2
12609 for (i=0; i <= 7; i++)
12610 {
12611 if (sinfo->signal <= rssiMcsTbl[mode][i])
12612 {
12613 temp = i+1;
12614 break;
12615 }
12616 }
12617 }
c_hpothu79aab322014-07-14 21:11:01 +053012618
12619 for (i = 0; i < MCSLeng; i++)
12620 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012621 for (j = 0; j < temp; j++)
12622 {
12623 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
12624 {
12625 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
12626 break;
12627 }
12628 }
12629 if ((j < temp) && (currentRate > maxRate))
12630 {
12631 maxRate = currentRate;
12632 maxSpeedMCS = 1;
12633 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
12634 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012635 }
12636 }
12637 }
12638
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012639 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
12640 {
12641 maxRate = myRate;
12642 maxSpeedMCS = 1;
12643 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12644 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012645 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053012646 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070012647 {
12648 maxRate = myRate;
12649 if (rate_flags & eHAL_TX_RATE_LEGACY)
12650 {
12651 maxSpeedMCS = 0;
12652 }
12653 else
12654 {
12655 maxSpeedMCS = 1;
12656 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12657 }
12658 }
12659
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012660 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070012661 {
12662 sinfo->txrate.legacy = maxRate;
12663#ifdef LINKSPEED_DEBUG_ENABLED
12664 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
12665#endif //LINKSPEED_DEBUG_ENABLED
12666 }
12667 else
12668 {
12669 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070012670#ifdef WLAN_FEATURE_11AC
12671 sinfo->txrate.nss = 1;
12672 if (rate_flags & eHAL_TX_RATE_VHT80)
12673 {
12674 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012675 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070012676 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012677 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070012678 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012679 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12680 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12681 }
12682 else if (rate_flags & eHAL_TX_RATE_VHT20)
12683 {
12684 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12685 }
12686#endif /* WLAN_FEATURE_11AC */
12687 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
12688 {
12689 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12690 if (rate_flags & eHAL_TX_RATE_HT40)
12691 {
12692 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12693 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012694 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012695 if (rate_flags & eHAL_TX_RATE_SGI)
12696 {
12697 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12698 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012699
Jeff Johnson295189b2012-06-20 16:38:30 -070012700#ifdef LINKSPEED_DEBUG_ENABLED
12701 pr_info("Reporting MCS rate %d flags %x\n",
12702 sinfo->txrate.mcs,
12703 sinfo->txrate.flags );
12704#endif //LINKSPEED_DEBUG_ENABLED
12705 }
12706 }
12707 else
12708 {
12709 // report current rate instead of max rate
12710
12711 if (rate_flags & eHAL_TX_RATE_LEGACY)
12712 {
12713 //provide to the UI in units of 100kbps
12714 sinfo->txrate.legacy = myRate;
12715#ifdef LINKSPEED_DEBUG_ENABLED
12716 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
12717#endif //LINKSPEED_DEBUG_ENABLED
12718 }
12719 else
12720 {
12721 //must be MCS
12722 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070012723#ifdef WLAN_FEATURE_11AC
12724 sinfo->txrate.nss = 1;
12725 if (rate_flags & eHAL_TX_RATE_VHT80)
12726 {
12727 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12728 }
12729 else
12730#endif /* WLAN_FEATURE_11AC */
12731 {
12732 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12733 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012734 if (rate_flags & eHAL_TX_RATE_SGI)
12735 {
12736 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12737 }
12738 if (rate_flags & eHAL_TX_RATE_HT40)
12739 {
12740 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12741 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012742#ifdef WLAN_FEATURE_11AC
12743 else if (rate_flags & eHAL_TX_RATE_VHT80)
12744 {
12745 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
12746 }
12747#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070012748#ifdef LINKSPEED_DEBUG_ENABLED
12749 pr_info("Reporting actual MCS rate %d flags %x\n",
12750 sinfo->txrate.mcs,
12751 sinfo->txrate.flags );
12752#endif //LINKSPEED_DEBUG_ENABLED
12753 }
12754 }
12755 sinfo->filled |= STATION_INFO_TX_BITRATE;
12756
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012757 sinfo->tx_packets =
12758 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
12759 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
12760 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
12761 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
12762
12763 sinfo->tx_retries =
12764 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
12765 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
12766 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
12767 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
12768
12769 sinfo->tx_failed =
12770 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
12771 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
12772 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
12773 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
12774
12775 sinfo->filled |=
12776 STATION_INFO_TX_PACKETS |
12777 STATION_INFO_TX_RETRIES |
12778 STATION_INFO_TX_FAILED;
12779
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012780 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12781 TRACE_CODE_HDD_CFG80211_GET_STA,
12782 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012783 EXIT();
12784 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012785}
12786
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012787static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
12788 u8* mac, struct station_info *sinfo)
12789{
12790 int ret;
12791
12792 vos_ssr_protect(__func__);
12793 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
12794 vos_ssr_unprotect(__func__);
12795
12796 return ret;
12797}
12798
12799static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070012800 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070012801{
12802 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012803 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012804 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012805 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012806
Jeff Johnsone7245742012-09-05 17:12:55 -070012807 ENTER();
12808
Jeff Johnson295189b2012-06-20 16:38:30 -070012809 if (NULL == pAdapter)
12810 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012811 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012812 return -ENODEV;
12813 }
12814
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012815 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12816 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
12817 pAdapter->sessionId, timeout));
12818
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012819 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012820 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012821
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012822 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012823 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12825 "%s: HDD context is not valid", __func__);
12826 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012827 }
12828
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012829 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
12830 (TRUE == pHddCtx->hdd_wlan_suspended) &&
12831 (pHddCtx->cfg_ini->fhostArpOffload) &&
12832 (eConnectionState_Associated ==
12833 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12834 {
Amar Singhald53568e2013-09-26 11:03:45 -070012835
12836 hddLog(VOS_TRACE_LEVEL_INFO,
12837 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053012838 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012839 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12840 {
12841 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012842 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012843 __func__, vos_status);
12844 }
12845 }
12846
Jeff Johnson295189b2012-06-20 16:38:30 -070012847 /**The get power cmd from the supplicant gets updated by the nl only
12848 *on successful execution of the function call
12849 *we are oppositely mapped w.r.t mode in the driver
12850 **/
12851 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
12852
Jeff Johnsone7245742012-09-05 17:12:55 -070012853 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012854 if (VOS_STATUS_E_FAILURE == vos_status)
12855 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12857 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012858 return -EINVAL;
12859 }
12860 return 0;
12861}
12862
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012863static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
12864 struct net_device *dev, bool mode, int timeout)
12865{
12866 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012867
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012868 vos_ssr_protect(__func__);
12869 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
12870 vos_ssr_unprotect(__func__);
12871
12872 return ret;
12873}
Jeff Johnson295189b2012-06-20 16:38:30 -070012874#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012875static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
12876 struct net_device *netdev,
12877 u8 key_index)
12878{
12879 ENTER();
12880 return 0;
12881}
12882
Jeff Johnson295189b2012-06-20 16:38:30 -070012883static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012884 struct net_device *netdev,
12885 u8 key_index)
12886{
12887 int ret;
12888 vos_ssr_protect(__func__);
12889 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
12890 vos_ssr_unprotect(__func__);
12891 return ret;
12892}
12893#endif //LINUX_VERSION_CODE
12894
12895#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
12896static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
12897 struct net_device *dev,
12898 struct ieee80211_txq_params *params)
12899{
12900 ENTER();
12901 return 0;
12902}
12903#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12904static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
12905 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070012906{
Jeff Johnsone7245742012-09-05 17:12:55 -070012907 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012908 return 0;
12909}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012910#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070012911
12912#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
12913static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012914 struct net_device *dev,
12915 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070012916{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012917 int ret;
12918
12919 vos_ssr_protect(__func__);
12920 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
12921 vos_ssr_unprotect(__func__);
12922 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012923}
12924#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12925static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12926 struct ieee80211_txq_params *params)
12927{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012928 int ret;
12929
12930 vos_ssr_protect(__func__);
12931 ret = __wlan_hdd_set_txq_params(wiphy, params);
12932 vos_ssr_unprotect(__func__);
12933 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012934}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012935#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012936
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012937static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012938 struct net_device *dev,
12939 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070012940{
12941 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012942 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012943 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012944 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012945 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012946 v_CONTEXT_t pVosContext = NULL;
12947 ptSapContext pSapCtx = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070012948 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012949
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012950 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070012951 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012952 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012953 return -EINVAL;
12954 }
12955
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012956 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12957 TRACE_CODE_HDD_CFG80211_DEL_STA,
12958 pAdapter->sessionId, pAdapter->device_mode));
12959
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012960 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12961 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012962
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012963 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012964 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012965 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12966 "%s: HDD context is not valid", __func__);
12967 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012968 }
12969
Jeff Johnson295189b2012-06-20 16:38:30 -070012970 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012971 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012972 )
12973 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012974 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12975 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12976 if(pSapCtx == NULL){
12977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12978 FL("psapCtx is NULL"));
12979 return -ENOENT;
12980 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012981 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070012982 {
12983 v_U16_t i;
12984 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
12985 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012986 if ((pSapCtx->aStaInfo[i].isUsed) &&
12987 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070012988 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012989 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012990 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012991 ETHER_ADDR_LEN);
12992
Jeff Johnson295189b2012-06-20 16:38:30 -070012993 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012994 "%s: Delete STA with MAC::"
12995 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012996 __func__,
12997 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
12998 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012999 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013000 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013001 }
13002 }
13003 }
13004 else
13005 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013006
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013007 vos_status = hdd_softap_GetStaId(pAdapter,
13008 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013009 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13010 {
13011 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013012 "%s: Skip this DEL STA as this is not used::"
13013 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013014 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013015 return -ENOENT;
13016 }
13017
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013018 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013019 {
13020 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013021 "%s: Skip this DEL STA as deauth is in progress::"
13022 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013023 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013024 return -ENOENT;
13025 }
13026
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013027 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013028
Jeff Johnson295189b2012-06-20 16:38:30 -070013029 hddLog(VOS_TRACE_LEVEL_INFO,
13030 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013031 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013032 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013033 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013034
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013035 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013036 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13037 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013038 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013039 hddLog(VOS_TRACE_LEVEL_INFO,
13040 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013041 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013042 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013043 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013044 return -ENOENT;
13045 }
13046
Jeff Johnson295189b2012-06-20 16:38:30 -070013047 }
13048 }
13049
13050 EXIT();
13051
13052 return 0;
13053}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013054
13055#ifdef CFG80211_DEL_STA_V2
13056static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13057 struct net_device *dev,
13058 struct station_del_parameters *param)
13059#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013060static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13061 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013062#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013063{
13064 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013065 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070013066
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013067 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013068
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013069#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013070 if (NULL == param) {
13071 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013072 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013073 return -EINVAL;
13074 }
13075
13076 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
13077 param->subtype, &delStaParams);
13078
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013079#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053013080 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013081 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013082#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013083 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
13084
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013085 vos_ssr_unprotect(__func__);
13086
13087 return ret;
13088}
13089
13090static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013091 struct net_device *dev, u8 *mac, struct station_parameters *params)
13092{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013093 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013094 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013095#ifdef FEATURE_WLAN_TDLS
13096 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013097 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013098
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013099 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13100 TRACE_CODE_HDD_CFG80211_ADD_STA,
13101 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013102 mask = params->sta_flags_mask;
13103
13104 set = params->sta_flags_set;
13105
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013106#ifdef WLAN_FEATURE_TDLS_DEBUG
13107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13108 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
13109 __func__, mask, set, MAC_ADDR_ARRAY(mac));
13110#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013111
13112 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13113 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013114 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013115 }
13116 }
13117#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013118 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013119}
13120
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013121static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
13122 struct net_device *dev, u8 *mac, struct station_parameters *params)
13123{
13124 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013125
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013126 vos_ssr_protect(__func__);
13127 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
13128 vos_ssr_unprotect(__func__);
13129
13130 return ret;
13131}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013132#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070013133
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013134static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070013135 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013136{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013137 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13138 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013139 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013140 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013141 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013142 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070013143
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013144 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013145 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013146 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013147 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013148 return -EINVAL;
13149 }
13150
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013151 if (!pmksa) {
13152 hddLog(LOGE, FL("pmksa is NULL"));
13153 return -EINVAL;
13154 }
13155
13156 if (!pmksa->bssid || !pmksa->pmkid) {
13157 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
13158 pmksa->bssid, pmksa->pmkid);
13159 return -EINVAL;
13160 }
13161
13162 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
13163 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13164
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013165 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13166 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013167
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013168 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013169 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13171 "%s: HDD context is not valid", __func__);
13172 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013173 }
13174
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013175 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013176 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13177
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013178 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
13179 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013180
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013181 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013182 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013183 &pmk_id, 1, FALSE);
13184
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013185 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13186 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
13187 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013188
13189 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013190}
13191
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013192static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
13193 struct cfg80211_pmksa *pmksa)
13194{
13195 int ret;
13196
13197 vos_ssr_protect(__func__);
13198 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
13199 vos_ssr_unprotect(__func__);
13200
13201 return ret;
13202}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013203
Wilson Yang6507c4e2013-10-01 20:11:19 -070013204
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013205static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070013206 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013207{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013208 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13209 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013210 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013211 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013212
Wilson Yang6507c4e2013-10-01 20:11:19 -070013213 /* Validate pAdapter */
13214 if (NULL == pAdapter)
13215 {
13216 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
13217 return -EINVAL;
13218 }
13219
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013220 if (!pmksa) {
13221 hddLog(LOGE, FL("pmksa is NULL"));
13222 return -EINVAL;
13223 }
13224
13225 if (!pmksa->bssid) {
13226 hddLog(LOGE, FL("pmksa->bssid is NULL"));
13227 return -EINVAL;
13228 }
13229
Kiet Lam98c46a12014-10-31 15:34:57 -070013230 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
13231 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13232
Wilson Yang6507c4e2013-10-01 20:11:19 -070013233 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13234 status = wlan_hdd_validate_context(pHddCtx);
13235
13236 if (0 != status)
13237 {
13238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13239 "%s: HDD context is not valid", __func__);
13240 return status;
13241 }
13242
13243 /*Retrieve halHandle*/
13244 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13245
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013246 /* Delete the PMKID CSR cache */
13247 if (eHAL_STATUS_SUCCESS !=
13248 sme_RoamDelPMKIDfromCache(halHandle,
13249 pAdapter->sessionId, pmksa->bssid, FALSE)) {
13250 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
13251 MAC_ADDR_ARRAY(pmksa->bssid));
13252 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013253 }
13254
Wilson Yangef657d32014-01-15 19:19:23 -080013255 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013256}
13257
Wilson Yang6507c4e2013-10-01 20:11:19 -070013258
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013259static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
13260 struct cfg80211_pmksa *pmksa)
13261{
13262 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013263
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013264 vos_ssr_protect(__func__);
13265 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
13266 vos_ssr_unprotect(__func__);
13267
13268 return ret;
13269
13270}
13271
13272static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013273{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013274 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13275 tHalHandle halHandle;
13276 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013277 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013278
13279 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
13280
13281 /* Validate pAdapter */
13282 if (NULL == pAdapter)
13283 {
13284 hddLog(VOS_TRACE_LEVEL_ERROR,
13285 "%s: Invalid Adapter" ,__func__);
13286 return -EINVAL;
13287 }
13288
13289 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13290 status = wlan_hdd_validate_context(pHddCtx);
13291
13292 if (0 != status)
13293 {
13294 hddLog(VOS_TRACE_LEVEL_ERROR,
13295 "%s: HDD context is not valid", __func__);
13296 return status;
13297 }
13298
13299 /*Retrieve halHandle*/
13300 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13301
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013302 /* Flush the PMKID cache in CSR */
13303 if (eHAL_STATUS_SUCCESS !=
13304 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
13305 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
13306 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013307 }
13308
Wilson Yangef657d32014-01-15 19:19:23 -080013309 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013310}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013311
13312static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
13313{
13314 int ret;
13315
13316 vos_ssr_protect(__func__);
13317 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
13318 vos_ssr_unprotect(__func__);
13319
13320 return ret;
13321}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013322#endif
13323
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013324#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013325static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13326 struct net_device *dev,
13327 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013328{
13329 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13330 hdd_station_ctx_t *pHddStaCtx;
13331
13332 if (NULL == pAdapter)
13333 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013334 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013335 return -ENODEV;
13336 }
13337
13338 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13339
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013340 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13341 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
13342 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013343 // Added for debug on reception of Re-assoc Req.
13344 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
13345 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013346 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013347 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080013348 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013349 }
13350
13351#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080013352 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013353 ftie->ie_len);
13354#endif
13355
13356 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013357 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13358 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013359 ftie->ie_len);
13360 return 0;
13361}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013362
13363static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13364 struct net_device *dev,
13365 struct cfg80211_update_ft_ies_params *ftie)
13366{
13367 int ret;
13368
13369 vos_ssr_protect(__func__);
13370 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
13371 vos_ssr_unprotect(__func__);
13372
13373 return ret;
13374}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013375#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013376
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013377#ifdef FEATURE_WLAN_SCAN_PNO
13378
13379void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
13380 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
13381{
13382 int ret;
13383 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
13384 hdd_context_t *pHddCtx;
13385
Nirav Shah80830bf2013-12-31 16:35:12 +053013386 ENTER();
13387
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013388 if (NULL == pAdapter)
13389 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013390 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013391 "%s: HDD adapter is Null", __func__);
13392 return ;
13393 }
13394
13395 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13396 if (NULL == pHddCtx)
13397 {
13398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13399 "%s: HDD context is Null!!!", __func__);
13400 return ;
13401 }
13402
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013403 spin_lock(&pHddCtx->schedScan_lock);
13404 if (TRUE == pHddCtx->isWiphySuspended)
13405 {
13406 pHddCtx->isSchedScanUpdatePending = TRUE;
13407 spin_unlock(&pHddCtx->schedScan_lock);
13408 hddLog(VOS_TRACE_LEVEL_INFO,
13409 "%s: Update cfg80211 scan database after it resume", __func__);
13410 return ;
13411 }
13412 spin_unlock(&pHddCtx->schedScan_lock);
13413
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013414 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
13415
13416 if (0 > ret)
13417 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
13418
13419 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013420 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13421 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013422}
13423
13424/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013425 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013426 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013427 */
13428static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
13429{
13430 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13431 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013432 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013433 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13434 int status = 0;
13435 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13436
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013437 /* The current firmware design does not allow PNO during any
13438 * active sessions. Hence, determine the active sessions
13439 * and return a failure.
13440 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013441 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
13442 {
13443 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013444 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013445
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013446 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
13447 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
13448 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
13449 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
13450 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053013451 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013452 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013453 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013454 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013455 }
13456 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13457 pAdapterNode = pNext;
13458 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013459 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013460}
13461
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013462void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
13463{
13464 hdd_adapter_t *pAdapter = callbackContext;
13465 hdd_context_t *pHddCtx;
13466
13467 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
13468 {
13469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13470 FL("Invalid adapter or adapter has invalid magic"));
13471 return;
13472 }
13473
13474 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13475 if (0 != wlan_hdd_validate_context(pHddCtx))
13476 {
13477 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13478 FL("HDD context is not valid"));
13479 return;
13480 }
13481
c_hpothub53c45d2014-08-18 16:53:14 +053013482 if (VOS_STATUS_SUCCESS != status)
13483 {
13484 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013485 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053013486 pHddCtx->isPnoEnable = FALSE;
13487 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013488
13489 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
13490 complete(&pAdapter->pno_comp_var);
13491}
13492
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013493/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013494 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
13495 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013496 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013497static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013498 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13499{
13500 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13501 tpSirPNOScanReq pPnoRequest = NULL;
13502 hdd_context_t *pHddCtx;
13503 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013504 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053013505 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
13506 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013507 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13508 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013509 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013510 hdd_config_t *pConfig = NULL;
13511 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013512
13513 if (NULL == pAdapter)
13514 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013516 "%s: HDD adapter is Null", __func__);
13517 return -ENODEV;
13518 }
13519
13520 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013521 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013522
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013523 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013524 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013525 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13526 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013527 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013528 }
13529
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013530 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013531 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13532 if (NULL == hHal)
13533 {
13534 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13535 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013536 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013537 }
Sushant Kaushik2fe89932014-09-03 10:58:09 +053013538 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013539 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053013540 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013541 {
13542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13543 "%s: aborting the existing scan is unsuccessfull", __func__);
13544 return -EBUSY;
13545 }
13546
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013547 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013548 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013549 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013550 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013551 return -EBUSY;
13552 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013553
c_hpothu37f21312014-04-09 21:49:54 +053013554 if (TRUE == pHddCtx->isPnoEnable)
13555 {
13556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13557 FL("already PNO is enabled"));
13558 return -EBUSY;
13559 }
c_hpothu225aa7c2014-10-22 17:45:13 +053013560
13561 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
13562 {
13563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13564 "%s: abort ROC failed ", __func__);
13565 return -EBUSY;
13566 }
13567
c_hpothu37f21312014-04-09 21:49:54 +053013568 pHddCtx->isPnoEnable = TRUE;
13569
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013570 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13571 if (NULL == pPnoRequest)
13572 {
13573 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13574 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053013575 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013576 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013577 }
13578
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053013579 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013580 pPnoRequest->enable = 1; /*Enable PNO */
13581 pPnoRequest->ucNetworksCount = request->n_match_sets;
13582
13583 if (( !pPnoRequest->ucNetworksCount ) ||
13584 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
13585 {
13586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013587 "%s: Network input is not correct %d Max Network supported is %d",
13588 __func__, pPnoRequest->ucNetworksCount,
13589 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013590 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013591 goto error;
13592 }
13593
13594 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
13595 {
13596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013597 "%s: Incorrect number of channels %d",
13598 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013599 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013600 goto error;
13601 }
13602
13603 /* Framework provides one set of channels(all)
13604 * common for all saved profile */
13605 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13606 channels_allowed, &num_channels_allowed))
13607 {
13608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13609 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013610 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013611 goto error;
13612 }
13613 /* Checking each channel against allowed channel list */
13614 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053013615 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013616 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013617 char chList [(request->n_channels*5)+1];
13618 int len;
13619 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013620 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013621 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013622 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013623 if (request->channels[i]->hw_value == channels_allowed[indx])
13624 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013625 if ((!pConfig->enableDFSPnoChnlScan) &&
13626 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
13627 {
13628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13629 "%s : Dropping DFS channel : %d",
13630 __func__,channels_allowed[indx]);
13631 num_ignore_dfs_ch++;
13632 break;
13633 }
13634
Nirav Shah80830bf2013-12-31 16:35:12 +053013635 valid_ch[num_ch++] = request->channels[i]->hw_value;
13636 len += snprintf(chList+len, 5, "%d ",
13637 request->channels[i]->hw_value);
13638 break ;
13639 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013640 }
13641 }
Nirav Shah80830bf2013-12-31 16:35:12 +053013642 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013643
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013644 /*If all channels are DFS and dropped, then ignore the PNO request*/
13645 if (num_ignore_dfs_ch == request->n_channels)
13646 {
13647 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13648 "%s : All requested channels are DFS channels", __func__);
13649 ret = -EINVAL;
13650 goto error;
13651 }
13652 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013653 /* Filling per profile params */
13654 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
13655 {
13656 pPnoRequest->aNetworks[i].ssId.length =
13657 request->match_sets[i].ssid.ssid_len;
13658
13659 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
13660 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
13661 {
13662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013663 "%s: SSID Len %d is not correct for network %d",
13664 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013665 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013666 goto error;
13667 }
13668
13669 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
13670 request->match_sets[i].ssid.ssid,
13671 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13673 "%s: SSID of network %d is %s ", __func__,
13674 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013675 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
13676 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
13677 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
13678
13679 /*Copying list of valid channel into request */
13680 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
13681 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
13682
13683 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
13684 }
13685
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013686 for (i = 0; i < request->n_ssids; i++)
13687 {
13688 j = 0;
13689 while (j < pPnoRequest->ucNetworksCount)
13690 {
13691 if ((pPnoRequest->aNetworks[j].ssId.length ==
13692 request->ssids[i].ssid_len) &&
13693 (0 == memcmp(pPnoRequest->aNetworks[j].ssId.ssId,
13694 request->ssids[i].ssid,
13695 pPnoRequest->aNetworks[j].ssId.length)))
13696 {
13697 pPnoRequest->aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
13698 break;
13699 }
13700 j++;
13701 }
13702 }
13703 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13704 "Number of hidden networks being Configured = %d",
13705 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080013707 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013708 if ((0 < request->ie_len) && (NULL != request->ie))
13709 {
13710 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
13711 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
13712 pPnoRequest->us24GProbeTemplateLen);
13713
13714 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
13715 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
13716 pPnoRequest->us5GProbeTemplateLen);
13717 }
13718
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053013719 /* Driver gets only one time interval which is hardcoded in
13720 * supplicant for 10000ms. Taking power consumption into account 6 timers
13721 * will be used, Timervalue is increased exponentially i.e 10,20,40,
13722 * 80,160,320 secs. And number of scan cycle for each timer
13723 * is configurable through INI param gPNOScanTimerRepeatValue.
13724 * If it is set to 0 only one timer will be used and PNO scan cycle
13725 * will be repeated after each interval specified by supplicant
13726 * till PNO is disabled.
13727 */
13728 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
13729 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
13730 else
13731 pPnoRequest->scanTimers.ucScanTimersCount =
13732 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
13733
13734 tempInterval = (request->interval)/1000;
13735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13736 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
13737 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
13738 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
13739 {
13740 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
13741 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
13742 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
13743 tempInterval *= 2;
13744 }
13745 //Repeat last timer until pno disabled.
13746 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
13747
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053013748 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013749
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013750 INIT_COMPLETION(pAdapter->pno_comp_var);
13751 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
13752 pPnoRequest->callbackContext = pAdapter;
13753 pAdapter->pno_req_status = 0;
13754
Nirav Shah80830bf2013-12-31 16:35:12 +053013755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13756 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
13757 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
13758 pPnoRequest->scanTimers.ucScanTimersCount);
13759
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013760 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
13761 pPnoRequest, pAdapter->sessionId,
13762 hdd_cfg80211_sched_scan_done_callback, pAdapter);
13763 if (eHAL_STATUS_SUCCESS != status)
13764 {
13765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013766 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013767 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013768 goto error;
13769 }
13770
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013771 ret = wait_for_completion_timeout(
13772 &pAdapter->pno_comp_var,
13773 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
13774 if (0 >= ret)
13775 {
13776 // Did not receive the response for PNO enable in time.
13777 // Assuming the PNO enable was success.
13778 // Returning error from here, because we timeout, results
13779 // in side effect of Wifi (Wifi Setting) not to work.
13780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13781 FL("Timed out waiting for PNO to be Enabled"));
13782 ret = 0;
13783 goto error;
13784 }
13785
c_hpothu3c986b22014-07-09 14:45:09 +053013786 vos_mem_free(pPnoRequest);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013787 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053013788 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013789
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013790error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13792 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013793 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053013794 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013795 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013796}
13797
13798/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013799 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
13800 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013801 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013802static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
13803 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13804{
13805 int ret;
13806
13807 vos_ssr_protect(__func__);
13808 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
13809 vos_ssr_unprotect(__func__);
13810
13811 return ret;
13812}
13813
13814/*
13815 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
13816 * Function to disable PNO
13817 */
13818static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013819 struct net_device *dev)
13820{
13821 eHalStatus status = eHAL_STATUS_FAILURE;
13822 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13823 hdd_context_t *pHddCtx;
13824 tHalHandle hHal;
13825 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013826 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013827
13828 ENTER();
13829
13830 if (NULL == pAdapter)
13831 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013832 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013833 "%s: HDD adapter is Null", __func__);
13834 return -ENODEV;
13835 }
13836
13837 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013838
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013839 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013840 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013842 "%s: HDD context is Null", __func__);
13843 return -ENODEV;
13844 }
13845
13846 /* The return 0 is intentional when isLogpInProgress and
13847 * isLoadUnloadInProgress. We did observe a crash due to a return of
13848 * failure in sched_scan_stop , especially for a case where the unload
13849 * of the happens at the same time. The function __cfg80211_stop_sched_scan
13850 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
13851 * success. If it returns a failure , then its next invocation due to the
13852 * clean up of the second interface will have the dev pointer corresponding
13853 * to the first one leading to a crash.
13854 */
13855 if (pHddCtx->isLogpInProgress)
13856 {
13857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13858 "%s: LOGP in Progress. Ignore!!!", __func__);
13859 return ret;
13860 }
13861
Mihir Shete18156292014-03-11 15:38:30 +053013862 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013863 {
13864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13865 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13866 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013867 }
13868
13869 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13870 if (NULL == hHal)
13871 {
13872 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13873 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013874 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013875 }
13876
13877 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13878 if (NULL == pPnoRequest)
13879 {
13880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13881 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013882 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013883 }
13884
13885 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
13886 pPnoRequest->enable = 0; /* Disable PNO */
13887 pPnoRequest->ucNetworksCount = 0;
13888
13889 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
13890 pAdapter->sessionId,
13891 NULL, pAdapter);
13892 if (eHAL_STATUS_SUCCESS != status)
13893 {
13894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13895 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013896 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013897 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013898 }
c_hpothu37f21312014-04-09 21:49:54 +053013899 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013900
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013901error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013903 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013904 vos_mem_free(pPnoRequest);
13905
13906 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013907 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013908}
13909
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013910/*
13911 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
13912 * NL interface to disable PNO
13913 */
13914static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
13915 struct net_device *dev)
13916{
13917 int ret;
13918
13919 vos_ssr_protect(__func__);
13920 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
13921 vos_ssr_unprotect(__func__);
13922
13923 return ret;
13924}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013925#endif /*FEATURE_WLAN_SCAN_PNO*/
13926
13927
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013928#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013929#if TDLS_MGMT_VERSION2
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013930static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013931 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013932 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
13933#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013934static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013935 u8 *peer, u8 action_code, u8 dialog_token,
13936 u16 status_code, const u8 *buf, size_t len)
13937#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013938{
13939
13940 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13941 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013942 u8 peerMac[6];
13943 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070013944 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080013945 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070013946 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053013947 int ret;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013948#if !(TDLS_MGMT_VERSION2)
13949 u32 peer_capability = 0;
13950#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013951 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013952
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013953 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13954 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
13955 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013956 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013957 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013958 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013959 "Invalid arguments");
13960 return -EINVAL;
13961 }
13962
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013963 if (pHddCtx->isLogpInProgress)
13964 {
13965 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13966 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053013967 wlan_hdd_tdls_set_link_status(pAdapter,
13968 peer,
13969 eTDLS_LINK_IDLE,
13970 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013971 return -EBUSY;
13972 }
13973
Hoonki Lee27511902013-03-14 18:19:06 -070013974 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013975 {
Hoonki Lee27511902013-03-14 18:19:06 -070013976 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13977 "%s: TDLS mode is disabled OR not enabled in FW."
13978 MAC_ADDRESS_STR " action %d declined.",
13979 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013980 return -ENOTSUPP;
13981 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013982
Hoonki Lee27511902013-03-14 18:19:06 -070013983 /* other than teardown frame, other mgmt frames are not sent if disabled */
13984 if (SIR_MAC_TDLS_TEARDOWN != action_code)
13985 {
13986 /* if tdls_mode is disabled to respond to peer's request */
13987 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
13988 {
13989 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13990 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013991 " TDLS mode is disabled. action %d declined.",
13992 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070013993
13994 return -ENOTSUPP;
13995 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053013996
13997 if (vos_max_concurrent_connections_reached())
13998 {
13999 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14000 return -EINVAL;
14001 }
Hoonki Lee27511902013-03-14 18:19:06 -070014002 }
14003
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014004 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
14005 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014006 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014007 {
14008 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014009 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014010 " TDLS setup is ongoing. action %d declined.",
14011 __func__, MAC_ADDR_ARRAY(peer), action_code);
14012 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014013 }
14014 }
14015
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014016 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
14017 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080014018 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014019 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14020 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014021 {
14022 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
14023 we return error code at 'add_station()'. Hence we have this
14024 check again in addtion to add_station().
14025 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014026 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014027 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014028 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14029 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014030 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
14031 __func__, MAC_ADDR_ARRAY(peer), action_code,
14032 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053014033 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080014034 }
14035 else
14036 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014037 /* maximum reached. tweak to send error code to peer and return
14038 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014039 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014040 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14041 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014042 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
14043 __func__, MAC_ADDR_ARRAY(peer), status_code,
14044 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070014045 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014046 /* fall through to send setup resp with failure status
14047 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014048 }
14049 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014050 else
14051 {
14052 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014053 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014054 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014055 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014057 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
14058 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014059 return -EPERM;
14060 }
14061 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014062 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014063 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014064
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014065#ifdef WLAN_FEATURE_TDLS_DEBUG
14066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014067 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014068 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
14069 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014070#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014071
Hoonki Leea34dd892013-02-05 22:56:02 -080014072 /*Except teardown responder will not be used so just make 0*/
14073 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014074 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080014075 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014076
14077 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014078 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014079
14080 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
14081 responder = pTdlsPeer->is_responder;
14082 else
Hoonki Leea34dd892013-02-05 22:56:02 -080014083 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014084 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014085 "%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 -070014086 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
14087 dialog_token, status_code, len);
14088 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080014089 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014090 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014091
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014092 /* For explicit trigger of DIS_REQ come out of BMPS for
14093 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070014094 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014095 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
14096 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070014097 {
14098 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
14099 {
14100 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014101 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070014102 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
14103 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014104 if (SIR_MAC_TDLS_DIS_REQ != action_code)
14105 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070014106 }
14107
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014108 /* make sure doesn't call send_mgmt() while it is pending */
14109 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
14110 {
14111 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014112 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014113 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014114 ret = -EBUSY;
14115 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014116 }
14117
14118 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014119 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
14120
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014121 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053014122 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014123
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014124 if (VOS_STATUS_SUCCESS != status)
14125 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014126 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14127 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014128 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014129 ret = -EINVAL;
14130 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014131 }
14132
Hoonki Leed37cbb32013-04-20 00:31:14 -070014133 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
14134 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
14135
14136 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014137 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070014138 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014139 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070014140 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014141 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080014142
14143 if (pHddCtx->isLogpInProgress)
14144 {
14145 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14146 "%s: LOGP in Progress. Ignore!!!", __func__);
14147 return -EAGAIN;
14148 }
14149
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014150 ret = -EINVAL;
14151 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014152 }
14153
Gopichand Nakkala05922802013-03-14 12:23:19 -070014154 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070014155 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014156 ret = max_sta_failed;
14157 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070014158 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014159
Hoonki Leea34dd892013-02-05 22:56:02 -080014160 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
14161 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014162 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080014163 }
14164 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
14165 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014166 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080014167 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014168
14169 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014170
14171tx_failed:
14172 /* add_station will be called before sending TDLS_SETUP_REQ and
14173 * TDLS_SETUP_RSP and as part of add_station driver will enable
14174 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
14175 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
14176 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
14177 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
14178 */
14179
14180 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
14181 (SIR_MAC_TDLS_SETUP_RSP == action_code))
14182 wlan_hdd_tdls_check_bmps(pAdapter);
14183 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014184}
14185
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014186#if TDLS_MGMT_VERSION2
14187static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14188 u8 *peer, u8 action_code, u8 dialog_token,
14189 u16 status_code, u32 peer_capability,
14190 const u8 *buf, size_t len)
14191#else
14192static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14193 u8 *peer, u8 action_code, u8 dialog_token,
14194 u16 status_code, const u8 *buf, size_t len)
14195#endif
14196{
14197 int ret;
14198
14199 vos_ssr_protect(__func__);
14200#if TDLS_MGMT_VERSION2
14201 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14202 status_code, peer_capability, buf, len);
14203#else
14204 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14205 status_code, buf, len);
14206#endif
14207 vos_ssr_unprotect(__func__);
14208
14209 return ret;
14210}
Atul Mittal115287b2014-07-08 13:26:33 +053014211
14212int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
14213 u8 *peer,
14214 cfg80211_exttdls_callback callback)
14215{
14216
14217 hddTdlsPeer_t *pTdlsPeer;
14218 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14220 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
14221 __func__, MAC_ADDR_ARRAY(peer));
14222
14223 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14224 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14225
14226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14227 " %s TDLS External control and Implicit Trigger not enabled ",
14228 __func__);
14229 return -ENOTSUPP;
14230 }
14231
14232 /* To cater the requirement of establishing the TDLS link
14233 * irrespective of the data traffic , get an entry of TDLS peer.
14234 */
14235 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
14236 if (pTdlsPeer == NULL) {
14237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14238 "%s: peer " MAC_ADDRESS_STR " not existing",
14239 __func__, MAC_ADDR_ARRAY(peer));
14240 return -EINVAL;
14241 }
14242
14243 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
14244
14245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14246 " %s TDLS Add Force Peer Failed",
14247 __func__);
14248 return -EINVAL;
14249 }
14250 /*EXT TDLS*/
14251
14252 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
14253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14254 " %s TDLS set callback Failed",
14255 __func__);
14256 return -EINVAL;
14257 }
14258
14259 return(0);
14260
14261}
14262
14263int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
14264{
14265
14266 hddTdlsPeer_t *pTdlsPeer;
14267 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14269 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
14270 __func__, MAC_ADDR_ARRAY(peer));
14271
14272 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14273 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14274
14275 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14276 " %s TDLS External control and Implicit Trigger not enabled ",
14277 __func__);
14278 return -ENOTSUPP;
14279 }
14280
14281
14282 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
14283
14284 if ( NULL == pTdlsPeer ) {
14285 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
14286 " peer not exsting",
14287 __func__, MAC_ADDR_ARRAY(peer));
14288 return -EINVAL;
14289 }
14290 else {
14291 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
14292 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
14293 }
14294
14295 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
14296 return -EINVAL;
14297
14298 /*EXT TDLS*/
14299
14300 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
14301
14302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14303 " %s TDLS set callback Failed",
14304 __func__);
14305 return -EINVAL;
14306 }
14307 return(0);
14308
14309}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014310static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014311 u8 *peer, enum nl80211_tdls_operation oper)
14312{
14313 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14314 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014315 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014316 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014317
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014318 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14319 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
14320 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014321 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014322 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014324 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014325 return -EINVAL;
14326 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014327
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014328 status = wlan_hdd_validate_context(pHddCtx);
14329
14330 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014331 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014332 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14333 "%s: HDD context is not valid", __func__);
14334 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014335 }
14336
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014337
14338 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014339 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014340 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014341 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014342 "TDLS Disabled in INI OR not enabled in FW. "
14343 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014344 return -ENOTSUPP;
14345 }
14346
14347 switch (oper) {
14348 case NL80211_TDLS_ENABLE_LINK:
14349 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014350 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014351 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014352 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053014353 WLAN_STADescType staDesc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014354
Sunil Dutt41de4e22013-11-14 18:09:02 +053014355 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053014356 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053014357 if ( NULL == pTdlsPeer ) {
14358 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
14359 " (oper %d) not exsting. ignored",
14360 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
14361 return -EINVAL;
14362 }
14363
14364 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14365 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
14366 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
14367 "NL80211_TDLS_ENABLE_LINK");
14368
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070014369 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
14370 {
14371 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
14372 MAC_ADDRESS_STR " failed",
14373 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
14374 return -EINVAL;
14375 }
14376
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014377 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014378 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014379 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053014380
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014381 if (0 != wlan_hdd_tdls_get_link_establish_params(
14382 pAdapter, peer,&tdlsLinkEstablishParams)) {
14383 return -EINVAL;
14384 }
14385 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014386
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014387 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
14388 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
14389 /* Send TDLS peer UAPSD capabilities to the firmware and
14390 * register with the TL on after the response for this operation
14391 * is received .
14392 */
14393 ret = wait_for_completion_interruptible_timeout(
14394 &pAdapter->tdls_link_establish_req_comp,
14395 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
14396 if (ret <= 0)
14397 {
14398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14399 "%s: Link Establish Request Faled Status %ld",
14400 __func__, ret);
14401 return -EINVAL;
14402 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014403 }
Atul Mittal115287b2014-07-08 13:26:33 +053014404 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
14405 eTDLS_LINK_CONNECTED,
14406 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053014407 staDesc.ucSTAId = pTdlsPeer->staId;
14408 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
14409 WLANTL_UpdateTdlsSTAClient(pHddCtx->pvosContext,
14410 &staDesc);
14411
14412
Gopichand Nakkala471708b2013-06-04 20:03:01 +053014413 /* Mark TDLS client Authenticated .*/
14414 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
14415 pTdlsPeer->staId,
14416 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014417 if (VOS_STATUS_SUCCESS == status)
14418 {
Hoonki Lee14621352013-04-16 17:51:19 -070014419 if (pTdlsPeer->is_responder == 0)
14420 {
14421 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
14422
14423 wlan_hdd_tdls_timer_restart(pAdapter,
14424 &pTdlsPeer->initiatorWaitTimeoutTimer,
14425 WAIT_TIME_TDLS_INITIATOR);
14426 /* suspend initiator TX until it receives direct packet from the
14427 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
14428 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
14429 &staId, NULL);
14430 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014431 wlan_hdd_tdls_increment_peer_count(pAdapter);
14432 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014433 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014434
14435 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053014436 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
14437 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014438 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053014439 int ac;
14440 uint8 ucAc[4] = { WLANTL_AC_VO,
14441 WLANTL_AC_VI,
14442 WLANTL_AC_BK,
14443 WLANTL_AC_BE };
14444 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
14445 for(ac=0; ac < 4; ac++)
14446 {
14447 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
14448 pTdlsPeer->staId, ucAc[ac],
14449 tlTid[ac], tlTid[ac], 0, 0,
14450 WLANTL_BI_DIR );
14451 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014452 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014453 }
14454
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014455 }
14456 break;
14457 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080014458 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053014459 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
14460
14461 if ( NULL == pTdlsPeer ) {
14462 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
14463 " (oper %d) not exsting. ignored",
14464 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
14465 return -EINVAL;
14466 }
14467
14468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14469 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
14470 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
14471 "NL80211_TDLS_DISABLE_LINK");
14472
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014473 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080014474 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014475 long status;
14476
Atul Mittal271a7652014-09-12 13:18:22 +053014477
14478 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
14479 eTDLS_LINK_TEARING,
14480 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
14481 eTDLS_LINK_UNSPECIFIED:
14482 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014483 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
14484
Lee Hoonkic1262f22013-01-24 21:59:00 -080014485 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
14486 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014487
14488 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
14489 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053014490 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053014491 eTDLS_LINK_IDLE,
14492 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014493 if (status <= 0)
14494 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014495 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14496 "%s: Del station failed status %ld",
14497 __func__, status);
14498 return -EPERM;
14499 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014500 }
14501 else
14502 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14504 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080014505 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014506 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014507 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014508 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053014509 {
Atul Mittal115287b2014-07-08 13:26:33 +053014510 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053014511
Atul Mittal115287b2014-07-08 13:26:33 +053014512 if (0 != status)
14513 {
14514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14515 "%s: Error in TDLS Teardown", __func__);
14516 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053014517 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053014518 break;
14519 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014520 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053014521 {
Atul Mittal115287b2014-07-08 13:26:33 +053014522 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
14523 peer,
14524 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053014525
Atul Mittal115287b2014-07-08 13:26:33 +053014526 if (0 != status)
14527 {
14528 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14529 "%s: Error in TDLS Setup", __func__);
14530 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053014531 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053014532 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053014533 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014534 case NL80211_TDLS_DISCOVERY_REQ:
14535 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14537 "%s: We don't support in-driver setup/teardown/discovery "
14538 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014539 return -ENOTSUPP;
14540 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14542 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014543 return -ENOTSUPP;
14544 }
14545 return 0;
14546}
Chilam NG571c65a2013-01-19 12:27:36 +053014547
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014548static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
14549 u8 *peer, enum nl80211_tdls_operation oper)
14550{
14551 int ret;
14552
14553 vos_ssr_protect(__func__);
14554 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
14555 vos_ssr_unprotect(__func__);
14556
14557 return ret;
14558}
14559
Chilam NG571c65a2013-01-19 12:27:36 +053014560int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
14561 struct net_device *dev, u8 *peer)
14562{
Arif Hussaina7c8e412013-11-20 11:06:42 -080014563 hddLog(VOS_TRACE_LEVEL_INFO,
14564 "tdls send discover req: "MAC_ADDRESS_STR,
14565 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053014566
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014567#if TDLS_MGMT_VERSION2
14568 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14569 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
14570#else
Chilam NG571c65a2013-01-19 12:27:36 +053014571 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14572 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014573#endif
Chilam NG571c65a2013-01-19 12:27:36 +053014574}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014575#endif
14576
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014577#ifdef WLAN_FEATURE_GTK_OFFLOAD
14578/*
14579 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
14580 * Callback rountine called upon receiving response for
14581 * get offload info
14582 */
14583void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
14584 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
14585{
14586
14587 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014588 tANI_U8 tempReplayCounter[8];
14589 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014590
14591 ENTER();
14592
14593 if (NULL == pAdapter)
14594 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014596 "%s: HDD adapter is Null", __func__);
14597 return ;
14598 }
14599
14600 if (NULL == pGtkOffloadGetInfoRsp)
14601 {
14602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14603 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
14604 return ;
14605 }
14606
14607 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
14608 {
14609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14610 "%s: wlan Failed to get replay counter value",
14611 __func__);
14612 return ;
14613 }
14614
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014615 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14616 /* Update replay counter */
14617 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
14618 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14619
14620 {
14621 /* changing from little to big endian since supplicant
14622 * works on big endian format
14623 */
14624 int i;
14625 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14626
14627 for (i = 0; i < 8; i++)
14628 {
14629 tempReplayCounter[7-i] = (tANI_U8)p[i];
14630 }
14631 }
14632
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014633 /* Update replay counter to NL */
14634 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014635 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014636}
14637
14638/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014639 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014640 * This function is used to offload GTK rekeying job to the firmware.
14641 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014642int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014643 struct cfg80211_gtk_rekey_data *data)
14644{
14645 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14646 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14647 hdd_station_ctx_t *pHddStaCtx;
14648 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014649 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014650 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014651 eHalStatus status = eHAL_STATUS_FAILURE;
14652
14653 ENTER();
14654
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014655
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014656 if (NULL == pAdapter)
14657 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014659 "%s: HDD adapter is Null", __func__);
14660 return -ENODEV;
14661 }
14662
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014663 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14664 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
14665 pAdapter->sessionId, pAdapter->device_mode));
14666
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014667 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014668
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014669 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014670 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14672 "%s: HDD context is not valid", __func__);
14673 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014674 }
14675
14676 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14677 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14678 if (NULL == hHal)
14679 {
14680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14681 "%s: HAL context is Null!!!", __func__);
14682 return -EAGAIN;
14683 }
14684
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014685 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
14686 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
14687 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
14688 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014689 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014690 {
14691 /* changing from big to little endian since driver
14692 * works on little endian format
14693 */
14694 tANI_U8 *p =
14695 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
14696 int i;
14697
14698 for (i = 0; i < 8; i++)
14699 {
14700 p[7-i] = data->replay_ctr[i];
14701 }
14702 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014703
14704 if (TRUE == pHddCtx->hdd_wlan_suspended)
14705 {
14706 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014707 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
14708 sizeof (tSirGtkOffloadParams));
14709 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014710 pAdapter->sessionId);
14711
14712 if (eHAL_STATUS_SUCCESS != status)
14713 {
14714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14715 "%s: sme_SetGTKOffload failed, returned %d",
14716 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053014717
14718 /* Need to clear any trace of key value in the memory.
14719 * Thus zero out the memory even though it is local
14720 * variable.
14721 */
14722 vos_mem_zero(&hddGtkOffloadReqParams,
14723 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014724 return status;
14725 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14727 "%s: sme_SetGTKOffload successfull", __func__);
14728 }
14729 else
14730 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14732 "%s: wlan not suspended GTKOffload request is stored",
14733 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014734 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014735
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053014736 /* Need to clear any trace of key value in the memory.
14737 * Thus zero out the memory even though it is local
14738 * variable.
14739 */
14740 vos_mem_zero(&hddGtkOffloadReqParams,
14741 sizeof(hddGtkOffloadReqParams));
14742
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014743 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014744}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014745
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014746int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
14747 struct cfg80211_gtk_rekey_data *data)
14748{
14749 int ret;
14750
14751 vos_ssr_protect(__func__);
14752 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
14753 vos_ssr_unprotect(__func__);
14754
14755 return ret;
14756}
14757#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014758/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014759 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014760 * This function is used to set access control policy
14761 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014762static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
14763 struct net_device *dev,
14764 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014765{
14766 int i;
14767 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14768 hdd_hostapd_state_t *pHostapdState;
14769 tsap_Config_t *pConfig;
14770 v_CONTEXT_t pVosContext = NULL;
14771 hdd_context_t *pHddCtx;
14772 int status;
14773
14774 ENTER();
14775
14776 if (NULL == pAdapter)
14777 {
14778 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14779 "%s: HDD adapter is Null", __func__);
14780 return -ENODEV;
14781 }
14782
14783 if (NULL == params)
14784 {
14785 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14786 "%s: params is Null", __func__);
14787 return -EINVAL;
14788 }
14789
14790 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14791 status = wlan_hdd_validate_context(pHddCtx);
14792
14793 if (0 != status)
14794 {
14795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14796 "%s: HDD context is not valid", __func__);
14797 return status;
14798 }
14799
14800 pVosContext = pHddCtx->pvosContext;
14801 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
14802
14803 if (NULL == pHostapdState)
14804 {
14805 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14806 "%s: pHostapdState is Null", __func__);
14807 return -EINVAL;
14808 }
14809
14810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
14811 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
14812
14813 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
14814 {
14815 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
14816
14817 /* default value */
14818 pConfig->num_accept_mac = 0;
14819 pConfig->num_deny_mac = 0;
14820
14821 /**
14822 * access control policy
14823 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
14824 * listed in hostapd.deny file.
14825 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
14826 * listed in hostapd.accept file.
14827 */
14828 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
14829 {
14830 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
14831 }
14832 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
14833 {
14834 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
14835 }
14836 else
14837 {
14838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14839 "%s:Acl Policy : %d is not supported",
14840 __func__, params->acl_policy);
14841 return -ENOTSUPP;
14842 }
14843
14844 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
14845 {
14846 pConfig->num_accept_mac = params->n_acl_entries;
14847 for (i = 0; i < params->n_acl_entries; i++)
14848 {
14849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14850 "** Add ACL MAC entry %i in WhiletList :"
14851 MAC_ADDRESS_STR, i,
14852 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14853
14854 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
14855 sizeof(qcmacaddr));
14856 }
14857 }
14858 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
14859 {
14860 pConfig->num_deny_mac = params->n_acl_entries;
14861 for (i = 0; i < params->n_acl_entries; i++)
14862 {
14863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14864 "** Add ACL MAC entry %i in BlackList :"
14865 MAC_ADDRESS_STR, i,
14866 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14867
14868 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
14869 sizeof(qcmacaddr));
14870 }
14871 }
14872
14873 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
14874 {
14875 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14876 "%s: SAP Set Mac Acl fail", __func__);
14877 return -EINVAL;
14878 }
14879 }
14880 else
14881 {
14882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014883 "%s: Invalid device_mode = %s (%d)",
14884 __func__, hdd_device_modetoString(pAdapter->device_mode),
14885 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014886 return -EINVAL;
14887 }
14888
14889 return 0;
14890}
14891
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014892static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
14893 struct net_device *dev,
14894 const struct cfg80211_acl_data *params)
14895{
14896 int ret;
14897 vos_ssr_protect(__func__);
14898 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
14899 vos_ssr_unprotect(__func__);
14900
14901 return ret;
14902}
14903
Leo Chang9056f462013-08-01 19:21:11 -070014904#ifdef WLAN_NL80211_TESTMODE
14905#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070014906void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070014907(
14908 void *pAdapter,
14909 void *indCont
14910)
14911{
Leo Changd9df8aa2013-09-26 13:32:26 -070014912 tSirLPHBInd *lphbInd;
14913 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053014914 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070014915
14916 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014917 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070014918
c_hpothu73f35e62014-04-18 13:40:08 +053014919 if (pAdapter == NULL)
14920 {
14921 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14922 "%s: pAdapter is NULL\n",__func__);
14923 return;
14924 }
14925
Leo Chang9056f462013-08-01 19:21:11 -070014926 if (NULL == indCont)
14927 {
14928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014929 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070014930 return;
14931 }
14932
c_hpothu73f35e62014-04-18 13:40:08 +053014933 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070014934 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070014935 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053014936 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070014937 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070014938 GFP_ATOMIC);
14939 if (!skb)
14940 {
14941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14942 "LPHB timeout, NL buffer alloc fail");
14943 return;
14944 }
14945
Leo Changac3ba772013-10-07 09:47:04 -070014946 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070014947 {
14948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14949 "WLAN_HDD_TM_ATTR_CMD put fail");
14950 goto nla_put_failure;
14951 }
Leo Changac3ba772013-10-07 09:47:04 -070014952 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070014953 {
14954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14955 "WLAN_HDD_TM_ATTR_TYPE put fail");
14956 goto nla_put_failure;
14957 }
Leo Changac3ba772013-10-07 09:47:04 -070014958 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070014959 sizeof(tSirLPHBInd), lphbInd))
14960 {
14961 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14962 "WLAN_HDD_TM_ATTR_DATA put fail");
14963 goto nla_put_failure;
14964 }
Leo Chang9056f462013-08-01 19:21:11 -070014965 cfg80211_testmode_event(skb, GFP_ATOMIC);
14966 return;
14967
14968nla_put_failure:
14969 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14970 "NLA Put fail");
14971 kfree_skb(skb);
14972
14973 return;
14974}
14975#endif /* FEATURE_WLAN_LPHB */
14976
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014977static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070014978{
14979 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
14980 int err = 0;
14981#ifdef FEATURE_WLAN_LPHB
14982 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070014983 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -070014984#endif /* FEATURE_WLAN_LPHB */
14985
14986 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
14987 if (err)
14988 {
14989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14990 "%s Testmode INV ATTR", __func__);
14991 return err;
14992 }
14993
14994 if (!tb[WLAN_HDD_TM_ATTR_CMD])
14995 {
14996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14997 "%s Testmode INV CMD", __func__);
14998 return -EINVAL;
14999 }
15000
15001 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
15002 {
15003#ifdef FEATURE_WLAN_LPHB
15004 /* Low Power Heartbeat configuration request */
15005 case WLAN_HDD_TM_CMD_WLAN_HB:
15006 {
15007 int buf_len;
15008 void *buf;
15009 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080015010 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070015011
15012 if (!tb[WLAN_HDD_TM_ATTR_DATA])
15013 {
15014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15015 "%s Testmode INV DATA", __func__);
15016 return -EINVAL;
15017 }
15018
15019 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
15020 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080015021
15022 hb_params_temp =(tSirLPHBReq *)buf;
15023 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
15024 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
15025 return -EINVAL;
15026
Leo Chang9056f462013-08-01 19:21:11 -070015027 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
15028 if (NULL == hb_params)
15029 {
15030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15031 "%s Request Buffer Alloc Fail", __func__);
15032 return -EINVAL;
15033 }
15034
15035 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070015036 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
15037 hb_params,
15038 wlan_hdd_cfg80211_lphb_ind_handler);
15039 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070015040 {
Leo Changd9df8aa2013-09-26 13:32:26 -070015041 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15042 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070015043 vos_mem_free(hb_params);
15044 }
Leo Chang9056f462013-08-01 19:21:11 -070015045 return 0;
15046 }
15047#endif /* FEATURE_WLAN_LPHB */
15048 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15050 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070015051 return -EOPNOTSUPP;
15052 }
15053
15054 return err;
15055}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015056
15057static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
15058{
15059 int ret;
15060
15061 vos_ssr_protect(__func__);
15062 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
15063 vos_ssr_unprotect(__func__);
15064
15065 return ret;
15066}
Leo Chang9056f462013-08-01 19:21:11 -070015067#endif /* CONFIG_NL80211_TESTMODE */
15068
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015069static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015070 struct net_device *dev,
15071 int idx, struct survey_info *survey)
15072{
15073 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15074 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053015075 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015076 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053015077 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015078 v_S7_t snr,rssi;
15079 int status, i, j, filled = 0;
15080
15081 ENTER();
15082
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015083 if (NULL == pAdapter)
15084 {
15085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15086 "%s: HDD adapter is Null", __func__);
15087 return -ENODEV;
15088 }
15089
15090 if (NULL == wiphy)
15091 {
15092 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15093 "%s: wiphy is Null", __func__);
15094 return -ENODEV;
15095 }
15096
15097 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15098 status = wlan_hdd_validate_context(pHddCtx);
15099
15100 if (0 != status)
15101 {
15102 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15103 "%s: HDD context is not valid", __func__);
15104 return status;
15105 }
15106
Mihir Sheted9072e02013-08-21 17:02:29 +053015107 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15108
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015109 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053015110 0 != pAdapter->survey_idx ||
15111 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015112 {
15113 /* The survey dump ops when implemented completely is expected to
15114 * return a survey of all channels and the ops is called by the
15115 * kernel with incremental values of the argument 'idx' till it
15116 * returns -ENONET. But we can only support the survey for the
15117 * operating channel for now. survey_idx is used to track
15118 * that the ops is called only once and then return -ENONET for
15119 * the next iteration
15120 */
15121 pAdapter->survey_idx = 0;
15122 return -ENONET;
15123 }
15124
15125 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15126
15127 wlan_hdd_get_snr(pAdapter, &snr);
15128 wlan_hdd_get_rssi(pAdapter, &rssi);
15129
15130 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
15131 hdd_wlan_get_freq(channel, &freq);
15132
15133
15134 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
15135 {
15136 if (NULL == wiphy->bands[i])
15137 {
15138 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
15139 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
15140 continue;
15141 }
15142
15143 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
15144 {
15145 struct ieee80211_supported_band *band = wiphy->bands[i];
15146
15147 if (band->channels[j].center_freq == (v_U16_t)freq)
15148 {
15149 survey->channel = &band->channels[j];
15150 /* The Rx BDs contain SNR values in dB for the received frames
15151 * while the supplicant expects noise. So we calculate and
15152 * return the value of noise (dBm)
15153 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
15154 */
15155 survey->noise = rssi - snr;
15156 survey->filled = SURVEY_INFO_NOISE_DBM;
15157 filled = 1;
15158 }
15159 }
15160 }
15161
15162 if (filled)
15163 pAdapter->survey_idx = 1;
15164 else
15165 {
15166 pAdapter->survey_idx = 0;
15167 return -ENONET;
15168 }
15169
15170 return 0;
15171}
15172
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015173static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
15174 struct net_device *dev,
15175 int idx, struct survey_info *survey)
15176{
15177 int ret;
15178
15179 vos_ssr_protect(__func__);
15180 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
15181 vos_ssr_unprotect(__func__);
15182
15183 return ret;
15184}
15185
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015186/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015187 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015188 * this is called when cfg80211 driver resume
15189 * driver updates latest sched_scan scan result(if any) to cfg80211 database
15190 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015191int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015192{
15193 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15194 hdd_adapter_t *pAdapter;
15195 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15196 VOS_STATUS status = VOS_STATUS_SUCCESS;
15197
15198 ENTER();
15199
15200 if ( NULL == pHddCtx )
15201 {
15202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15203 "%s: HddCtx validation failed", __func__);
15204 return 0;
15205 }
15206
15207 if (pHddCtx->isLogpInProgress)
15208 {
15209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15210 "%s: LOGP in Progress. Ignore!!!", __func__);
15211 return 0;
15212 }
15213
Mihir Shete18156292014-03-11 15:38:30 +053015214 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015215 {
15216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15217 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15218 return 0;
15219 }
15220
15221 spin_lock(&pHddCtx->schedScan_lock);
15222 pHddCtx->isWiphySuspended = FALSE;
15223 if (TRUE != pHddCtx->isSchedScanUpdatePending)
15224 {
15225 spin_unlock(&pHddCtx->schedScan_lock);
15226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15227 "%s: Return resume is not due to PNO indication", __func__);
15228 return 0;
15229 }
15230 // Reset flag to avoid updatating cfg80211 data old results again
15231 pHddCtx->isSchedScanUpdatePending = FALSE;
15232 spin_unlock(&pHddCtx->schedScan_lock);
15233
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015234
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015235 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15236
15237 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15238 {
15239 pAdapter = pAdapterNode->pAdapter;
15240 if ( (NULL != pAdapter) &&
15241 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
15242 {
15243 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015244 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15246 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015247 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015248 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015249 {
15250 /* Acquire wakelock to handle the case where APP's tries to
15251 * suspend immediately after updating the scan results. Whis
15252 * results in app's is in suspended state and not able to
15253 * process the connect request to AP
15254 */
15255 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015256 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015257 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015258
15259 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15260 "%s : cfg80211 scan result database updated", __func__);
15261
15262 return 0;
15263
15264 }
15265 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15266 pAdapterNode = pNext;
15267 }
15268
15269 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15270 "%s: Failed to find Adapter", __func__);
15271 return 0;
15272}
15273
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015274int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
15275{
15276 int ret;
15277
15278 vos_ssr_protect(__func__);
15279 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
15280 vos_ssr_unprotect(__func__);
15281
15282 return ret;
15283}
15284
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015285/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015286 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015287 * this is called when cfg80211 driver suspends
15288 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015289int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015290 struct cfg80211_wowlan *wow)
15291{
15292 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15293
15294 ENTER();
15295 if (NULL == pHddCtx)
15296 {
15297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15298 "%s: HddCtx validation failed", __func__);
15299 return 0;
15300 }
15301
15302 pHddCtx->isWiphySuspended = TRUE;
15303
15304 EXIT();
15305
15306 return 0;
15307}
15308
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015309int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
15310 struct cfg80211_wowlan *wow)
15311{
15312 int ret;
15313
15314 vos_ssr_protect(__func__);
15315 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
15316 vos_ssr_unprotect(__func__);
15317
15318 return ret;
15319}
Jeff Johnson295189b2012-06-20 16:38:30 -070015320/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015321static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070015322{
15323 .add_virtual_intf = wlan_hdd_add_virtual_intf,
15324 .del_virtual_intf = wlan_hdd_del_virtual_intf,
15325 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
15326 .change_station = wlan_hdd_change_station,
15327#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
15328 .add_beacon = wlan_hdd_cfg80211_add_beacon,
15329 .del_beacon = wlan_hdd_cfg80211_del_beacon,
15330 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015331#else
15332 .start_ap = wlan_hdd_cfg80211_start_ap,
15333 .change_beacon = wlan_hdd_cfg80211_change_beacon,
15334 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070015335#endif
15336 .change_bss = wlan_hdd_cfg80211_change_bss,
15337 .add_key = wlan_hdd_cfg80211_add_key,
15338 .get_key = wlan_hdd_cfg80211_get_key,
15339 .del_key = wlan_hdd_cfg80211_del_key,
15340 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015341#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070015342 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015343#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015344 .scan = wlan_hdd_cfg80211_scan,
15345 .connect = wlan_hdd_cfg80211_connect,
15346 .disconnect = wlan_hdd_cfg80211_disconnect,
15347 .join_ibss = wlan_hdd_cfg80211_join_ibss,
15348 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
15349 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
15350 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
15351 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070015352 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
15353 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053015354 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070015355#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15356 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
15357 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
15358 .set_txq_params = wlan_hdd_set_txq_params,
15359#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015360 .get_station = wlan_hdd_cfg80211_get_station,
15361 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
15362 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015363 .add_station = wlan_hdd_cfg80211_add_station,
15364#ifdef FEATURE_WLAN_LFR
15365 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
15366 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
15367 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
15368#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015369#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
15370 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
15371#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015372#ifdef FEATURE_WLAN_TDLS
15373 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
15374 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
15375#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015376#ifdef WLAN_FEATURE_GTK_OFFLOAD
15377 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
15378#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015379#ifdef FEATURE_WLAN_SCAN_PNO
15380 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
15381 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
15382#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015383 .resume = wlan_hdd_cfg80211_resume_wlan,
15384 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015385 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070015386#ifdef WLAN_NL80211_TESTMODE
15387 .testmode_cmd = wlan_hdd_cfg80211_testmode,
15388#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015389 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070015390};
15391