blob: 4f986266d9537c4439d2cf9a273f1a0e282d8b8d [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#ifdef FEATURE_WLAN_TDLS
94#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053095#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053096#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080097#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053098#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070099#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700100
101#define g_mode_rates_size (12)
102#define a_mode_rates_size (8)
103#define FREQ_BASE_80211G (2407)
104#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700105#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530106#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700107#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800108 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700109
110#define HDD2GHZCHAN(freq, chan, flag) { \
111 .band = IEEE80211_BAND_2GHZ, \
112 .center_freq = (freq), \
113 .hw_value = (chan),\
114 .flags = (flag), \
115 .max_antenna_gain = 0 ,\
116 .max_power = 30, \
117}
118
119#define HDD5GHZCHAN(freq, chan, flag) { \
120 .band = IEEE80211_BAND_5GHZ, \
121 .center_freq = (freq), \
122 .hw_value = (chan),\
123 .flags = (flag), \
124 .max_antenna_gain = 0 ,\
125 .max_power = 30, \
126}
127
128#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
129{\
130 .bitrate = rate, \
131 .hw_value = rate_id, \
132 .flags = flag, \
133}
134
Lee Hoonkic1262f22013-01-24 21:59:00 -0800135#ifndef WLAN_FEATURE_TDLS_DEBUG
136#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
137#else
138#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
139#endif
140
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530141#ifdef WLAN_FEATURE_VOWIFI_11R
142#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
143#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
144#endif
145
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530146#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530147#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530148
Sunil Duttc69bccb2014-05-26 21:30:20 +0530149#ifdef WLAN_FEATURE_LINK_LAYER_STATS
150/*
151 * Used to allocate the size of 4096 for the link layer stats.
152 * The size of 4096 is considered assuming that all data per
153 * respective event fit with in the limit.Please take a call
154 * on the limit based on the data requirements on link layer
155 * statistics.
156 */
157#define LL_STATS_EVENT_BUF_SIZE 4096
158#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530159#ifdef WLAN_FEATURE_EXTSCAN
160/*
161 * Used to allocate the size of 4096 for the EXTScan NL data.
162 * The size of 4096 is considered assuming that all data per
163 * respective event fit with in the limit.Please take a call
164 * on the limit based on the data requirements.
165 */
166
167#define EXTSCAN_EVENT_BUF_SIZE 4096
168#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
169#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530170
Atul Mittal115287b2014-07-08 13:26:33 +0530171/*EXT TDLS*/
172/*
173 * Used to allocate the size of 4096 for the TDLS.
174 * The size of 4096 is considered assuming that all data per
175 * respective event fit with in the limit.Please take a call
176 * on the limit based on the data requirements on link layer
177 * statistics.
178 */
179#define EXTTDLS_EVENT_BUF_SIZE 4096
180
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530181static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700182{
183 WLAN_CIPHER_SUITE_WEP40,
184 WLAN_CIPHER_SUITE_WEP104,
185 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800186#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700187#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
188 WLAN_CIPHER_SUITE_KRK,
189 WLAN_CIPHER_SUITE_CCMP,
190#else
191 WLAN_CIPHER_SUITE_CCMP,
192#endif
193#ifdef FEATURE_WLAN_WAPI
194 WLAN_CIPHER_SUITE_SMS4,
195#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700196#ifdef WLAN_FEATURE_11W
197 WLAN_CIPHER_SUITE_AES_CMAC,
198#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700199};
200
201static inline int is_broadcast_ether_addr(const u8 *addr)
202{
203 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
204 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
205}
206
207static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530208{
Jeff Johnson295189b2012-06-20 16:38:30 -0700209 HDD2GHZCHAN(2412, 1, 0) ,
210 HDD2GHZCHAN(2417, 2, 0) ,
211 HDD2GHZCHAN(2422, 3, 0) ,
212 HDD2GHZCHAN(2427, 4, 0) ,
213 HDD2GHZCHAN(2432, 5, 0) ,
214 HDD2GHZCHAN(2437, 6, 0) ,
215 HDD2GHZCHAN(2442, 7, 0) ,
216 HDD2GHZCHAN(2447, 8, 0) ,
217 HDD2GHZCHAN(2452, 9, 0) ,
218 HDD2GHZCHAN(2457, 10, 0) ,
219 HDD2GHZCHAN(2462, 11, 0) ,
220 HDD2GHZCHAN(2467, 12, 0) ,
221 HDD2GHZCHAN(2472, 13, 0) ,
222 HDD2GHZCHAN(2484, 14, 0) ,
223};
224
Jeff Johnson295189b2012-06-20 16:38:30 -0700225static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
226{
227 HDD2GHZCHAN(2412, 1, 0) ,
228 HDD2GHZCHAN(2437, 6, 0) ,
229 HDD2GHZCHAN(2462, 11, 0) ,
230};
Jeff Johnson295189b2012-06-20 16:38:30 -0700231
232static struct ieee80211_channel hdd_channels_5_GHZ[] =
233{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700234 HDD5GHZCHAN(4920, 240, 0) ,
235 HDD5GHZCHAN(4940, 244, 0) ,
236 HDD5GHZCHAN(4960, 248, 0) ,
237 HDD5GHZCHAN(4980, 252, 0) ,
238 HDD5GHZCHAN(5040, 208, 0) ,
239 HDD5GHZCHAN(5060, 212, 0) ,
240 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700241 HDD5GHZCHAN(5180, 36, 0) ,
242 HDD5GHZCHAN(5200, 40, 0) ,
243 HDD5GHZCHAN(5220, 44, 0) ,
244 HDD5GHZCHAN(5240, 48, 0) ,
245 HDD5GHZCHAN(5260, 52, 0) ,
246 HDD5GHZCHAN(5280, 56, 0) ,
247 HDD5GHZCHAN(5300, 60, 0) ,
248 HDD5GHZCHAN(5320, 64, 0) ,
249 HDD5GHZCHAN(5500,100, 0) ,
250 HDD5GHZCHAN(5520,104, 0) ,
251 HDD5GHZCHAN(5540,108, 0) ,
252 HDD5GHZCHAN(5560,112, 0) ,
253 HDD5GHZCHAN(5580,116, 0) ,
254 HDD5GHZCHAN(5600,120, 0) ,
255 HDD5GHZCHAN(5620,124, 0) ,
256 HDD5GHZCHAN(5640,128, 0) ,
257 HDD5GHZCHAN(5660,132, 0) ,
258 HDD5GHZCHAN(5680,136, 0) ,
259 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800260#ifdef FEATURE_WLAN_CH144
261 HDD5GHZCHAN(5720,144, 0) ,
262#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700263 HDD5GHZCHAN(5745,149, 0) ,
264 HDD5GHZCHAN(5765,153, 0) ,
265 HDD5GHZCHAN(5785,157, 0) ,
266 HDD5GHZCHAN(5805,161, 0) ,
267 HDD5GHZCHAN(5825,165, 0) ,
268};
269
270static struct ieee80211_rate g_mode_rates[] =
271{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530272 HDD_G_MODE_RATETAB(10, 0x1, 0),
273 HDD_G_MODE_RATETAB(20, 0x2, 0),
274 HDD_G_MODE_RATETAB(55, 0x4, 0),
275 HDD_G_MODE_RATETAB(110, 0x8, 0),
276 HDD_G_MODE_RATETAB(60, 0x10, 0),
277 HDD_G_MODE_RATETAB(90, 0x20, 0),
278 HDD_G_MODE_RATETAB(120, 0x40, 0),
279 HDD_G_MODE_RATETAB(180, 0x80, 0),
280 HDD_G_MODE_RATETAB(240, 0x100, 0),
281 HDD_G_MODE_RATETAB(360, 0x200, 0),
282 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700283 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530284};
Jeff Johnson295189b2012-06-20 16:38:30 -0700285
286static struct ieee80211_rate a_mode_rates[] =
287{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530288 HDD_G_MODE_RATETAB(60, 0x10, 0),
289 HDD_G_MODE_RATETAB(90, 0x20, 0),
290 HDD_G_MODE_RATETAB(120, 0x40, 0),
291 HDD_G_MODE_RATETAB(180, 0x80, 0),
292 HDD_G_MODE_RATETAB(240, 0x100, 0),
293 HDD_G_MODE_RATETAB(360, 0x200, 0),
294 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700295 HDD_G_MODE_RATETAB(540, 0x800, 0),
296};
297
298static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
299{
300 .channels = hdd_channels_2_4_GHZ,
301 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
302 .band = IEEE80211_BAND_2GHZ,
303 .bitrates = g_mode_rates,
304 .n_bitrates = g_mode_rates_size,
305 .ht_cap.ht_supported = 1,
306 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
307 | IEEE80211_HT_CAP_GRN_FLD
308 | IEEE80211_HT_CAP_DSSSCCK40
309 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
310 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
311 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
312 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
313 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
314 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
315};
316
Jeff Johnson295189b2012-06-20 16:38:30 -0700317static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
318{
319 .channels = hdd_social_channels_2_4_GHZ,
320 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
321 .band = IEEE80211_BAND_2GHZ,
322 .bitrates = g_mode_rates,
323 .n_bitrates = g_mode_rates_size,
324 .ht_cap.ht_supported = 1,
325 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
326 | IEEE80211_HT_CAP_GRN_FLD
327 | IEEE80211_HT_CAP_DSSSCCK40
328 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
329 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
330 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
331 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
332 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
333 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
334};
Jeff Johnson295189b2012-06-20 16:38:30 -0700335
336static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
337{
338 .channels = hdd_channels_5_GHZ,
339 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
340 .band = IEEE80211_BAND_5GHZ,
341 .bitrates = a_mode_rates,
342 .n_bitrates = a_mode_rates_size,
343 .ht_cap.ht_supported = 1,
344 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
345 | IEEE80211_HT_CAP_GRN_FLD
346 | IEEE80211_HT_CAP_DSSSCCK40
347 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
348 | IEEE80211_HT_CAP_SGI_40
349 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
350 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
351 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
352 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
353 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
354 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
355};
356
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530357/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700358 TX/RX direction for each kind of interface */
359static const struct ieee80211_txrx_stypes
360wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
361 [NL80211_IFTYPE_STATION] = {
362 .tx = 0xffff,
363 .rx = BIT(SIR_MAC_MGMT_ACTION) |
364 BIT(SIR_MAC_MGMT_PROBE_REQ),
365 },
366 [NL80211_IFTYPE_AP] = {
367 .tx = 0xffff,
368 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
369 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
370 BIT(SIR_MAC_MGMT_PROBE_REQ) |
371 BIT(SIR_MAC_MGMT_DISASSOC) |
372 BIT(SIR_MAC_MGMT_AUTH) |
373 BIT(SIR_MAC_MGMT_DEAUTH) |
374 BIT(SIR_MAC_MGMT_ACTION),
375 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700376 [NL80211_IFTYPE_ADHOC] = {
377 .tx = 0xffff,
378 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
379 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
380 BIT(SIR_MAC_MGMT_PROBE_REQ) |
381 BIT(SIR_MAC_MGMT_DISASSOC) |
382 BIT(SIR_MAC_MGMT_AUTH) |
383 BIT(SIR_MAC_MGMT_DEAUTH) |
384 BIT(SIR_MAC_MGMT_ACTION),
385 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700386 [NL80211_IFTYPE_P2P_CLIENT] = {
387 .tx = 0xffff,
388 .rx = BIT(SIR_MAC_MGMT_ACTION) |
389 BIT(SIR_MAC_MGMT_PROBE_REQ),
390 },
391 [NL80211_IFTYPE_P2P_GO] = {
392 /* This is also same as for SoftAP */
393 .tx = 0xffff,
394 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
395 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
396 BIT(SIR_MAC_MGMT_PROBE_REQ) |
397 BIT(SIR_MAC_MGMT_DISASSOC) |
398 BIT(SIR_MAC_MGMT_AUTH) |
399 BIT(SIR_MAC_MGMT_DEAUTH) |
400 BIT(SIR_MAC_MGMT_ACTION),
401 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700402};
403
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800404#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800405static const struct ieee80211_iface_limit
406wlan_hdd_iface_limit[] = {
407 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800408 /* max = 3 ; Our driver create two interfaces during driver init
409 * wlan0 and p2p0 interfaces. p2p0 is considered as station
410 * interface until a group is formed. In JB architecture, once the
411 * group is formed, interface type of p2p0 is changed to P2P GO or
412 * Client.
413 * When supplicant remove the group, it first issue a set interface
414 * cmd to change the mode back to Station. In JB this works fine as
415 * we advertize two station type interface during driver init.
416 * Some vendors create separate interface for P2P GO/Client,
417 * after group formation(Third one). But while group remove
418 * supplicant first tries to change the mode(3rd interface) to STATION
419 * But as we advertized only two sta type interfaces nl80211 was
420 * returning error for the third one which was leading to failure in
421 * delete interface. Ideally while removing the group, supplicant
422 * should not try to change the 3rd interface mode to Station type.
423 * Till we get a fix in wpa_supplicant, we advertize max STA
424 * interface type to 3
425 */
426 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800427 .types = BIT(NL80211_IFTYPE_STATION),
428 },
429 {
430 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700431 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800432 },
433 {
434 .max = 1,
435 .types = BIT(NL80211_IFTYPE_P2P_GO) |
436 BIT(NL80211_IFTYPE_P2P_CLIENT),
437 },
438};
439
440/* By default, only single channel concurrency is allowed */
441static struct ieee80211_iface_combination
442wlan_hdd_iface_combination = {
443 .limits = wlan_hdd_iface_limit,
444 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800445 /*
446 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
447 * and p2p0 interfaces during driver init
448 * Some vendors create separate interface for P2P operations.
449 * wlan0: STA interface
450 * p2p0: P2P Device interface, action frames goes
451 * through this interface.
452 * p2p-xx: P2P interface, After GO negotiation this interface is
453 * created for p2p operations(GO/CLIENT interface).
454 */
455 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800456 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
457 .beacon_int_infra_match = false,
458};
459#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800460
Jeff Johnson295189b2012-06-20 16:38:30 -0700461static struct cfg80211_ops wlan_hdd_cfg80211_ops;
462
463/* Data rate 100KBPS based on IE Index */
464struct index_data_rate_type
465{
466 v_U8_t beacon_rate_index;
467 v_U16_t supported_rate[4];
468};
469
470/* 11B, 11G Rate table include Basic rate and Extended rate
471 The IDX field is the rate index
472 The HI field is the rate when RSSI is strong or being ignored
473 (in this case we report actual rate)
474 The MID field is the rate when RSSI is moderate
475 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
476 The LO field is the rate when RSSI is low
477 (in this case we don't report rates, actual current rate used)
478 */
479static const struct
480{
481 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700482 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700483} supported_data_rate[] =
484{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700485/* IDX HI HM LM LO (RSSI-based index */
486 {2, { 10, 10, 10, 0}},
487 {4, { 20, 20, 10, 0}},
488 {11, { 55, 20, 10, 0}},
489 {12, { 60, 55, 20, 0}},
490 {18, { 90, 55, 20, 0}},
491 {22, {110, 55, 20, 0}},
492 {24, {120, 90, 60, 0}},
493 {36, {180, 120, 60, 0}},
494 {44, {220, 180, 60, 0}},
495 {48, {240, 180, 90, 0}},
496 {66, {330, 180, 90, 0}},
497 {72, {360, 240, 90, 0}},
498 {96, {480, 240, 120, 0}},
499 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700500};
501
502/* MCS Based rate table */
503static struct index_data_rate_type supported_mcs_rate[] =
504{
505/* MCS L20 L40 S20 S40 */
506 {0, {65, 135, 72, 150}},
507 {1, {130, 270, 144, 300}},
508 {2, {195, 405, 217, 450}},
509 {3, {260, 540, 289, 600}},
510 {4, {390, 810, 433, 900}},
511 {5, {520, 1080, 578, 1200}},
512 {6, {585, 1215, 650, 1350}},
513 {7, {650, 1350, 722, 1500}}
514};
515
Leo Chang6f8870f2013-03-26 18:11:36 -0700516#ifdef WLAN_FEATURE_11AC
517
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530518#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700519
520struct index_vht_data_rate_type
521{
522 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530523 v_U16_t supported_VHT80_rate[2];
524 v_U16_t supported_VHT40_rate[2];
525 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700526};
527
528typedef enum
529{
530 DATA_RATE_11AC_MAX_MCS_7,
531 DATA_RATE_11AC_MAX_MCS_8,
532 DATA_RATE_11AC_MAX_MCS_9,
533 DATA_RATE_11AC_MAX_MCS_NA
534} eDataRate11ACMaxMcs;
535
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530536/* SSID broadcast type */
537typedef enum eSSIDBcastType
538{
539 eBCAST_UNKNOWN = 0,
540 eBCAST_NORMAL = 1,
541 eBCAST_HIDDEN = 2,
542} tSSIDBcastType;
543
Leo Chang6f8870f2013-03-26 18:11:36 -0700544/* MCS Based VHT rate table */
545static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
546{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530547/* MCS L80 S80 L40 S40 L20 S40*/
548 {0, {293, 325}, {135, 150}, {65, 72}},
549 {1, {585, 650}, {270, 300}, {130, 144}},
550 {2, {878, 975}, {405, 450}, {195, 217}},
551 {3, {1170, 1300}, {540, 600}, {260, 289}},
552 {4, {1755, 1950}, {810, 900}, {390, 433}},
553 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
554 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
555 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
556 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
557 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700558};
559#endif /* WLAN_FEATURE_11AC */
560
c_hpothu79aab322014-07-14 21:11:01 +0530561/*array index points to MCS and array value points respective rssi*/
562static int rssiMcsTbl[][10] =
563{
564/*MCS 0 1 2 3 4 5 6 7 8 9*/
565 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
566 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
567 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
568};
569
Jeff Johnson295189b2012-06-20 16:38:30 -0700570extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530571#ifdef FEATURE_WLAN_SCAN_PNO
572static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
573#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700574
Leo Chang9056f462013-08-01 19:21:11 -0700575#ifdef WLAN_NL80211_TESTMODE
576enum wlan_hdd_tm_attr
577{
578 WLAN_HDD_TM_ATTR_INVALID = 0,
579 WLAN_HDD_TM_ATTR_CMD = 1,
580 WLAN_HDD_TM_ATTR_DATA = 2,
581 WLAN_HDD_TM_ATTR_TYPE = 3,
582 /* keep last */
583 WLAN_HDD_TM_ATTR_AFTER_LAST,
584 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
585};
586
587enum wlan_hdd_tm_cmd
588{
589 WLAN_HDD_TM_CMD_WLAN_HB = 1,
590};
591
592#define WLAN_HDD_TM_DATA_MAX_LEN 5000
593
594static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
595{
596 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
597 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
598 .len = WLAN_HDD_TM_DATA_MAX_LEN },
599};
600#endif /* WLAN_NL80211_TESTMODE */
601
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800602#ifdef FEATURE_WLAN_CH_AVOID
603/*
604 * FUNCTION: wlan_hdd_send_avoid_freq_event
605 * This is called when wlan driver needs to send vendor specific
606 * avoid frequency range event to userspace
607 */
608int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
609 tHddAvoidFreqList *pAvoidFreqList)
610{
611 struct sk_buff *vendor_event;
612
613 ENTER();
614
615 if (!pHddCtx)
616 {
617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
618 "%s: HDD context is null", __func__);
619 return -1;
620 }
621
622 if (!pAvoidFreqList)
623 {
624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
625 "%s: pAvoidFreqList is null", __func__);
626 return -1;
627 }
628
629 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
630 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530631 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800632 GFP_KERNEL);
633 if (!vendor_event)
634 {
635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
636 "%s: cfg80211_vendor_event_alloc failed", __func__);
637 return -1;
638 }
639
640 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
641 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
642
643 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
644
645 EXIT();
646 return 0;
647}
648#endif /* FEATURE_WLAN_CH_AVOID */
649
Sunil Duttc69bccb2014-05-26 21:30:20 +0530650#ifdef WLAN_FEATURE_LINK_LAYER_STATS
651
652static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
653 struct sk_buff *vendor_event)
654{
655 if (nla_put_u8(vendor_event,
656 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
657 stats->rate.preamble) ||
658 nla_put_u8(vendor_event,
659 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
660 stats->rate.nss) ||
661 nla_put_u8(vendor_event,
662 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
663 stats->rate.bw) ||
664 nla_put_u8(vendor_event,
665 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
666 stats->rate.rateMcsIdx) ||
667 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
668 stats->rate.bitrate ) ||
669 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
670 stats->txMpdu ) ||
671 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
672 stats->rxMpdu ) ||
673 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
674 stats->mpduLost ) ||
675 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
676 stats->retries) ||
677 nla_put_u32(vendor_event,
678 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
679 stats->retriesShort ) ||
680 nla_put_u32(vendor_event,
681 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
682 stats->retriesLong))
683 {
684 hddLog(VOS_TRACE_LEVEL_ERROR,
685 FL("QCA_WLAN_VENDOR_ATTR put fail"));
686 return FALSE;
687 }
688 return TRUE;
689}
690
691static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
692 struct sk_buff *vendor_event)
693{
694 u32 i = 0;
695 struct nlattr *rateInfo;
696 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
697 stats->type) ||
698 nla_put(vendor_event,
699 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
700 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
701 nla_put_u32(vendor_event,
702 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
703 stats->capabilities) ||
704 nla_put_u32(vendor_event,
705 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
706 stats->numRate))
707 {
708 hddLog(VOS_TRACE_LEVEL_ERROR,
709 FL("QCA_WLAN_VENDOR_ATTR put fail"));
710 goto error;
711 }
712
713 rateInfo = nla_nest_start(vendor_event,
714 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530715 if(!rateInfo)
716 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530717 for (i = 0; i < stats->numRate; i++)
718 {
719 struct nlattr *rates;
720 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
721 stats->rateStats +
722 (i * sizeof(tSirWifiRateStat)));
723 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530724 if(!rates)
725 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530726
727 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
728 {
729 hddLog(VOS_TRACE_LEVEL_ERROR,
730 FL("QCA_WLAN_VENDOR_ATTR put fail"));
731 return FALSE;
732 }
733 nla_nest_end(vendor_event, rates);
734 }
735 nla_nest_end(vendor_event, rateInfo);
736
737 return TRUE;
738error:
739 return FALSE;
740}
741
742static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
743 struct sk_buff *vendor_event)
744{
745 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
746 stats->ac ) ||
747 nla_put_u32(vendor_event,
748 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
749 stats->txMpdu ) ||
750 nla_put_u32(vendor_event,
751 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
752 stats->rxMpdu ) ||
753 nla_put_u32(vendor_event,
754 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
755 stats->txMcast ) ||
756 nla_put_u32(vendor_event,
757 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
758 stats->rxMcast ) ||
759 nla_put_u32(vendor_event,
760 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
761 stats->rxAmpdu ) ||
762 nla_put_u32(vendor_event,
763 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
764 stats->txAmpdu ) ||
765 nla_put_u32(vendor_event,
766 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
767 stats->mpduLost )||
768 nla_put_u32(vendor_event,
769 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
770 stats->retries ) ||
771 nla_put_u32(vendor_event,
772 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
773 stats->retriesShort ) ||
774 nla_put_u32(vendor_event,
775 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
776 stats->retriesLong ) ||
777 nla_put_u32(vendor_event,
778 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
779 stats->contentionTimeMin ) ||
780 nla_put_u32(vendor_event,
781 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
782 stats->contentionTimeMax ) ||
783 nla_put_u32(vendor_event,
784 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
785 stats->contentionTimeAvg ) ||
786 nla_put_u32(vendor_event,
787 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
788 stats->contentionNumSamples ))
789 {
790 hddLog(VOS_TRACE_LEVEL_ERROR,
791 FL("QCA_WLAN_VENDOR_ATTR put fail") );
792 return FALSE;
793 }
794 return TRUE;
795}
796
797static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
798 struct sk_buff *vendor_event)
799{
Dino Myclec8f3f332014-07-21 16:48:27 +0530800 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530801 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
802 nla_put(vendor_event,
803 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
804 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
805 nla_put_u32(vendor_event,
806 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
807 stats->state ) ||
808 nla_put_u32(vendor_event,
809 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
810 stats->roaming ) ||
811 nla_put_u32(vendor_event,
812 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
813 stats->capabilities ) ||
814 nla_put(vendor_event,
815 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
816 strlen(stats->ssid), stats->ssid) ||
817 nla_put(vendor_event,
818 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
819 WNI_CFG_BSSID_LEN, stats->bssid) ||
820 nla_put(vendor_event,
821 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
822 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
823 nla_put(vendor_event,
824 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
825 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
826 )
827 {
828 hddLog(VOS_TRACE_LEVEL_ERROR,
829 FL("QCA_WLAN_VENDOR_ATTR put fail") );
830 return FALSE;
831 }
832 return TRUE;
833}
834
Dino Mycle3b9536d2014-07-09 22:05:24 +0530835static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
836 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530837 struct sk_buff *vendor_event)
838{
839 int i = 0;
840 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530841 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
842 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530843 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530844
Sunil Duttc69bccb2014-05-26 21:30:20 +0530845 if (FALSE == put_wifi_interface_info(
846 &pWifiIfaceStat->info,
847 vendor_event))
848 {
849 hddLog(VOS_TRACE_LEVEL_ERROR,
850 FL("QCA_WLAN_VENDOR_ATTR put fail") );
851 return FALSE;
852
853 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530854 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
855 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
856 if (NULL == pWifiIfaceStatTL)
857 {
858 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
859 return FALSE;
860 }
861
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530862 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
863 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
864 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
865 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
866
867 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
868 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
869 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
870 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530871
872 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
873 {
874 if (VOS_STATUS_SUCCESS ==
875 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
876 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
877 {
878 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
879 * obtained from TL structure
880 */
881
882 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
883 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530884 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
885
Srinivas Dasari98947432014-11-07 19:41:24 +0530886 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
887 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
888 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
889 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
890 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
891 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
892 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
893 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530894
Srinivas Dasari98947432014-11-07 19:41:24 +0530895 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
896 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
897 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
898 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
899 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
900 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
901 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
902 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530903
Srinivas Dasari98947432014-11-07 19:41:24 +0530904 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
905 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
906 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
907 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
908 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
909 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
910 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
911 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530912 }
913 else
914 {
915 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
916 }
917
Dino Mycle3b9536d2014-07-09 22:05:24 +0530918 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
919 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
920 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
921 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
922 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
923 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
924 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
925 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
926 }
927 else
928 {
929 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
930 }
931
932
Sunil Duttc69bccb2014-05-26 21:30:20 +0530933
934 if (nla_put_u32(vendor_event,
935 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
936 pWifiIfaceStat->beaconRx) ||
937 nla_put_u32(vendor_event,
938 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
939 pWifiIfaceStat->mgmtRx) ||
940 nla_put_u32(vendor_event,
941 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
942 pWifiIfaceStat->mgmtActionRx) ||
943 nla_put_u32(vendor_event,
944 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
945 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530946 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530947 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
948 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530949 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530950 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
951 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530952 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530953 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
954 pWifiIfaceStat->rssiAck))
955 {
956 hddLog(VOS_TRACE_LEVEL_ERROR,
957 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530958 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530959 return FALSE;
960 }
961
962 wmmInfo = nla_nest_start(vendor_event,
963 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530964 if(!wmmInfo)
965 {
966 vos_mem_free(pWifiIfaceStatTL);
967 return FALSE;
968 }
Sunil Duttc69bccb2014-05-26 21:30:20 +0530969 for (i = 0; i < WIFI_AC_MAX; i++)
970 {
971 struct nlattr *wmmStats;
972 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530973 if(!wmmStats)
974 {
975 vos_mem_free(pWifiIfaceStatTL);
976 return FALSE;
977 }
Sunil Duttc69bccb2014-05-26 21:30:20 +0530978 if (FALSE == put_wifi_wmm_ac_stat(
979 &pWifiIfaceStat->AccessclassStats[i],
980 vendor_event))
981 {
982 hddLog(VOS_TRACE_LEVEL_ERROR,
983 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530984 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530985 return FALSE;
986 }
987
988 nla_nest_end(vendor_event, wmmStats);
989 }
990 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +0530991 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530992 return TRUE;
993}
994
995static tSirWifiInterfaceMode
996 hdd_map_device_to_ll_iface_mode ( int deviceMode )
997{
998 switch (deviceMode)
999 {
1000 case WLAN_HDD_INFRA_STATION:
1001 return WIFI_INTERFACE_STA;
1002 case WLAN_HDD_SOFTAP:
1003 return WIFI_INTERFACE_SOFTAP;
1004 case WLAN_HDD_P2P_CLIENT:
1005 return WIFI_INTERFACE_P2P_CLIENT;
1006 case WLAN_HDD_P2P_GO:
1007 return WIFI_INTERFACE_P2P_GO;
1008 case WLAN_HDD_IBSS:
1009 return WIFI_INTERFACE_IBSS;
1010 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301011 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301012 }
1013}
1014
1015static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1016 tpSirWifiInterfaceInfo pInfo)
1017{
1018 v_U8_t *staMac = NULL;
1019 hdd_station_ctx_t *pHddStaCtx;
1020 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1021 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1022
1023 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1024
1025 vos_mem_copy(pInfo->macAddr,
1026 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1027
1028 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1029 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1030 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1031 {
1032 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1033 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1034 {
1035 pInfo->state = WIFI_DISCONNECTED;
1036 }
1037 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1038 {
1039 hddLog(VOS_TRACE_LEVEL_ERROR,
1040 "%s: Session ID %d, Connection is in progress", __func__,
1041 pAdapter->sessionId);
1042 pInfo->state = WIFI_ASSOCIATING;
1043 }
1044 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1045 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1046 {
1047 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1048 hddLog(VOS_TRACE_LEVEL_ERROR,
1049 "%s: client " MAC_ADDRESS_STR
1050 " is in the middle of WPS/EAPOL exchange.", __func__,
1051 MAC_ADDR_ARRAY(staMac));
1052 pInfo->state = WIFI_AUTHENTICATING;
1053 }
1054 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1055 {
1056 pInfo->state = WIFI_ASSOCIATED;
1057 vos_mem_copy(pInfo->bssid,
1058 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1059 vos_mem_copy(pInfo->ssid,
1060 pHddStaCtx->conn_info.SSID.SSID.ssId,
1061 pHddStaCtx->conn_info.SSID.SSID.length);
1062 //NULL Terminate the string.
1063 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1064 }
1065 }
1066 vos_mem_copy(pInfo->countryStr,
1067 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1068
1069 vos_mem_copy(pInfo->apCountryStr,
1070 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1071
1072 return TRUE;
1073}
1074
1075/*
1076 * hdd_link_layer_process_peer_stats () - This function is called after
1077 * receiving Link Layer Peer statistics from FW.This function converts
1078 * the firmware data to the NL data and sends the same to the kernel/upper
1079 * layers.
1080 */
1081static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1082 v_VOID_t *pData)
1083{
1084 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1085 tpSirWifiRateStat pWifiRateStat;
1086 tpSirWifiPeerStat pWifiPeerStat;
1087 tpSirWifiPeerInfo pWifiPeerInfo;
1088 struct nlattr *peerInfo;
1089 struct sk_buff *vendor_event;
1090 int status, i;
1091
1092 status = wlan_hdd_validate_context(pHddCtx);
1093 if (0 != status)
1094 {
1095 hddLog(VOS_TRACE_LEVEL_ERROR,
1096 FL("HDD context is not valid") );
1097 return;
1098 }
1099
1100 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1101
1102 hddLog(VOS_TRACE_LEVEL_INFO,
1103 "LL_STATS_PEER_ALL : numPeers %u",
1104 pWifiPeerStat->numPeers);
1105 {
1106 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1107 {
1108 pWifiPeerInfo = (tpSirWifiPeerInfo)
1109 ((uint8 *)pWifiPeerStat->peerInfo +
1110 ( i * sizeof(tSirWifiPeerInfo)));
1111
Dasari Srinivas1be0c4e2014-10-19 13:03:41 +05301112 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) {
1113 pWifiPeerInfo->type = WIFI_PEER_AP;
1114 }
1115 if (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) {
1116 pWifiPeerInfo->type = WIFI_PEER_P2P_GO;
1117 }
1118
Sunil Duttc69bccb2014-05-26 21:30:20 +05301119 hddLog(VOS_TRACE_LEVEL_INFO,
1120 " %d) LL_STATS Channel Stats "
1121 " Peer Type %u "
1122 " peerMacAddress %pM "
1123 " capabilities 0x%x "
1124 " numRate %u ",
1125 i,
1126 pWifiPeerInfo->type,
1127 pWifiPeerInfo->peerMacAddress,
1128 pWifiPeerInfo->capabilities,
1129 pWifiPeerInfo->numRate);
1130 {
1131 int j;
1132 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1133 {
1134 pWifiRateStat = (tpSirWifiRateStat)
1135 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1136 ( j * sizeof(tSirWifiRateStat)));
1137
1138 hddLog(VOS_TRACE_LEVEL_INFO,
1139 " peer Rate Stats "
1140 " preamble %u "
1141 " nss %u "
1142 " bw %u "
1143 " rateMcsIdx %u "
1144 " reserved %u "
1145 " bitrate %u "
1146 " txMpdu %u "
1147 " rxMpdu %u "
1148 " mpduLost %u "
1149 " retries %u "
1150 " retriesShort %u "
1151 " retriesLong %u",
1152 pWifiRateStat->rate.preamble,
1153 pWifiRateStat->rate.nss,
1154 pWifiRateStat->rate.bw,
1155 pWifiRateStat->rate.rateMcsIdx,
1156 pWifiRateStat->rate.reserved,
1157 pWifiRateStat->rate.bitrate,
1158 pWifiRateStat->txMpdu,
1159 pWifiRateStat->rxMpdu,
1160 pWifiRateStat->mpduLost,
1161 pWifiRateStat->retries,
1162 pWifiRateStat->retriesShort,
1163 pWifiRateStat->retriesLong);
1164 }
1165 }
1166 }
1167 }
1168
1169 /*
1170 * Allocate a size of 4096 for the peer stats comprising
1171 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1172 * sizeof (tSirWifiRateStat).Each field is put with an
1173 * NL attribute.The size of 4096 is considered assuming
1174 * that number of rates shall not exceed beyond 50 with
1175 * the sizeof (tSirWifiRateStat) being 32.
1176 */
1177 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1178 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1179 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1180 GFP_KERNEL);
1181 if (!vendor_event)
1182 {
1183 hddLog(VOS_TRACE_LEVEL_ERROR,
1184 "%s: cfg80211_vendor_event_alloc failed",
1185 __func__);
1186 return;
1187 }
1188 if (nla_put_u32(vendor_event,
1189 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1190 pWifiPeerStat->numPeers))
1191 {
1192 hddLog(VOS_TRACE_LEVEL_ERROR,
1193 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1194 kfree_skb(vendor_event);
1195 return;
1196 }
1197
1198 peerInfo = nla_nest_start(vendor_event,
1199 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301200 if(!peerInfo)
1201 {
1202 hddLog(VOS_TRACE_LEVEL_ERROR,
1203 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1204 __func__);
1205 kfree_skb(vendor_event);
1206 return;
1207 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301208
1209 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1210 pWifiPeerStat->peerInfo);
1211
1212 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1213 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301214 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301215 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301216
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301217 if(!peers)
1218 {
1219 hddLog(VOS_TRACE_LEVEL_ERROR,
1220 "%s: peer stats put fail",
1221 __func__);
1222 kfree_skb(vendor_event);
1223 return;
1224 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301225 if (FALSE == put_wifi_peer_info(
1226 pWifiPeerInfo, vendor_event))
1227 {
1228 hddLog(VOS_TRACE_LEVEL_ERROR,
1229 "%s: put_wifi_peer_info put fail", __func__);
1230 kfree_skb(vendor_event);
1231 return;
1232 }
1233
1234 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1235 pWifiPeerStat->peerInfo +
1236 (i * sizeof(tSirWifiPeerInfo)) +
1237 (numRate * sizeof (tSirWifiRateStat)));
1238 nla_nest_end(vendor_event, peers);
1239 }
1240 nla_nest_end(vendor_event, peerInfo);
1241 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1242}
1243
1244/*
1245 * hdd_link_layer_process_iface_stats () - This function is called after
1246 * receiving Link Layer Interface statistics from FW.This function converts
1247 * the firmware data to the NL data and sends the same to the kernel/upper
1248 * layers.
1249 */
1250static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1251 v_VOID_t *pData)
1252{
1253 tpSirWifiIfaceStat pWifiIfaceStat;
1254 struct sk_buff *vendor_event;
1255 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1256 int status;
1257
1258 status = wlan_hdd_validate_context(pHddCtx);
1259 if (0 != status)
1260 {
1261 hddLog(VOS_TRACE_LEVEL_ERROR,
1262 FL("HDD context is not valid") );
1263 return;
1264 }
1265 /*
1266 * Allocate a size of 4096 for the interface stats comprising
1267 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1268 * assuming that all these fit with in the limit.Please take
1269 * a call on the limit based on the data requirements on
1270 * interface statistics.
1271 */
1272 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1273 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1274 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1275 GFP_KERNEL);
1276 if (!vendor_event)
1277 {
1278 hddLog(VOS_TRACE_LEVEL_ERROR,
1279 FL("cfg80211_vendor_event_alloc failed") );
1280 return;
1281 }
1282
1283 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1284
Dino Mycle3b9536d2014-07-09 22:05:24 +05301285
1286 if (FALSE == hdd_get_interface_info( pAdapter,
1287 &pWifiIfaceStat->info))
1288 {
1289 hddLog(VOS_TRACE_LEVEL_ERROR,
1290 FL("hdd_get_interface_info get fail") );
1291 kfree_skb(vendor_event);
1292 return;
1293 }
1294
1295 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1296 vendor_event))
1297 {
1298 hddLog(VOS_TRACE_LEVEL_ERROR,
1299 FL("put_wifi_iface_stats fail") );
1300 kfree_skb(vendor_event);
1301 return;
1302 }
1303
Sunil Duttc69bccb2014-05-26 21:30:20 +05301304 hddLog(VOS_TRACE_LEVEL_INFO,
1305 "WMI_LINK_STATS_IFACE Data");
1306
1307 hddLog(VOS_TRACE_LEVEL_INFO,
1308 "LL_STATS_IFACE: "
1309 " Mode %u "
1310 " MAC %pM "
1311 " State %u "
1312 " Roaming %u "
1313 " capabilities 0x%x "
1314 " SSID %s "
1315 " BSSID %pM",
1316 pWifiIfaceStat->info.mode,
1317 pWifiIfaceStat->info.macAddr,
1318 pWifiIfaceStat->info.state,
1319 pWifiIfaceStat->info.roaming,
1320 pWifiIfaceStat->info.capabilities,
1321 pWifiIfaceStat->info.ssid,
1322 pWifiIfaceStat->info.bssid);
1323
1324 hddLog(VOS_TRACE_LEVEL_INFO,
1325 " AP country str: %c%c%c",
1326 pWifiIfaceStat->info.apCountryStr[0],
1327 pWifiIfaceStat->info.apCountryStr[1],
1328 pWifiIfaceStat->info.apCountryStr[2]);
1329
1330
1331 hddLog(VOS_TRACE_LEVEL_INFO,
1332 " Country Str Association: %c%c%c",
1333 pWifiIfaceStat->info.countryStr[0],
1334 pWifiIfaceStat->info.countryStr[1],
1335 pWifiIfaceStat->info.countryStr[2]);
1336
1337 hddLog(VOS_TRACE_LEVEL_INFO,
1338 " beaconRx %u "
1339 " mgmtRx %u "
1340 " mgmtActionRx %u "
1341 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301342 " rssiMgmt %d "
1343 " rssiData %d "
1344 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301345 pWifiIfaceStat->beaconRx,
1346 pWifiIfaceStat->mgmtRx,
1347 pWifiIfaceStat->mgmtActionRx,
1348 pWifiIfaceStat->mgmtActionTx,
1349 pWifiIfaceStat->rssiMgmt,
1350 pWifiIfaceStat->rssiData,
1351 pWifiIfaceStat->rssiAck );
1352
1353
1354 {
1355 int i;
1356 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1357 {
1358 hddLog(VOS_TRACE_LEVEL_INFO,
1359
1360 " %d) LL_STATS IFACE: "
1361 " ac: %u txMpdu: %u "
1362 " rxMpdu: %u txMcast: %u "
1363 " rxMcast: %u rxAmpdu: %u "
1364 " txAmpdu: %u mpduLost: %u "
1365 " retries: %u retriesShort: %u "
1366 " retriesLong: %u contentionTimeMin: %u "
1367 " contentionTimeMax: %u contentionTimeAvg: %u "
1368 " contentionNumSamples: %u",
1369 i,
1370 pWifiIfaceStat->AccessclassStats[i].ac,
1371 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1372 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1373 pWifiIfaceStat->AccessclassStats[i].txMcast,
1374 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1375 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1376 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1377 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1378 pWifiIfaceStat->AccessclassStats[i].retries,
1379 pWifiIfaceStat->
1380 AccessclassStats[i].retriesShort,
1381 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1382 pWifiIfaceStat->
1383 AccessclassStats[i].contentionTimeMin,
1384 pWifiIfaceStat->
1385 AccessclassStats[i].contentionTimeMax,
1386 pWifiIfaceStat->
1387 AccessclassStats[i].contentionTimeAvg,
1388 pWifiIfaceStat->
1389 AccessclassStats[i].contentionNumSamples);
1390
1391 }
1392 }
1393
Sunil Duttc69bccb2014-05-26 21:30:20 +05301394 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1395}
1396
1397/*
1398 * hdd_link_layer_process_radio_stats () - This function is called after
1399 * receiving Link Layer Radio statistics from FW.This function converts
1400 * the firmware data to the NL data and sends the same to the kernel/upper
1401 * layers.
1402 */
1403static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1404 v_VOID_t *pData)
1405{
1406 int status, i;
1407 tpSirWifiRadioStat pWifiRadioStat;
1408 tpSirWifiChannelStats pWifiChannelStats;
1409 struct sk_buff *vendor_event;
1410 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1411 struct nlattr *chList;
1412
1413 status = wlan_hdd_validate_context(pHddCtx);
1414 if (0 != status)
1415 {
1416 hddLog(VOS_TRACE_LEVEL_ERROR,
1417 FL("HDD context is not valid") );
1418 return;
1419 }
1420 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1421
1422 hddLog(VOS_TRACE_LEVEL_INFO,
1423 "LL_STATS_RADIO"
1424 " radio is %d onTime is %u "
1425 " txTime is %u rxTime is %u "
1426 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301427 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301428 " onTimePnoScan is %u onTimeHs20 is %u "
1429 " numChannels is %u",
1430 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1431 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1432 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301433 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301434 pWifiRadioStat->onTimeRoamScan,
1435 pWifiRadioStat->onTimePnoScan,
1436 pWifiRadioStat->onTimeHs20,
1437 pWifiRadioStat->numChannels);
1438 /*
1439 * Allocate a size of 4096 for the Radio stats comprising
1440 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1441 * (tSirWifiChannelStats).Each channel data is put with an
1442 * NL attribute.The size of 4096 is considered assuming that
1443 * number of channels shall not exceed beyond 60 with the
1444 * sizeof (tSirWifiChannelStats) being 24 bytes.
1445 */
1446
1447 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1448 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1449 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1450 GFP_KERNEL);
1451
1452 if (!vendor_event)
1453 {
1454 hddLog(VOS_TRACE_LEVEL_ERROR,
1455 FL("cfg80211_vendor_event_alloc failed") );
1456 return;
1457 }
1458
1459 if (nla_put_u32(vendor_event,
1460 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1461 pWifiRadioStat->radio) ||
1462 nla_put_u32(vendor_event,
1463 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1464 pWifiRadioStat->onTime) ||
1465 nla_put_u32(vendor_event,
1466 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1467 pWifiRadioStat->txTime) ||
1468 nla_put_u32(vendor_event,
1469 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1470 pWifiRadioStat->rxTime) ||
1471 nla_put_u32(vendor_event,
1472 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1473 pWifiRadioStat->onTimeScan) ||
1474 nla_put_u32(vendor_event,
1475 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1476 pWifiRadioStat->onTimeNbd) ||
1477 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301478 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1479 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301480 nla_put_u32(vendor_event,
1481 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1482 pWifiRadioStat->onTimeRoamScan) ||
1483 nla_put_u32(vendor_event,
1484 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1485 pWifiRadioStat->onTimePnoScan) ||
1486 nla_put_u32(vendor_event,
1487 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1488 pWifiRadioStat->onTimeHs20) ||
1489 nla_put_u32(vendor_event,
1490 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1491 pWifiRadioStat->numChannels))
1492 {
1493 hddLog(VOS_TRACE_LEVEL_ERROR,
1494 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1495 kfree_skb(vendor_event);
1496 return ;
1497 }
1498
1499 chList = nla_nest_start(vendor_event,
1500 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301501 if(!chList)
1502 {
1503 hddLog(VOS_TRACE_LEVEL_ERROR,
1504 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1505 __func__);
1506 kfree_skb(vendor_event);
1507 return;
1508 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301509 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1510 {
1511 struct nlattr *chInfo;
1512
1513 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1514 pWifiRadioStat->channels +
1515 (i * sizeof(tSirWifiChannelStats)));
1516
1517 hddLog(VOS_TRACE_LEVEL_INFO,
1518 " %d) Channel Info"
1519 " width is %u "
1520 " CenterFreq %u "
1521 " CenterFreq0 %u "
1522 " CenterFreq1 %u "
1523 " onTime %u "
1524 " ccaBusyTime %u",
1525 i,
1526 pWifiChannelStats->channel.width,
1527 pWifiChannelStats->channel.centerFreq,
1528 pWifiChannelStats->channel.centerFreq0,
1529 pWifiChannelStats->channel.centerFreq1,
1530 pWifiChannelStats->onTime,
1531 pWifiChannelStats->ccaBusyTime);
1532
1533
1534 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301535 if(!chInfo)
1536 {
1537 hddLog(VOS_TRACE_LEVEL_ERROR,
1538 "%s: failed to put chInfo",
1539 __func__);
1540 kfree_skb(vendor_event);
1541 return;
1542 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301543
1544 if (nla_put_u32(vendor_event,
1545 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1546 pWifiChannelStats->channel.width) ||
1547 nla_put_u32(vendor_event,
1548 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1549 pWifiChannelStats->channel.centerFreq) ||
1550 nla_put_u32(vendor_event,
1551 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1552 pWifiChannelStats->channel.centerFreq0) ||
1553 nla_put_u32(vendor_event,
1554 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1555 pWifiChannelStats->channel.centerFreq1) ||
1556 nla_put_u32(vendor_event,
1557 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1558 pWifiChannelStats->onTime) ||
1559 nla_put_u32(vendor_event,
1560 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1561 pWifiChannelStats->ccaBusyTime))
1562 {
1563 hddLog(VOS_TRACE_LEVEL_ERROR,
1564 FL("cfg80211_vendor_event_alloc failed") );
1565 kfree_skb(vendor_event);
1566 return ;
1567 }
1568 nla_nest_end(vendor_event, chInfo);
1569 }
1570 nla_nest_end(vendor_event, chList);
1571
1572 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1573 return;
1574}
1575
1576/*
1577 * hdd_link_layer_stats_ind_callback () - This function is called after
1578 * receiving Link Layer indications from FW.This callback converts the firmware
1579 * data to the NL data and send the same to the kernel/upper layers.
1580 */
1581static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1582 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301583 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301584{
Dino Mycled3d50022014-07-07 12:58:25 +05301585 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1586 hdd_adapter_t *pAdapter = NULL;
1587 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301588 int status;
1589
1590 status = wlan_hdd_validate_context(pHddCtx);
1591
1592 if (0 != status)
1593 {
1594 hddLog(VOS_TRACE_LEVEL_ERROR,
1595 FL("HDD context is not valid"));
1596 return;
1597 }
1598
Dino Mycled3d50022014-07-07 12:58:25 +05301599
1600
1601 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1602 if (NULL == pAdapter)
1603 {
1604 hddLog(VOS_TRACE_LEVEL_ERROR,
1605 FL(" MAC address %pM does not exist with host"),
1606 macAddr);
1607 return;
1608 }
1609
Sunil Duttc69bccb2014-05-26 21:30:20 +05301610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301611 "%s: Interface: %s LLStats indType: %d", __func__,
1612 pAdapter->dev->name, indType);
1613
Sunil Duttc69bccb2014-05-26 21:30:20 +05301614 switch (indType)
1615 {
1616 case SIR_HAL_LL_STATS_RESULTS_RSP:
1617 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301618 hddLog(VOS_TRACE_LEVEL_INFO,
1619 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1620 hddLog(VOS_TRACE_LEVEL_INFO,
1621 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1622 linkLayerStatsResults->paramId);
1623 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301624 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1625 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301626 hddLog(VOS_TRACE_LEVEL_INFO,
1627 "LL_STATS RESULTS RESPONSE respId = %u",
1628 linkLayerStatsResults->respId);
1629 hddLog(VOS_TRACE_LEVEL_INFO,
1630 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1631 linkLayerStatsResults->moreResultToFollow);
1632 hddLog(VOS_TRACE_LEVEL_INFO,
1633 "LL_STATS RESULTS RESPONSE result = %p",
1634 linkLayerStatsResults->result);
1635 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1636 {
1637 hdd_link_layer_process_radio_stats(pAdapter,
1638 (v_VOID_t *)linkLayerStatsResults->result);
1639 }
1640 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1641 {
1642 hdd_link_layer_process_iface_stats(pAdapter,
1643 (v_VOID_t *)linkLayerStatsResults->result);
1644 }
1645 else if ( linkLayerStatsResults->paramId &
1646 WMI_LINK_STATS_ALL_PEER )
1647 {
1648 hdd_link_layer_process_peer_stats(pAdapter,
1649 (v_VOID_t *)linkLayerStatsResults->result);
1650 } /* WMI_LINK_STATS_ALL_PEER */
1651 else
1652 {
1653 hddLog(VOS_TRACE_LEVEL_ERROR,
1654 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1655 }
1656
1657 break;
1658 }
1659 default:
1660 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1661 break;
1662 }
1663 return;
1664}
1665
1666const struct
1667nla_policy
1668qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1669{
1670 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1671 { .type = NLA_U32 },
1672 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1673 { .type = NLA_U32 },
1674};
1675
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301676static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1677 struct wireless_dev *wdev,
1678 const void *data,
1679 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301680{
1681 int status;
1682 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301683 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301684 struct net_device *dev = wdev->netdev;
1685 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1686 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Srinivas Dasari98947432014-11-07 19:41:24 +05301687 hdd_station_ctx_t *pHddStaCtx;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301688
1689 status = wlan_hdd_validate_context(pHddCtx);
1690 if (0 != status)
1691 {
1692 hddLog(VOS_TRACE_LEVEL_ERROR,
1693 FL("HDD context is not valid"));
1694 return -EINVAL;
1695 }
1696
1697 if (NULL == pAdapter)
1698 {
1699 hddLog(VOS_TRACE_LEVEL_ERROR,
1700 FL("HDD adapter is Null"));
1701 return -ENODEV;
1702 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301703 /* check the LLStats Capability */
1704 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1705 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1706 {
1707 hddLog(VOS_TRACE_LEVEL_ERROR,
1708 FL("Link Layer Statistics not supported by Firmware"));
1709 return -EINVAL;
1710 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301711
1712 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1713 (struct nlattr *)data,
1714 data_len, qca_wlan_vendor_ll_set_policy))
1715 {
1716 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1717 return -EINVAL;
1718 }
1719 if (!tb_vendor
1720 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1721 {
1722 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1723 return -EINVAL;
1724 }
1725 if (!tb_vendor[
1726 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1727 {
1728 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1729 return -EINVAL;
1730 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301731 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301732 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301733
Dino Mycledf0a5d92014-07-04 09:41:55 +05301734 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301735 nla_get_u32(
1736 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1737
Dino Mycledf0a5d92014-07-04 09:41:55 +05301738 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301739 nla_get_u32(
1740 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1741
Dino Mycled3d50022014-07-07 12:58:25 +05301742 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1743 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301744
1745
1746 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301747 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301748 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301749 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301750 hddLog(VOS_TRACE_LEVEL_INFO,
1751 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301752 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301753 hddLog(VOS_TRACE_LEVEL_INFO,
1754 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301755 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301756
1757 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1758 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301759 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301760 {
1761 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1762 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301763 return -EINVAL;
1764
1765 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301766
1767 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1768 if (VOS_STATUS_SUCCESS !=
1769 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1770 pHddStaCtx->conn_info.staId[0], WIFI_STATS_IFACE))
1771 {
1772 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1773 "WLANTL_ClearInterfaceStats Failed", __func__);
1774 return -EINVAL;
1775 }
1776
1777 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
1778 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
1779 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
1780 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
1781
Sunil Duttc69bccb2014-05-26 21:30:20 +05301782 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301783 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301784 {
1785 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1786 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301787 return -EINVAL;
1788 }
1789
1790 pAdapter->isLinkLayerStatsSet = 1;
1791
1792 return 0;
1793}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301794static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1795 struct wireless_dev *wdev,
1796 const void *data,
1797 int data_len)
1798{
1799 int ret = 0;
1800
1801 vos_ssr_protect(__func__);
1802 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1803 vos_ssr_unprotect(__func__);
1804
1805 return ret;
1806}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301807
1808const struct
1809nla_policy
1810qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1811{
1812 /* Unsigned 32bit value provided by the caller issuing the GET stats
1813 * command. When reporting
1814 * the stats results, the driver uses the same value to indicate
1815 * which GET request the results
1816 * correspond to.
1817 */
1818 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1819
1820 /* Unsigned 32bit value . bit mask to identify what statistics are
1821 requested for retrieval */
1822 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1823};
1824
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301825static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1826 struct wireless_dev *wdev,
1827 const void *data,
1828 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301829{
1830 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1831 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301832 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301833 struct net_device *dev = wdev->netdev;
1834 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1835 int status;
1836
1837 status = wlan_hdd_validate_context(pHddCtx);
1838 if (0 != status)
1839 {
1840 hddLog(VOS_TRACE_LEVEL_ERROR,
1841 FL("HDD context is not valid"));
1842 return -EINVAL ;
1843 }
1844
1845 if (NULL == pAdapter)
1846 {
1847 hddLog(VOS_TRACE_LEVEL_FATAL,
1848 "%s: HDD adapter is Null", __func__);
1849 return -ENODEV;
1850 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301851 /* check the LLStats Capability */
1852 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1853 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1854 {
1855 hddLog(VOS_TRACE_LEVEL_ERROR,
1856 FL("Link Layer Statistics not supported by Firmware"));
1857 return -EINVAL;
1858 }
1859
Sunil Duttc69bccb2014-05-26 21:30:20 +05301860
1861 if (!pAdapter->isLinkLayerStatsSet)
1862 {
1863 hddLog(VOS_TRACE_LEVEL_FATAL,
1864 "%s: isLinkLayerStatsSet : %d",
1865 __func__, pAdapter->isLinkLayerStatsSet);
1866 return -EINVAL;
1867 }
1868
1869 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1870 (struct nlattr *)data,
1871 data_len, qca_wlan_vendor_ll_get_policy))
1872 {
1873 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1874 return -EINVAL;
1875 }
1876
1877 if (!tb_vendor
1878 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1879 {
1880 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1881 return -EINVAL;
1882 }
1883
1884 if (!tb_vendor
1885 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1886 {
1887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1888 return -EINVAL;
1889 }
1890
Sunil Duttc69bccb2014-05-26 21:30:20 +05301891
Dino Mycledf0a5d92014-07-04 09:41:55 +05301892 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301893 nla_get_u32( tb_vendor[
1894 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301895 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301896 nla_get_u32( tb_vendor[
1897 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1898
Dino Mycled3d50022014-07-07 12:58:25 +05301899 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1900 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301901
1902 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301903 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301904 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301905 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301906 hddLog(VOS_TRACE_LEVEL_INFO,
1907 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301908 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301909
1910 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301911 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301912 {
1913 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1914 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301915 return -EINVAL;
1916 }
1917 return 0;
1918}
1919
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301920static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1921 struct wireless_dev *wdev,
1922 const void *data,
1923 int data_len)
1924{
1925 int ret = 0;
1926
1927 vos_ssr_protect(__func__);
1928 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1929 vos_ssr_unprotect(__func__);
1930
1931 return ret;
1932}
1933
Sunil Duttc69bccb2014-05-26 21:30:20 +05301934const struct
1935nla_policy
1936qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1937{
1938 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1939 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1940 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1941 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1942};
1943
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301944static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1945 struct wireless_dev *wdev,
1946 const void *data,
1947 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301948{
1949 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1950 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301951 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301952 struct net_device *dev = wdev->netdev;
1953 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1954 u32 statsClearReqMask;
1955 u8 stopReq;
1956 int status;
1957
1958 status = wlan_hdd_validate_context(pHddCtx);
1959 if (0 != status)
1960 {
1961 hddLog(VOS_TRACE_LEVEL_ERROR,
1962 FL("HDD context is not valid"));
1963 return -EINVAL;
1964 }
1965
1966 if (NULL == pAdapter)
1967 {
1968 hddLog(VOS_TRACE_LEVEL_FATAL,
1969 "%s: HDD adapter is Null", __func__);
1970 return -ENODEV;
1971 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301972 /* check the LLStats Capability */
1973 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1974 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1975 {
1976 hddLog(VOS_TRACE_LEVEL_ERROR,
1977 FL("Enable LLStats Capability"));
1978 return -EINVAL;
1979 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301980
1981 if (!pAdapter->isLinkLayerStatsSet)
1982 {
1983 hddLog(VOS_TRACE_LEVEL_FATAL,
1984 "%s: isLinkLayerStatsSet : %d",
1985 __func__, pAdapter->isLinkLayerStatsSet);
1986 return -EINVAL;
1987 }
1988
1989 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1990 (struct nlattr *)data,
1991 data_len, qca_wlan_vendor_ll_clr_policy))
1992 {
1993 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1994 return -EINVAL;
1995 }
1996
1997 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
1998
1999 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2000 {
2001 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2002 return -EINVAL;
2003
2004 }
2005
Sunil Duttc69bccb2014-05-26 21:30:20 +05302006
Dino Mycledf0a5d92014-07-04 09:41:55 +05302007 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302008 nla_get_u32(
2009 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2010
Dino Mycledf0a5d92014-07-04 09:41:55 +05302011 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302012 nla_get_u8(
2013 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2014
2015 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302016 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302017
Dino Mycled3d50022014-07-07 12:58:25 +05302018 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2019 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302020
2021 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302022 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302023 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302024 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302025 hddLog(VOS_TRACE_LEVEL_INFO,
2026 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302027 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302028 hddLog(VOS_TRACE_LEVEL_INFO,
2029 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302030 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302031
2032 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302033 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302034 {
2035 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302036 hdd_station_ctx_t *pHddStaCtx;
2037
2038 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2039 if (VOS_STATUS_SUCCESS !=
2040 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2041 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2042 {
2043 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2044 "WLANTL_ClearInterfaceStats Failed", __func__);
2045 return -EINVAL;
2046 }
2047 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2048 (statsClearReqMask & WIFI_STATS_IFACE)) {
2049 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2050 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2051 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2052 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2053 }
2054
Sunil Duttc69bccb2014-05-26 21:30:20 +05302055 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2056 2 * sizeof(u32) +
2057 NLMSG_HDRLEN);
2058
2059 if (temp_skbuff != NULL)
2060 {
2061
2062 if (nla_put_u32(temp_skbuff,
2063 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2064 statsClearReqMask) ||
2065 nla_put_u32(temp_skbuff,
2066 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2067 stopReq))
2068 {
2069 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2070 kfree_skb(temp_skbuff);
2071 return -EINVAL;
2072 }
2073 /* If the ask is to stop the stats collection as part of clear
2074 * (stopReq = 1) , ensure that no further requests of get
2075 * go to the firmware by having isLinkLayerStatsSet set to 0.
2076 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302077 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302078 * case the firmware is just asked to clear the statistics.
2079 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302080 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302081 pAdapter->isLinkLayerStatsSet = 0;
2082 return cfg80211_vendor_cmd_reply(temp_skbuff);
2083 }
2084 return -ENOMEM;
2085 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302086 return -EINVAL;
2087}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302088static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2089 struct wireless_dev *wdev,
2090 const void *data,
2091 int data_len)
2092{
2093 int ret = 0;
2094
2095 vos_ssr_protect(__func__);
2096 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2097 vos_ssr_unprotect(__func__);
2098
2099 return ret;
2100
2101
2102}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302103#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2104
Dino Mycle6fb96c12014-06-10 11:52:40 +05302105#ifdef WLAN_FEATURE_EXTSCAN
2106static const struct nla_policy
2107wlan_hdd_extscan_config_policy
2108 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2109{
2110 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2111 { .type = NLA_U32 },
2112 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2113 { .type = NLA_U32 },
2114 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2115 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2116 { .type = NLA_U32 },
2117 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2118 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2119
2120 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2121 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2122 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2123 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2124 { .type = NLA_U8 },
2125 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2126 { .type = NLA_U32 },
2127 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2128 { .type = NLA_U32 },
2129 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2130 { .type = NLA_U32 },
2131 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
2132 { .type = NLA_U8 },
2133 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2134 { .type = NLA_U8 },
2135 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2136 { .type = NLA_U8 },
2137
2138 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2139 { .type = NLA_U32 },
2140 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2141 { .type = NLA_UNSPEC },
2142 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2143 { .type = NLA_S32 },
2144 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2145 { .type = NLA_S32 },
2146 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2147 { .type = NLA_U32 },
2148 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2149 { .type = NLA_U32 },
2150 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2151 { .type = NLA_U32 },
2152 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2153 = { .type = NLA_U32 },
2154 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2155 { .type = NLA_U32 },
2156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2157 NLA_U32 },
2158};
2159
2160static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
2161{
2162 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2163 struct sk_buff *skb = NULL;
2164 tpSirEXTScanCapabilitiesEvent pData =
2165 (tpSirEXTScanCapabilitiesEvent) pMsg;
2166
2167 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2168 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2169 "or pData(%p) is null"), pData);
2170 return;
2171 }
2172
2173 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2174 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2175 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
2176 GFP_KERNEL);
2177
2178 if (!skb) {
2179 hddLog(VOS_TRACE_LEVEL_ERROR,
2180 FL("cfg80211_vendor_event_alloc failed"));
2181 return;
2182 }
2183
2184 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2185 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
2186 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
2187 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
2188 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
2189 pData->maxRssiSampleSize);
2190 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
2191 pData->maxScanReportingThreshold);
2192 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
2193 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
2194 pData->maxSignificantWifiChangeAPs);
2195 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
2196 pData->maxBsidHistoryEntries);
2197
2198 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2199 pData->requestId) ||
2200 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
2201 nla_put_u32(skb,
2202 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
2203 pData->scanCacheSize) ||
2204 nla_put_u32(skb,
2205 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
2206 pData->scanBuckets) ||
2207 nla_put_u32(skb,
2208 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
2209 pData->maxApPerScan) ||
2210 nla_put_u32(skb,
2211 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
2212 pData->maxRssiSampleSize) ||
2213 nla_put_u32(skb,
2214 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
2215 pData->maxScanReportingThreshold) ||
2216 nla_put_u32(skb,
2217 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
2218 pData->maxHotlistAPs) ||
2219 nla_put_u32(skb,
2220 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
2221 pData->maxSignificantWifiChangeAPs) ||
2222 nla_put_u32(skb,
2223 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2224 pData->maxBsidHistoryEntries)) {
2225 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2226 goto nla_put_failure;
2227 }
2228
2229 cfg80211_vendor_event(skb, GFP_KERNEL);
2230 return;
2231
2232nla_put_failure:
2233 kfree_skb(skb);
2234 return;
2235}
2236
2237
2238static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2239{
2240 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2241 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2242 struct sk_buff *skb = NULL;
2243 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2244
2245
2246 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2247 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2248 "or pData(%p) is null"), pData);
2249 return;
2250 }
2251
2252 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2253 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2254 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2255 GFP_KERNEL);
2256
2257 if (!skb) {
2258 hddLog(VOS_TRACE_LEVEL_ERROR,
2259 FL("cfg80211_vendor_event_alloc failed"));
2260 return;
2261 }
2262 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2263 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2264 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2265
2266 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2267 pData->requestId) ||
2268 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2269 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2270 goto nla_put_failure;
2271 }
2272
2273 /*
2274 * Store the Request ID for comparing with the requestID obtained
2275 * in other requests.HDD shall return a failure is the extscan_stop
2276 * request is issued with a different requestId as that of the
2277 * extscan_start request. Also, This requestId shall be used while
2278 * indicating the full scan results to the upper layers.
2279 * The requestId is stored with the assumption that the firmware
2280 * shall return the ext scan start request's requestId in ext scan
2281 * start response.
2282 */
2283 if (pData->status == 0)
2284 pMac->sme.extScanStartReqId = pData->requestId;
2285
2286
2287 cfg80211_vendor_event(skb, GFP_KERNEL);
2288 return;
2289
2290nla_put_failure:
2291 kfree_skb(skb);
2292 return;
2293}
2294
2295
2296static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2297{
2298 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2299 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2300 struct sk_buff *skb = NULL;
2301
2302 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2303 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2304 "or pData(%p) is null"), pData);
2305 return;
2306 }
2307
2308 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2309 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2310 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2311 GFP_KERNEL);
2312
2313 if (!skb) {
2314 hddLog(VOS_TRACE_LEVEL_ERROR,
2315 FL("cfg80211_vendor_event_alloc failed"));
2316 return;
2317 }
2318 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2319 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2320
2321 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2322 pData->requestId) ||
2323 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2324 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2325 goto nla_put_failure;
2326 }
2327
2328 cfg80211_vendor_event(skb, GFP_KERNEL);
2329 return;
2330
2331nla_put_failure:
2332 kfree_skb(skb);
2333 return;
2334}
2335
2336
2337static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2338 void *pMsg)
2339{
2340 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2341 struct sk_buff *skb = NULL;
2342 tpSirEXTScanSetBssidHotListRspParams pData =
2343 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2344
2345 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2346 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2347 "or pData(%p) is null"), pData);
2348 return;
2349 }
2350 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2351 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2352 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2353 GFP_KERNEL);
2354
2355 if (!skb) {
2356 hddLog(VOS_TRACE_LEVEL_ERROR,
2357 FL("cfg80211_vendor_event_alloc failed"));
2358 return;
2359 }
2360 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2361 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2362 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2363
2364 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2365 pData->requestId) ||
2366 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2367 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2368 goto nla_put_failure;
2369 }
2370
2371 cfg80211_vendor_event(skb, GFP_KERNEL);
2372 return;
2373
2374nla_put_failure:
2375 kfree_skb(skb);
2376 return;
2377}
2378
2379static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2380 void *pMsg)
2381{
2382 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2383 struct sk_buff *skb = NULL;
2384 tpSirEXTScanResetBssidHotlistRspParams pData =
2385 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2386
2387 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2388 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2389 "or pData(%p) is null"), pData);
2390 return;
2391 }
2392
2393 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2394 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2395 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2396 GFP_KERNEL);
2397
2398 if (!skb) {
2399 hddLog(VOS_TRACE_LEVEL_ERROR,
2400 FL("cfg80211_vendor_event_alloc failed"));
2401 return;
2402 }
2403 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2404 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
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
2421
2422static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2423 void *pMsg)
2424{
2425 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2426 struct sk_buff *skb = NULL;
2427 tpSirEXTScanSetSignificantChangeRspParams pData =
2428 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2429
2430 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2431 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2432 "or pData(%p) is null"), pData);
2433 return;
2434 }
2435
2436 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2437 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2438 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2439 GFP_KERNEL);
2440
2441 if (!skb) {
2442 hddLog(VOS_TRACE_LEVEL_ERROR,
2443 FL("cfg80211_vendor_event_alloc failed"));
2444 return;
2445 }
2446 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2447 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2448 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2449
2450 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2451 pData->requestId) ||
2452 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2453 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2454 goto nla_put_failure;
2455 }
2456
2457 cfg80211_vendor_event(skb, GFP_KERNEL);
2458 return;
2459
2460nla_put_failure:
2461 kfree_skb(skb);
2462 return;
2463}
2464
2465
2466static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2467 void *pMsg)
2468{
2469 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2470 struct sk_buff *skb = NULL;
2471 tpSirEXTScanResetSignificantChangeRspParams pData =
2472 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2473
2474 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2476 "or pData(%p) is null"), pData);
2477 return;
2478 }
2479
2480 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2481 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2482 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2483 GFP_KERNEL);
2484
2485 if (!skb) {
2486 hddLog(VOS_TRACE_LEVEL_ERROR,
2487 FL("cfg80211_vendor_event_alloc failed"));
2488 return;
2489 }
2490 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2491 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2492 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2493
2494 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2495 pData->requestId) ||
2496 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2497 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2498 goto nla_put_failure;
2499 }
2500
2501 cfg80211_vendor_event(skb, GFP_KERNEL);
2502 return;
2503
2504nla_put_failure:
2505 kfree_skb(skb);
2506 return;
2507}
2508
2509static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2510 void *pMsg)
2511{
2512 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2513 struct sk_buff *skb = NULL;
2514 tANI_U32 i = 0, j, resultsPerEvent;
2515 tANI_S32 totalResults;
2516 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2517 tpSirWifiScanResult pSirWifiScanResult;
2518
2519 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2520 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2521 "or pData(%p) is null"), pData);
2522 return;
2523 }
2524 totalResults = pData->numOfAps;
2525 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2526 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2527 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2528
2529 do{
2530 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2531 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2532 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2533
2534 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2535 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2536 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2537 GFP_KERNEL);
2538
2539 if (!skb) {
2540 hddLog(VOS_TRACE_LEVEL_ERROR,
2541 FL("cfg80211_vendor_event_alloc failed"));
2542 return;
2543 }
2544
2545 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2546
2547 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2548 pData->requestId) ||
2549 nla_put_u32(skb,
2550 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2551 resultsPerEvent)) {
2552 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2553 goto fail;
2554 }
2555 if (nla_put_u8(skb,
2556 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2557 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2558 {
2559 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2560 goto fail;
2561 }
2562
2563 if (resultsPerEvent) {
2564 struct nlattr *aps;
2565
2566 aps = nla_nest_start(skb,
2567 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2568 if (!aps)
2569 {
2570 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2571 goto fail;
2572 }
2573
2574 for (j = 0; j < resultsPerEvent; j++, i++) {
2575 struct nlattr *ap;
2576 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2577 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2578
2579 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2580 "Ssid (%s)"
2581 "Bssid: %pM "
2582 "Channel (%u)"
2583 "Rssi (%d)"
2584 "RTT (%u)"
2585 "RTT_SD (%u)",
2586 i,
2587 pSirWifiScanResult->ts,
2588 pSirWifiScanResult->ssid,
2589 pSirWifiScanResult->bssid,
2590 pSirWifiScanResult->channel,
2591 pSirWifiScanResult->rssi,
2592 pSirWifiScanResult->rtt,
2593 pSirWifiScanResult->rtt_sd);
2594
2595 ap = nla_nest_start(skb, j + 1);
2596 if (!ap)
2597 {
2598 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2599 goto fail;
2600 }
2601
2602 if (nla_put_u64(skb,
2603 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2604 pSirWifiScanResult->ts) )
2605 {
2606 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2607 goto fail;
2608 }
2609 if (nla_put(skb,
2610 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2611 sizeof(pSirWifiScanResult->ssid),
2612 pSirWifiScanResult->ssid) )
2613 {
2614 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2615 goto fail;
2616 }
2617 if (nla_put(skb,
2618 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2619 sizeof(pSirWifiScanResult->bssid),
2620 pSirWifiScanResult->bssid) )
2621 {
2622 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2623 goto fail;
2624 }
2625 if (nla_put_u32(skb,
2626 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2627 pSirWifiScanResult->channel) )
2628 {
2629 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2630 goto fail;
2631 }
Dasari Srinivas90747d72014-10-08 12:16:15 +05302632 if (nla_put_s32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302633 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2634 pSirWifiScanResult->rssi) )
2635 {
2636 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2637 goto fail;
2638 }
2639 if (nla_put_u32(skb,
2640 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2641 pSirWifiScanResult->rtt) )
2642 {
2643 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2644 goto fail;
2645 }
2646 if (nla_put_u32(skb,
2647 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2648 pSirWifiScanResult->rtt_sd))
2649 {
2650 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2651 goto fail;
2652 }
2653
2654 nla_nest_end(skb, ap);
2655 }
2656 nla_nest_end(skb, aps);
2657
2658 }
2659 cfg80211_vendor_event(skb, GFP_KERNEL);
2660 } while (totalResults > 0);
2661
2662 return;
2663fail:
2664 kfree_skb(skb);
2665 return;
2666}
2667
2668static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2669 void *pMsg)
2670{
2671 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2672 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2673 struct sk_buff *skb = NULL;
2674 tANI_U32 i;
2675
2676 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2677 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2678 "or pData(%p) is null"), pData);
2679 return;
2680 }
2681
2682 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2683 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2684 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2685 GFP_KERNEL);
2686
2687 if (!skb) {
2688 hddLog(VOS_TRACE_LEVEL_ERROR,
2689 FL("cfg80211_vendor_event_alloc failed"));
2690 return;
2691 }
2692 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2693 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2694 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2695 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2696
2697 for (i = 0; i < pData->numOfAps; i++) {
2698 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2699 "Ssid (%s) "
2700 "Bssid (" MAC_ADDRESS_STR ") "
2701 "Channel (%u) "
2702 "Rssi (%d) "
2703 "RTT (%u) "
2704 "RTT_SD (%u) ",
2705 i,
2706 pData->ap[i].ts,
2707 pData->ap[i].ssid,
2708 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2709 pData->ap[i].channel,
2710 pData->ap[i].rssi,
2711 pData->ap[i].rtt,
2712 pData->ap[i].rtt_sd);
2713 }
2714
2715 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2716 pData->requestId) ||
2717 nla_put_u32(skb,
2718 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2719 pData->numOfAps)) {
2720 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2721 goto fail;
2722 }
2723 if (pData->numOfAps) {
2724 struct nlattr *aps;
2725
2726 aps = nla_nest_start(skb,
2727 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2728 if (!aps)
2729 goto fail;
2730
2731 for (i = 0; i < pData->numOfAps; i++) {
2732 struct nlattr *ap;
2733
2734 ap = nla_nest_start(skb, i + 1);
2735 if (!ap)
2736 goto fail;
2737
2738 if (nla_put_u64(skb,
2739 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2740 pData->ap[i].ts) ||
2741 nla_put(skb,
2742 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2743 sizeof(pData->ap[i].ssid),
2744 pData->ap[i].ssid) ||
2745 nla_put(skb,
2746 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2747 sizeof(pData->ap[i].bssid),
2748 pData->ap[i].bssid) ||
2749 nla_put_u32(skb,
2750 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2751 pData->ap[i].channel) ||
2752 nla_put_s32(skb,
2753 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2754 pData->ap[i].rssi) ||
2755 nla_put_u32(skb,
2756 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2757 pData->ap[i].rtt) ||
2758 nla_put_u32(skb,
2759 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2760 pData->ap[i].rtt_sd))
2761 goto fail;
2762
2763 nla_nest_end(skb, ap);
2764 }
2765 nla_nest_end(skb, aps);
2766
2767 if (nla_put_u8(skb,
2768 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2769 pData->moreData))
2770 goto fail;
2771 }
2772
2773 cfg80211_vendor_event(skb, GFP_KERNEL);
2774 return;
2775
2776fail:
2777 kfree_skb(skb);
2778 return;
2779
2780}
2781static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2782 void *pMsg)
2783{
2784 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2785 struct sk_buff *skb = NULL;
2786 tANI_U32 i, j;
2787 tpSirWifiSignificantChangeEvent pData =
2788 (tpSirWifiSignificantChangeEvent) pMsg;
2789
2790 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2791 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2792 "or pData(%p) is null"), pData);
2793 return;
2794 }
2795 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2796 EXTSCAN_EVENT_BUF_SIZE,
2797 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2798 GFP_KERNEL);
2799
2800 if (!skb) {
2801 hddLog(VOS_TRACE_LEVEL_ERROR,
2802 FL("cfg80211_vendor_event_alloc failed"));
2803 return;
2804 }
2805 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2806 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2807 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2808 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2809 pData->numSigRssiBss);
2810 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2811
2812 for (i = 0; i < pData->numSigRssiBss; i++) {
2813 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2814 " num RSSI %u ",
2815 i, pData->sigRssiResult[i].bssid,
2816 pData->sigRssiResult[i].channel,
2817 pData->sigRssiResult[i].numRssi);
2818
2819 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2820
2821 hddLog(VOS_TRACE_LEVEL_INFO,
2822 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05302823 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302824
2825 }
2826 }
2827
2828
2829 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2830 pData->requestId) ||
2831 nla_put_u32(skb,
2832 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2833 pData->numSigRssiBss)) {
2834 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2835 goto fail;
2836 }
2837
2838 if (pData->numSigRssiBss) {
2839 struct nlattr *aps;
2840 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2841 if (!aps)
2842 goto fail;
2843 for (i = 0; i < pData->numSigRssiBss; i++) {
2844 struct nlattr *ap;
2845
2846 ap = nla_nest_start(skb, i);
2847 if (!ap)
2848 goto fail;
2849 if (nla_put(skb,
2850 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2851 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2852 nla_put_u32(skb,
2853 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2854 pData->sigRssiResult[i].channel) ||
2855 nla_put_u32(skb,
2856 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2857 pData->sigRssiResult[i].numRssi) ||
2858 nla_put(skb,
2859 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2860 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2861 pData->sigRssiResult[i].rssi))
2862 goto fail;
2863 nla_nest_end(skb, ap);
2864 }
2865 nla_nest_end(skb, aps);
2866 if (nla_put_u8(skb,
2867 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2868 pData->moreData))
2869 goto fail;
2870 }
2871 cfg80211_vendor_event(skb, GFP_KERNEL);
2872 return;
2873fail:
2874 kfree_skb(skb);
2875 return;
2876}
2877
2878static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2879 void *pMsg)
2880{
2881 struct sk_buff *skb;
2882 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2883 tpSirWifiFullScanResultEvent pData =
2884 (tpSirWifiFullScanResultEvent) (pMsg);
2885
2886 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2888 "or pData(%p) is null"), pData);
2889 return;
2890 }
2891
2892 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2893 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2894 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2895 GFP_KERNEL);
2896
2897 if (!skb) {
2898 hddLog(VOS_TRACE_LEVEL_ERROR,
2899 FL("cfg80211_vendor_event_alloc failed"));
2900 return;
2901 }
2902
2903 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2904 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2905 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2906 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2907 "Ssid (%s)"
2908 "Bssid (" MAC_ADDRESS_STR ")"
2909 "Channel (%u)"
2910 "Rssi (%d)"
2911 "RTT (%u)"
2912 "RTT_SD (%u)"),
2913 pData->ap.ts,
2914 pData->ap.ssid,
2915 MAC_ADDR_ARRAY(pData->ap.bssid),
2916 pData->ap.channel,
2917 pData->ap.rssi,
2918 pData->ap.rtt,
2919 pData->ap.rtt_sd);
2920 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2921 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2922 pData->requestId) ||
2923 nla_put_u64(skb,
2924 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2925 pData->ap.ts) ||
2926 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2927 sizeof(pData->ap.ssid),
2928 pData->ap.ssid) ||
2929 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2930 WNI_CFG_BSSID_LEN,
2931 pData->ap.bssid) ||
2932 nla_put_u32(skb,
2933 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2934 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05302935 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302936 pData->ap.rssi) ||
2937 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2938 pData->ap.rtt) ||
2939 nla_put_u32(skb,
2940 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2941 pData->ap.rtt_sd) ||
2942 nla_put_u16(skb,
2943 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2944 pData->ap.beaconPeriod) ||
2945 nla_put_u16(skb,
2946 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2947 pData->ap.capability) ||
2948 nla_put_u32(skb,
2949 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2950 pData->ieLength))
2951 {
2952 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2953 goto nla_put_failure;
2954 }
2955 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2956 pData->ieLength,
2957 pData->ie))
2958 {
2959 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2960 goto nla_put_failure;
2961 }
2962
2963 cfg80211_vendor_event(skb, GFP_KERNEL);
2964 return;
2965
2966nla_put_failure:
2967 kfree_skb(skb);
2968 return;
2969}
2970
2971static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
2972 void *pMsg)
2973{
2974 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2975 struct sk_buff *skb = NULL;
2976 tpSirEXTScanResultsAvailableIndParams pData =
2977 (tpSirEXTScanResultsAvailableIndParams) pMsg;
2978
2979 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2980 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2981 "or pData(%p) is null"), pData);
2982 return;
2983 }
2984
2985 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2986 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2987 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
2988 GFP_KERNEL);
2989
2990 if (!skb) {
2991 hddLog(VOS_TRACE_LEVEL_ERROR,
2992 FL("cfg80211_vendor_event_alloc failed"));
2993 return;
2994 }
2995
2996 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2997 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2998 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
2999 pData->numResultsAvailable);
3000 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3001 pData->requestId) ||
3002 nla_put_u32(skb,
3003 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3004 pData->numResultsAvailable)) {
3005 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3006 goto nla_put_failure;
3007 }
3008
3009 cfg80211_vendor_event(skb, GFP_KERNEL);
3010 return;
3011
3012nla_put_failure:
3013 kfree_skb(skb);
3014 return;
3015}
3016
3017static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3018{
3019 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3020 struct sk_buff *skb = NULL;
3021 tpSirEXTScanProgressIndParams pData =
3022 (tpSirEXTScanProgressIndParams) pMsg;
3023
3024 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
3025 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
3026 "or pData(%p) is null"), pData);
3027 return;
3028 }
3029
3030 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
3031 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3032 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3033 GFP_KERNEL);
3034
3035 if (!skb) {
3036 hddLog(VOS_TRACE_LEVEL_ERROR,
3037 FL("cfg80211_vendor_event_alloc failed"));
3038 return;
3039 }
3040 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3041 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3042 pData->extScanEventType);
3043 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3044 pData->status);
3045
3046 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3047 pData->extScanEventType) ||
3048 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303049 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3050 pData->requestId) ||
3051 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303052 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3053 pData->status)) {
3054 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3055 goto nla_put_failure;
3056 }
3057
3058 cfg80211_vendor_event(skb, GFP_KERNEL);
3059 return;
3060
3061nla_put_failure:
3062 kfree_skb(skb);
3063 return;
3064}
3065
3066void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3067 void *pMsg)
3068{
3069 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3070
3071 if (wlan_hdd_validate_context(pHddCtx)) {
Dasari Srinivasb46ed1d2014-10-08 13:03:08 +05303072 hddLog(VOS_TRACE_LEVEL_INFO, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303073 return;
3074 }
3075
3076 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3077
3078
3079 switch(evType) {
3080 case SIR_HAL_EXTSCAN_START_RSP:
3081 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3082 break;
3083
3084 case SIR_HAL_EXTSCAN_STOP_RSP:
3085 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3086 break;
3087 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3088 /* There is no need to send this response to upper layer
3089 Just log the message */
3090 hddLog(VOS_TRACE_LEVEL_INFO,
3091 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3092 break;
3093 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3094 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3095 break;
3096
3097 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3098 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3099 break;
3100
3101 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
3102 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
3103 break;
3104
3105 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
3106 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
3107 break;
3108 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
3109 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
3110 break;
3111 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3112 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3113 break;
3114 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3115 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3116 break;
3117 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3118 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3119 break;
3120 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3121 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3122 break;
3123 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
3124 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
3125 break;
3126 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3127 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3128 break;
3129 default:
3130 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3131 break;
3132 }
3133}
3134
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303135static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3136 struct wireless_dev *wdev,
3137 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303138{
Dino Myclee8843b32014-07-04 14:21:45 +05303139 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303140 struct net_device *dev = wdev->netdev;
3141 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3142 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3143 struct nlattr
3144 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3145 eHalStatus status;
3146
3147 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3148 status = wlan_hdd_validate_context(pHddCtx);
3149 if (0 != status)
3150 {
3151 hddLog(VOS_TRACE_LEVEL_ERROR,
3152 FL("HDD context is not valid"));
3153 return -EINVAL;
3154 }
Dino Myclee8843b32014-07-04 14:21:45 +05303155 /* check the EXTScan Capability */
3156 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3157 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3158 {
3159 hddLog(VOS_TRACE_LEVEL_ERROR,
3160 FL("EXTScan not enabled/supported by Firmware"));
3161 return -EINVAL;
3162 }
3163
Dino Mycle6fb96c12014-06-10 11:52:40 +05303164 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3165 data, dataLen,
3166 wlan_hdd_extscan_config_policy)) {
3167 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3168 return -EINVAL;
3169 }
3170
3171 /* Parse and fetch request Id */
3172 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3173 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3174 return -EINVAL;
3175 }
3176
Dino Mycle6fb96c12014-06-10 11:52:40 +05303177
Dino Myclee8843b32014-07-04 14:21:45 +05303178 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303179 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303180 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303181
Dino Myclee8843b32014-07-04 14:21:45 +05303182 reqMsg.sessionId = pAdapter->sessionId;
3183 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303184
Dino Myclee8843b32014-07-04 14:21:45 +05303185 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303186 if (!HAL_STATUS_SUCCESS(status)) {
3187 hddLog(VOS_TRACE_LEVEL_ERROR,
3188 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303189 return -EINVAL;
3190 }
3191
3192 return 0;
3193}
3194
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303195static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3196 struct wireless_dev *wdev,
3197 const void *data, int dataLen)
3198{
3199 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303200
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303201 vos_ssr_protect(__func__);
3202 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3203 vos_ssr_unprotect(__func__);
3204
3205 return ret;
3206}
3207
3208static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3209 struct wireless_dev *wdev,
3210 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303211{
Dino Myclee8843b32014-07-04 14:21:45 +05303212 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303213 struct net_device *dev = wdev->netdev;
3214 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3215 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3216 struct nlattr
3217 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3218 eHalStatus status;
3219
3220 status = wlan_hdd_validate_context(pHddCtx);
3221 if (0 != status)
3222 {
3223 hddLog(VOS_TRACE_LEVEL_ERROR,
3224 FL("HDD context is not valid"));
3225 return -EINVAL;
3226 }
Dino Myclee8843b32014-07-04 14:21:45 +05303227 /* check the EXTScan Capability */
3228 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3229 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3230 {
3231 hddLog(VOS_TRACE_LEVEL_ERROR,
3232 FL("EXTScan not enabled/supported by Firmware"));
3233 return -EINVAL;
3234 }
3235
Dino Mycle6fb96c12014-06-10 11:52:40 +05303236 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3237 data, dataLen,
3238 wlan_hdd_extscan_config_policy)) {
3239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3240 return -EINVAL;
3241 }
3242 /* Parse and fetch request Id */
3243 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3244 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3245 return -EINVAL;
3246 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303247
Dino Myclee8843b32014-07-04 14:21:45 +05303248 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303249 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3250
Dino Myclee8843b32014-07-04 14:21:45 +05303251 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303252
Dino Myclee8843b32014-07-04 14:21:45 +05303253 reqMsg.sessionId = pAdapter->sessionId;
3254 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303255
3256 /* Parse and fetch flush parameter */
3257 if (!tb
3258 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3259 {
3260 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3261 goto failed;
3262 }
Dino Myclee8843b32014-07-04 14:21:45 +05303263 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303264 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3265
Dino Myclee8843b32014-07-04 14:21:45 +05303266 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303267
Dino Myclee8843b32014-07-04 14:21:45 +05303268 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303269 if (!HAL_STATUS_SUCCESS(status)) {
3270 hddLog(VOS_TRACE_LEVEL_ERROR,
3271 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303272 return -EINVAL;
3273 }
3274 return 0;
3275
3276failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303277 return -EINVAL;
3278}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303279static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3280 struct wireless_dev *wdev,
3281 const void *data, int dataLen)
3282{
3283 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303284
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303285 vos_ssr_protect(__func__);
3286 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3287 vos_ssr_unprotect(__func__);
3288
3289 return ret;
3290}
3291
3292static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303293 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303294 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303295{
3296 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3297 struct net_device *dev = wdev->netdev;
3298 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3299 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3300 struct nlattr
3301 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3302 struct nlattr
3303 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3304 struct nlattr *apTh;
3305 eHalStatus status;
3306 tANI_U8 i = 0;
3307 int rem;
3308
3309 status = wlan_hdd_validate_context(pHddCtx);
3310 if (0 != status)
3311 {
3312 hddLog(VOS_TRACE_LEVEL_ERROR,
3313 FL("HDD context is not valid"));
3314 return -EINVAL;
3315 }
Dino Myclee8843b32014-07-04 14:21:45 +05303316 /* check the EXTScan Capability */
3317 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3318 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3319 {
3320 hddLog(VOS_TRACE_LEVEL_ERROR,
3321 FL("EXTScan not enabled/supported by Firmware"));
3322 return -EINVAL;
3323 }
3324
Dino Mycle6fb96c12014-06-10 11:52:40 +05303325 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3326 data, dataLen,
3327 wlan_hdd_extscan_config_policy)) {
3328 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3329 return -EINVAL;
3330 }
3331
3332 /* Parse and fetch request Id */
3333 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3334 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3335 return -EINVAL;
3336 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303337 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3338 vos_mem_malloc(sizeof(*pReqMsg));
3339 if (!pReqMsg) {
3340 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3341 return -ENOMEM;
3342 }
3343
Dino Myclee8843b32014-07-04 14:21:45 +05303344
Dino Mycle6fb96c12014-06-10 11:52:40 +05303345 pReqMsg->requestId = nla_get_u32(
3346 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3347 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3348
3349 /* Parse and fetch number of APs */
3350 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3352 goto fail;
3353 }
3354
3355 pReqMsg->sessionId = pAdapter->sessionId;
3356 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3357
3358 pReqMsg->numAp = nla_get_u32(
3359 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3360 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3361
3362 nla_for_each_nested(apTh,
3363 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3364 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3365 nla_data(apTh), nla_len(apTh),
3366 NULL)) {
3367 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3368 goto fail;
3369 }
3370
3371 /* Parse and fetch MAC address */
3372 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3373 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3374 goto fail;
3375 }
3376 memcpy(pReqMsg->ap[i].bssid, nla_data(
3377 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3378 sizeof(tSirMacAddr));
3379 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3380
3381 /* Parse and fetch low RSSI */
3382 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3383 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3384 goto fail;
3385 }
3386 pReqMsg->ap[i].low = nla_get_s32(
3387 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3388 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3389
3390 /* Parse and fetch high RSSI */
3391 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3392 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3393 goto fail;
3394 }
3395 pReqMsg->ap[i].high = nla_get_s32(
3396 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3397 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3398 pReqMsg->ap[i].high);
3399
3400 /* Parse and fetch channel */
3401 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3402 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3403 goto fail;
3404 }
3405 pReqMsg->ap[i].channel = nla_get_u32(
3406 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3407 hddLog(VOS_TRACE_LEVEL_INFO,
3408 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3409 i++;
3410 }
3411 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3412 if (!HAL_STATUS_SUCCESS(status)) {
3413 hddLog(VOS_TRACE_LEVEL_ERROR,
3414 FL("sme_SetBssHotlist failed(err=%d)"), status);
3415 vos_mem_free(pReqMsg);
3416 return -EINVAL;
3417 }
3418
Dino Myclee8843b32014-07-04 14:21:45 +05303419 vos_mem_free(pReqMsg);
3420
Dino Mycle6fb96c12014-06-10 11:52:40 +05303421 return 0;
3422
3423fail:
3424 vos_mem_free(pReqMsg);
3425 return -EINVAL;
3426}
3427
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303428static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3429 struct wireless_dev *wdev,
3430 const void *data, int dataLen)
3431{
3432 int ret = 0;
3433
3434 vos_ssr_protect(__func__);
3435 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3436 dataLen);
3437 vos_ssr_unprotect(__func__);
3438
3439 return ret;
3440}
3441
3442static int __wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303443 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303444 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303445{
3446 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3447 struct net_device *dev = wdev->netdev;
3448 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3449 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3450 struct nlattr
3451 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3452 struct nlattr
3453 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3454 struct nlattr *apTh;
3455 eHalStatus status;
3456 int i = 0;
3457 int rem;
3458
3459 status = wlan_hdd_validate_context(pHddCtx);
3460 if (0 != status)
3461 {
3462 hddLog(VOS_TRACE_LEVEL_ERROR,
3463 FL("HDD context is not valid"));
3464 return -EINVAL;
3465 }
Dino Myclee8843b32014-07-04 14:21:45 +05303466 /* check the EXTScan Capability */
3467 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3468 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3469 {
3470 hddLog(VOS_TRACE_LEVEL_ERROR,
3471 FL("EXTScan not enabled/supported by Firmware"));
3472 return -EINVAL;
3473 }
3474
Dino Mycle6fb96c12014-06-10 11:52:40 +05303475 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3476 data, dataLen,
3477 wlan_hdd_extscan_config_policy)) {
3478 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3479 return -EINVAL;
3480 }
3481
3482 /* Parse and fetch request Id */
3483 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3484 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3485 return -EINVAL;
3486 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303487 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303488 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303489 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303490 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3491 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303492 }
3493
Dino Myclee8843b32014-07-04 14:21:45 +05303494
3495
Dino Mycle6fb96c12014-06-10 11:52:40 +05303496 pReqMsg->requestId = nla_get_u32(
3497 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3498 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3499
3500 /* Parse and fetch RSSI sample size */
3501 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3502 {
3503 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3504 goto fail;
3505 }
3506 pReqMsg->rssiSampleSize = nla_get_u32(
3507 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3508 hddLog(VOS_TRACE_LEVEL_INFO,
3509 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3510
3511 /* Parse and fetch lost AP sample size */
3512 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3513 {
3514 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3515 goto fail;
3516 }
3517 pReqMsg->lostApSampleSize = nla_get_u32(
3518 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3519 hddLog(VOS_TRACE_LEVEL_INFO,
3520 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3521 /* Parse and fetch minimum Breaching */
3522 if (!tb
3523 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3524 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3525 goto fail;
3526 }
3527 pReqMsg->minBreaching = nla_get_u32(
3528 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3529 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3530
3531 /* Parse and fetch number of APs */
3532 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3533 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3534 goto fail;
3535 }
3536 pReqMsg->numAp = nla_get_u32(
3537 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3538 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3539
3540 pReqMsg->sessionId = pAdapter->sessionId;
3541 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3542
3543 nla_for_each_nested(apTh,
3544 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3545 if(nla_parse(tb2,
3546 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3547 nla_data(apTh), nla_len(apTh),
3548 NULL)) {
3549 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3550 goto fail;
3551 }
3552
3553 /* Parse and fetch MAC address */
3554 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3555 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3556 goto fail;
3557 }
3558 memcpy(pReqMsg->ap[i].bssid, nla_data(
3559 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3560 sizeof(tSirMacAddr));
3561
3562 /* Parse and fetch low RSSI */
3563 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3564 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3565 goto fail;
3566 }
3567 pReqMsg->ap[i].low = nla_get_s32(
3568 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3569 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3570
3571 /* Parse and fetch high RSSI */
3572 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3573 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3574 goto fail;
3575 }
3576 pReqMsg->ap[i].high = nla_get_s32(
3577 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3578 hddLog(VOS_TRACE_LEVEL_INFO,
3579 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3580
3581 /* Parse and fetch channel */
3582 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3583 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3584 goto fail;
3585 }
3586 pReqMsg->ap[i].channel = nla_get_u32(
3587 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3588 hddLog(VOS_TRACE_LEVEL_INFO,
3589 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3590 i++;
3591 }
3592
3593 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3594 if (!HAL_STATUS_SUCCESS(status)) {
3595 hddLog(VOS_TRACE_LEVEL_ERROR,
3596 FL("sme_SetSignificantChange failed(err=%d)"), status);
3597 vos_mem_free(pReqMsg);
3598 return -EINVAL;
3599 }
Dino Myclee8843b32014-07-04 14:21:45 +05303600 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303601 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3602 return 0;
3603
3604fail:
3605 vos_mem_free(pReqMsg);
3606 return -EINVAL;
3607}
3608
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303609static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3610 struct wireless_dev *wdev,
3611 const void *data, int dataLen)
3612{
3613 int ret = 0;
3614
3615 vos_ssr_protect(__func__);
3616 ret = __wlan_hdd_cfg80211_extscan_set_significant_change(wiphy, wdev, data,
3617 dataLen);
3618 vos_ssr_unprotect(__func__);
3619
3620 return ret;
3621}
3622
3623static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303624 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303625 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303626{
3627 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3628 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3629 tANI_U8 numChannels = 0;
3630 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3631 tANI_U32 requestId;
3632 tWifiBand wifiBand;
3633 eHalStatus status;
3634 struct sk_buff *replySkb;
3635 tANI_U8 i;
3636
3637 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3638 status = wlan_hdd_validate_context(pHddCtx);
3639 if (0 != status)
3640 {
3641 hddLog(VOS_TRACE_LEVEL_ERROR,
3642 FL("HDD context is not valid"));
3643 return -EINVAL;
3644 }
Dino Myclee8843b32014-07-04 14:21:45 +05303645 /* check the EXTScan Capability */
3646 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3647 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3648 {
3649 hddLog(VOS_TRACE_LEVEL_ERROR,
3650 FL("EXTScan not enabled/supported by Firmware"));
3651 return -EINVAL;
3652 }
3653
Dino Mycle6fb96c12014-06-10 11:52:40 +05303654 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3655 data, dataLen,
3656 wlan_hdd_extscan_config_policy)) {
3657 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3658 return -EINVAL;
3659 }
3660
3661 /* Parse and fetch request Id */
3662 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3663 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3664 return -EINVAL;
3665 }
3666 requestId = nla_get_u32(
3667 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3668 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3669
3670 /* Parse and fetch wifi band */
3671 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3672 {
3673 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3674 return -EINVAL;
3675 }
3676 wifiBand = nla_get_u32(
3677 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3678 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3679
3680 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3681 wifiBand, ChannelList,
3682 &numChannels);
3683 if (eHAL_STATUS_SUCCESS != status) {
3684 hddLog(VOS_TRACE_LEVEL_ERROR,
3685 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3686 return -EINVAL;
3687 }
3688 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3689 for (i = 0; i < numChannels; i++)
3690 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3691
3692 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3693 sizeof(u32) * numChannels +
3694 NLMSG_HDRLEN);
3695
3696 if (!replySkb) {
3697 hddLog(VOS_TRACE_LEVEL_ERROR,
3698 FL("valid channels: buffer alloc fail"));
3699 return -EINVAL;
3700 }
3701 if (nla_put_u32(replySkb,
3702 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3703 numChannels) ||
3704 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3705 sizeof(u32) * numChannels, ChannelList)) {
3706
3707 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3708 kfree_skb(replySkb);
3709 return -EINVAL;
3710 }
3711
3712 return cfg80211_vendor_cmd_reply(replySkb);
3713}
3714
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303715static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3716 struct wireless_dev *wdev,
3717 const void *data, int dataLen)
3718{
3719 int ret = 0;
3720
3721 vos_ssr_protect(__func__);
3722 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
3723 dataLen);
3724 vos_ssr_unprotect(__func__);
3725
3726 return ret;
3727}
3728
3729static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303730 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303731 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303732{
Dino Myclee8843b32014-07-04 14:21:45 +05303733 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303734 struct net_device *dev = wdev->netdev;
3735 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3736 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3737 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3738 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3739 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3740 struct nlattr *buckets;
3741 struct nlattr *channels;
3742 int rem1;
3743 int rem2;
3744 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303745 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303746
3747 status = wlan_hdd_validate_context(pHddCtx);
3748 if (0 != status)
3749 {
3750 hddLog(VOS_TRACE_LEVEL_ERROR,
3751 FL("HDD context is not valid"));
3752 return -EINVAL;
3753 }
Dino Myclee8843b32014-07-04 14:21:45 +05303754 /* check the EXTScan Capability */
3755 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3756 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3757 {
3758 hddLog(VOS_TRACE_LEVEL_ERROR,
3759 FL("EXTScan not enabled/supported by Firmware"));
3760 return -EINVAL;
3761 }
3762
Dino Mycle6fb96c12014-06-10 11:52:40 +05303763 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3764 data, dataLen,
3765 wlan_hdd_extscan_config_policy)) {
3766 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3767 return -EINVAL;
3768 }
3769
3770 /* Parse and fetch request Id */
3771 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3772 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3773 return -EINVAL;
3774 }
3775
Dino Myclee8843b32014-07-04 14:21:45 +05303776 pReqMsg = (tpSirEXTScanStartReqParams)
3777 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303778 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303779 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3780 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303781 }
3782
3783 pReqMsg->requestId = nla_get_u32(
3784 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3785 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3786
3787 pReqMsg->sessionId = pAdapter->sessionId;
3788 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3789
3790 /* Parse and fetch base period */
3791 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3792 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3793 goto fail;
3794 }
3795 pReqMsg->basePeriod = nla_get_u32(
3796 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3797 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3798 pReqMsg->basePeriod);
3799
3800 /* Parse and fetch max AP per scan */
3801 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3802 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3803 goto fail;
3804 }
3805 pReqMsg->maxAPperScan = nla_get_u32(
3806 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3807 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3808 pReqMsg->maxAPperScan);
3809
3810 /* Parse and fetch report threshold */
3811 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3812 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3813 goto fail;
3814 }
3815 pReqMsg->reportThreshold = nla_get_u8(
3816 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3817 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3818 pReqMsg->reportThreshold);
3819
3820 /* Parse and fetch number of buckets */
3821 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3822 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3823 goto fail;
3824 }
3825 pReqMsg->numBuckets = nla_get_u8(
3826 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3827 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3828 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3829 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3830 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3831 }
3832 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3833 pReqMsg->numBuckets);
3834 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3835 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3836 goto fail;
3837 }
3838
3839 nla_for_each_nested(buckets,
3840 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3841 if(nla_parse(bucket,
3842 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3843 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3844 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3845 goto fail;
3846 }
3847
3848 /* Parse and fetch bucket spec */
3849 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3850 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3851 goto fail;
3852 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303853
3854 pReqMsg->buckets[index].bucket = nla_get_u8(
3855 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3856
3857 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
3858 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303859
3860 /* Parse and fetch wifi band */
3861 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3862 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3863 goto fail;
3864 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303865 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303866 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3867 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303868 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303869
3870 /* Parse and fetch period */
3871 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3872 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3873 goto fail;
3874 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303875 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303876 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3877 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303878 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303879
3880 /* Parse and fetch report events */
3881 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3882 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3883 goto fail;
3884 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303885 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303886 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3887 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303888 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303889
3890 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303891 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
3892 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303893 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3894 goto fail;
3895 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303896 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303897 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3898 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303899 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303900
3901 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3902 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3903 goto fail;
3904 }
3905
3906 j = 0;
3907 nla_for_each_nested(channels,
3908 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3909 if(nla_parse(channel,
3910 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3911 nla_data(channels), nla_len(channels),
3912 NULL)) { //wlan_hdd_extscan_config_policy here
3913 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3914 goto fail;
3915 }
3916
3917 /* Parse and fetch channel */
3918 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3919 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3920 goto fail;
3921 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303922 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303923 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3924 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303925 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303926
3927 /* Parse and fetch dwell time */
3928 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3929 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3930 goto fail;
3931 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303932 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303933 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3934 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303935 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303936
3937 /* Parse and fetch channel spec passive */
3938 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3939 hddLog(VOS_TRACE_LEVEL_ERROR,
3940 FL("attr channel spec passive failed"));
3941 goto fail;
3942 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303943 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303944 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3945 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303946 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303947 j++;
3948 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303949 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303950 }
3951 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3952 if (!HAL_STATUS_SUCCESS(status)) {
3953 hddLog(VOS_TRACE_LEVEL_ERROR,
3954 FL("sme_EXTScanStart failed(err=%d)"), status);
3955 vos_mem_free(pReqMsg);
3956 return -EINVAL;
3957 }
3958
Dino Myclee8843b32014-07-04 14:21:45 +05303959 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303960 return 0;
3961
3962fail:
3963 vos_mem_free(pReqMsg);
3964 return -EINVAL;
3965}
3966
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303967static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3968 struct wireless_dev *wdev,
3969 const void *data, int dataLen)
3970{
3971 int ret = 0;
3972
3973 vos_ssr_protect(__func__);
3974 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
3975 vos_ssr_unprotect(__func__);
3976
3977 return ret;
3978}
3979
3980static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303981 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303982 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303983{
Dino Myclee8843b32014-07-04 14:21:45 +05303984 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303985 struct net_device *dev = wdev->netdev;
3986 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3987 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3988 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3989 eHalStatus status;
3990
3991 status = wlan_hdd_validate_context(pHddCtx);
3992 if (0 != status)
3993 {
3994 hddLog(VOS_TRACE_LEVEL_ERROR,
3995 FL("HDD context is not valid"));
3996 return -EINVAL;
3997 }
Dino Myclee8843b32014-07-04 14:21:45 +05303998 /* check the EXTScan Capability */
3999 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4000 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4001 {
4002 hddLog(VOS_TRACE_LEVEL_ERROR,
4003 FL("EXTScan not enabled/supported by Firmware"));
4004 return -EINVAL;
4005 }
4006
Dino Mycle6fb96c12014-06-10 11:52:40 +05304007 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4008 data, dataLen,
4009 wlan_hdd_extscan_config_policy)) {
4010 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4011 return -EINVAL;
4012 }
4013
4014 /* Parse and fetch request Id */
4015 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4016 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4017 return -EINVAL;
4018 }
4019
Dino Myclee8843b32014-07-04 14:21:45 +05304020 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304021 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304022 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304023
Dino Myclee8843b32014-07-04 14:21:45 +05304024 reqMsg.sessionId = pAdapter->sessionId;
4025 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304026
Dino Myclee8843b32014-07-04 14:21:45 +05304027 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304028 if (!HAL_STATUS_SUCCESS(status)) {
4029 hddLog(VOS_TRACE_LEVEL_ERROR,
4030 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304031 return -EINVAL;
4032 }
4033
4034 return 0;
4035}
4036
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304037static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4038 struct wireless_dev *wdev,
4039 const void *data, int dataLen)
4040{
4041 int ret = 0;
4042
4043 vos_ssr_protect(__func__);
4044 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4045 vos_ssr_unprotect(__func__);
4046
4047 return ret;
4048}
4049
4050static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304051 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304052 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304053{
Dino Myclee8843b32014-07-04 14:21:45 +05304054 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304055 struct net_device *dev = wdev->netdev;
4056 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4057 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4058 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4059 eHalStatus status;
4060
4061 status = wlan_hdd_validate_context(pHddCtx);
4062 if (0 != status)
4063 {
4064 hddLog(VOS_TRACE_LEVEL_ERROR,
4065 FL("HDD context is not valid"));
4066 return -EINVAL;
4067 }
Dino Myclee8843b32014-07-04 14:21:45 +05304068 /* check the EXTScan Capability */
4069 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4070 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4071 {
4072 hddLog(VOS_TRACE_LEVEL_ERROR,
4073 FL("EXTScan not enabled/supported by Firmware"));
4074 return -EINVAL;
4075 }
4076
Dino Mycle6fb96c12014-06-10 11:52:40 +05304077 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4078 data, dataLen,
4079 wlan_hdd_extscan_config_policy)) {
4080 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4081 return -EINVAL;
4082 }
4083
4084 /* Parse and fetch request Id */
4085 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4086 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4087 return -EINVAL;
4088 }
4089
Dino Myclee8843b32014-07-04 14:21:45 +05304090 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304091 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304092 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304093
Dino Myclee8843b32014-07-04 14:21:45 +05304094 reqMsg.sessionId = pAdapter->sessionId;
4095 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304096
Dino Myclee8843b32014-07-04 14:21:45 +05304097 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304098 if (!HAL_STATUS_SUCCESS(status)) {
4099 hddLog(VOS_TRACE_LEVEL_ERROR,
4100 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304101 return -EINVAL;
4102 }
4103
4104 return 0;
4105}
4106
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304107static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4108 struct wireless_dev *wdev,
4109 const void *data, int dataLen)
4110{
4111 int ret = 0;
4112
4113 vos_ssr_protect(__func__);
4114 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4115 vos_ssr_unprotect(__func__);
4116
4117 return ret;
4118}
4119
4120static int __wlan_hdd_cfg80211_extscan_reset_significant_change(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304121 struct wiphy *wiphy,
4122 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304123 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304124{
Dino Myclee8843b32014-07-04 14:21:45 +05304125 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304126 struct net_device *dev = wdev->netdev;
4127 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4128 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4129 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4130 eHalStatus status;
4131
4132 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
4133 status = wlan_hdd_validate_context(pHddCtx);
4134 if (0 != status)
4135 {
4136 hddLog(VOS_TRACE_LEVEL_ERROR,
4137 FL("HDD context is not valid"));
4138 return -EINVAL;
4139 }
Dino Myclee8843b32014-07-04 14:21:45 +05304140 /* check the EXTScan Capability */
4141 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4142 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4143 {
4144 hddLog(VOS_TRACE_LEVEL_ERROR,
4145 FL("EXTScan not enabled/supported by Firmware"));
4146 return -EINVAL;
4147 }
4148
Dino Mycle6fb96c12014-06-10 11:52:40 +05304149 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4150 data, dataLen,
4151 wlan_hdd_extscan_config_policy)) {
4152 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4153 return -EINVAL;
4154 }
4155
4156 /* Parse and fetch request Id */
4157 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4158 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4159 return -EINVAL;
4160 }
4161
Dino Mycle6fb96c12014-06-10 11:52:40 +05304162
Dino Myclee8843b32014-07-04 14:21:45 +05304163 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304164 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304165 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304166
Dino Myclee8843b32014-07-04 14:21:45 +05304167 reqMsg.sessionId = pAdapter->sessionId;
4168 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304169
Dino Myclee8843b32014-07-04 14:21:45 +05304170 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304171 if (!HAL_STATUS_SUCCESS(status)) {
4172 hddLog(VOS_TRACE_LEVEL_ERROR,
4173 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304174 return -EINVAL;
4175 }
4176
4177 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
4178 return 0;
4179}
4180
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304181static int wlan_hdd_cfg80211_extscan_reset_significant_change(
4182 struct wiphy *wiphy,
4183 struct wireless_dev *wdev,
4184 const void *data, int dataLen)
4185{
4186 int ret = 0;
4187
4188 vos_ssr_protect(__func__);
4189 ret = __wlan_hdd_cfg80211_extscan_reset_significant_change(wiphy,
4190 wdev, data,
4191 dataLen);
4192 vos_ssr_unprotect(__func__);
4193
4194 return ret;
4195}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304196#endif /* WLAN_FEATURE_EXTSCAN */
4197
Atul Mittal115287b2014-07-08 13:26:33 +05304198/*EXT TDLS*/
4199static const struct nla_policy
4200wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4201{
4202 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4203 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4204 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4205 {.type = NLA_S32 },
4206 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4207 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4208
4209};
4210
4211static const struct nla_policy
4212wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4213{
4214 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4215
4216};
4217
4218static const struct nla_policy
4219wlan_hdd_tdls_config_state_change_policy[
4220 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4221{
4222 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4223 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4224 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304225 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4226 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4227 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304228
4229};
4230
4231static const struct nla_policy
4232wlan_hdd_tdls_config_get_status_policy[
4233 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4234{
4235 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4236 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4237 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304238 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4239 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4240 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304241
4242};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304243
4244static const struct nla_policy
4245wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4246{
4247 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4248};
4249
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304250static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304251 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304252 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304253 int data_len)
4254{
4255
4256 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4257 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4258
4259 if (0 != wlan_hdd_validate_context(pHddCtx)){
4260 hddLog(VOS_TRACE_LEVEL_ERROR, FL("hdd Ctx invalid while spoof macAddr"));
4261 return -EINVAL;
4262 }
4263 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
4264 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN disabled in ini"));
4265 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304266 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304267 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
4268 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN not supported by FW"));
4269 return -ENOTSUPP;
4270 }
4271
4272 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4273 data, data_len, wlan_hdd_mac_config)) {
4274 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4275 return -EINVAL;
4276 }
4277
4278 /* Parse and fetch mac address */
4279 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4280 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4281 return -EINVAL;
4282 }
4283
4284 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4285 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4286 VOS_MAC_ADDR_LAST_3_BYTES);
4287
Siddharth Bhal76972212014-10-15 16:22:51 +05304288 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4289
4290 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304291 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4292 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304293 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4294 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4295 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4296 {
4297 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4298 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4299 VOS_MAC_ADDRESS_LEN);
4300 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304301 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304302
Siddharth Bhal76972212014-10-15 16:22:51 +05304303 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
4304 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304305 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4306 }
4307
4308 return 0;
4309}
4310
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304311static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
4312 struct wireless_dev *wdev,
4313 const void *data,
4314 int data_len)
4315{
4316 int ret = 0;
4317
4318 vos_ssr_protect(__func__);
4319 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
4320 vos_ssr_unprotect(__func__);
4321
4322 return ret;
4323}
4324
4325static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304326 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304327 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304328 int data_len)
4329{
4330 u8 peer[6] = {0};
4331 struct net_device *dev = wdev->netdev;
4332 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4333 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4334 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4335 eHalStatus ret;
4336 tANI_S32 state;
4337 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304338 tANI_S32 global_operating_class = 0;
4339 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304340 struct sk_buff *skb = NULL;
4341
4342 ret = wlan_hdd_validate_context(pHddCtx);
4343 if (0 != ret) {
4344
4345 return -EINVAL;
4346 }
4347 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4348
4349 return -ENOTSUPP;
4350 }
4351 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4352 data, data_len,
4353 wlan_hdd_tdls_config_get_status_policy)) {
4354 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4355 return -EINVAL;
4356 }
4357
4358 /* Parse and fetch mac address */
4359 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4360 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4361 return -EINVAL;
4362 }
4363
4364 memcpy(peer, nla_data(
4365 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4366 sizeof(peer));
4367 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4368
4369 ret = wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
4370
4371 if (0 != ret) {
4372 hddLog(VOS_TRACE_LEVEL_ERROR,
4373 FL("get status Failed"));
4374 return -EINVAL;
4375 }
4376 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304377 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304378 NLMSG_HDRLEN);
4379
4380 if (!skb) {
4381 hddLog(VOS_TRACE_LEVEL_ERROR,
4382 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4383 return -EINVAL;
4384 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304385 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 +05304386 reason,
4387 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304388 global_operating_class,
4389 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304390 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304391 if (nla_put_s32(skb,
4392 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4393 state) ||
4394 nla_put_s32(skb,
4395 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4396 reason) ||
4397 nla_put_s32(skb,
4398 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4399 global_operating_class) ||
4400 nla_put_s32(skb,
4401 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4402 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304403
4404 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4405 goto nla_put_failure;
4406 }
4407
4408 return cfg80211_vendor_cmd_reply(skb);
4409
4410nla_put_failure:
4411 kfree_skb(skb);
4412 return -EINVAL;
4413}
4414
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304415static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4416 struct wireless_dev *wdev,
4417 const void *data,
4418 int data_len)
4419{
4420 int ret = 0;
4421
4422 vos_ssr_protect(__func__);
4423 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
4424 vos_ssr_unprotect(__func__);
4425
4426 return ret;
4427}
4428
Atul Mittal115287b2014-07-08 13:26:33 +05304429static int wlan_hdd_cfg80211_exttdls_callback(tANI_U8* mac,
4430 tANI_S32 state,
4431 tANI_S32 reason,
4432 void *ctx)
4433{
4434 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
4435 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4436 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304437 tANI_S32 global_operating_class = 0;
4438 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304439
4440 if (wlan_hdd_validate_context(pHddCtx)) {
4441 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "));
4442 return -EINVAL;
4443 }
4444
4445 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4446
4447 return -ENOTSUPP;
4448 }
4449 skb = cfg80211_vendor_event_alloc(
4450 pHddCtx->wiphy,
4451 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4452 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4453 GFP_KERNEL);
4454
4455 if (!skb) {
4456 hddLog(VOS_TRACE_LEVEL_ERROR,
4457 FL("cfg80211_vendor_event_alloc failed"));
4458 return -EINVAL;
4459 }
4460 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304461 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4462 reason,
4463 state,
4464 global_operating_class,
4465 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304466 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4467 MAC_ADDR_ARRAY(mac));
4468
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304469 if (nla_put(skb,
4470 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4471 VOS_MAC_ADDR_SIZE, mac) ||
4472 nla_put_s32(skb,
4473 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4474 state) ||
4475 nla_put_s32(skb,
4476 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4477 reason) ||
4478 nla_put_s32(skb,
4479 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4480 channel) ||
4481 nla_put_s32(skb,
4482 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4483 global_operating_class)
4484 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304485 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4486 goto nla_put_failure;
4487 }
4488
4489 cfg80211_vendor_event(skb, GFP_KERNEL);
4490 return (0);
4491
4492nla_put_failure:
4493 kfree_skb(skb);
4494 return -EINVAL;
4495}
4496
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304497static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304498 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304499 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304500 int data_len)
4501{
4502 u8 peer[6] = {0};
4503 struct net_device *dev = wdev->netdev;
4504 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4505 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4506 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4507 eHalStatus status;
4508 tdls_req_params_t pReqMsg = {0};
4509
4510 status = wlan_hdd_validate_context(pHddCtx);
4511 if (0 != status) {
4512 hddLog(VOS_TRACE_LEVEL_ERROR,
4513 FL("HDD context is not valid"));
4514 return -EINVAL;
4515 }
4516 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4517
4518 return -ENOTSUPP;
4519 }
4520 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4521 data, data_len,
4522 wlan_hdd_tdls_config_enable_policy)) {
4523 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4524 return -EINVAL;
4525 }
4526
4527 /* Parse and fetch mac address */
4528 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4529 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4530 return -EINVAL;
4531 }
4532
4533 memcpy(peer, nla_data(
4534 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4535 sizeof(peer));
4536 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4537
4538 /* Parse and fetch channel */
4539 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4540 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4541 return -EINVAL;
4542 }
4543 pReqMsg.channel = nla_get_s32(
4544 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4545 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4546
4547 /* Parse and fetch global operating class */
4548 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4549 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4550 return -EINVAL;
4551 }
4552 pReqMsg.global_operating_class = nla_get_s32(
4553 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4554 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4555 pReqMsg.global_operating_class);
4556
4557 /* Parse and fetch latency ms */
4558 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4559 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4560 return -EINVAL;
4561 }
4562 pReqMsg.max_latency_ms = nla_get_s32(
4563 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4564 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4565 pReqMsg.max_latency_ms);
4566
4567 /* Parse and fetch required bandwidth kbps */
4568 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4569 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4570 return -EINVAL;
4571 }
4572
4573 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4574 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4575 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4576 pReqMsg.min_bandwidth_kbps);
4577
4578 return (wlan_hdd_tdls_extctrl_config_peer(pAdapter,
4579 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05304580 &pReqMsg,
Atul Mittal115287b2014-07-08 13:26:33 +05304581 wlan_hdd_cfg80211_exttdls_callback));
4582}
4583
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304584static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4585 struct wireless_dev *wdev,
4586 const void *data,
4587 int data_len)
4588{
4589 int ret = 0;
4590
4591 vos_ssr_protect(__func__);
4592 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
4593 vos_ssr_unprotect(__func__);
4594
4595 return ret;
4596}
4597
4598static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304599 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304600 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304601 int data_len)
4602{
4603 u8 peer[6] = {0};
4604 struct net_device *dev = wdev->netdev;
4605 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4606 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4607 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4608 eHalStatus status;
4609
4610 status = wlan_hdd_validate_context(pHddCtx);
4611 if (0 != status) {
4612 hddLog(VOS_TRACE_LEVEL_ERROR,
4613 FL("HDD context is not valid"));
4614 return -EINVAL;
4615 }
4616 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4617
4618 return -ENOTSUPP;
4619 }
4620 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4621 data, data_len,
4622 wlan_hdd_tdls_config_disable_policy)) {
4623 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4624 return -EINVAL;
4625 }
4626 /* Parse and fetch mac address */
4627 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4628 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4629 return -EINVAL;
4630 }
4631
4632 memcpy(peer, nla_data(
4633 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4634 sizeof(peer));
4635 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4636
4637 return (wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer));
4638}
4639
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304640static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4641 struct wireless_dev *wdev,
4642 const void *data,
4643 int data_len)
4644{
4645 int ret = 0;
4646
4647 vos_ssr_protect(__func__);
4648 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
4649 vos_ssr_unprotect(__func__);
4650
4651 return ret;
4652}
4653
Dasari Srinivas7875a302014-09-26 17:50:57 +05304654static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304655__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05304656 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304657 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05304658{
4659 struct net_device *dev = wdev->netdev;
4660 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4661 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4662 struct sk_buff *skb = NULL;
4663 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304664 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05304665
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304666
4667 ret = wlan_hdd_validate_context(pHddCtx);
4668 if (0 != ret)
4669 {
4670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4671 "%s: HDD context is not valid (%d)",__func__, ret);
4672 return ret;
4673 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05304674 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
4675 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
4676 fset |= WIFI_FEATURE_INFRA;
4677 }
4678
4679 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
4680 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
4681 fset |= WIFI_FEATURE_INFRA_5G;
4682 }
4683
4684#ifdef WLAN_FEATURE_P2P
4685 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
4686 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
4687 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
4688 fset |= WIFI_FEATURE_P2P;
4689 }
4690#endif
4691
4692 /* Soft-AP is supported currently by default */
4693 fset |= WIFI_FEATURE_SOFT_AP;
4694
4695#ifdef WLAN_FEATURE_EXTSCAN
4696 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
4697 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
4698 hddLog(LOG1, FL("EXTScan is supported by firmware"));
4699 fset |= WIFI_FEATURE_EXTSCAN;
4700 }
4701#endif
4702
4703#ifdef WLAN_FEATURE_NAN
4704 if (sme_IsFeatureSupportedByFW(NAN)) {
4705 hddLog(LOG1, FL("NAN is supported by firmware"));
4706 fset |= WIFI_FEATURE_NAN;
4707 }
4708#endif
4709
4710 /* D2D RTT is not supported currently by default */
4711 if (sme_IsFeatureSupportedByFW(RTT)) {
4712 hddLog(LOG1, FL("RTT is supported by firmware"));
4713 fset |= WIFI_FEATURE_D2AP_RTT;
4714 }
4715
4716#ifdef FEATURE_WLAN_BATCH_SCAN
4717 if (fset & WIFI_FEATURE_EXTSCAN) {
4718 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
4719 fset &= ~WIFI_FEATURE_BATCH_SCAN;
4720 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
4721 hddLog(LOG1, FL("Batch scan is supported by firmware"));
4722 fset |= WIFI_FEATURE_BATCH_SCAN;
4723 }
4724#endif
4725
4726#ifdef FEATURE_WLAN_SCAN_PNO
4727 if (pHddCtx->cfg_ini->configPNOScanSupport &&
4728 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
4729 hddLog(LOG1, FL("PNO is supported by firmware"));
4730 fset |= WIFI_FEATURE_PNO;
4731 }
4732#endif
4733
4734 /* STA+STA is supported currently by default */
4735 fset |= WIFI_FEATURE_ADDITIONAL_STA;
4736
4737#ifdef FEATURE_WLAN_TDLS
4738 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
4739 sme_IsFeatureSupportedByFW(TDLS)) {
4740 hddLog(LOG1, FL("TDLS is supported by firmware"));
4741 fset |= WIFI_FEATURE_TDLS;
4742 }
4743
4744 /* TDLS_OFFCHANNEL is not supported currently by default */
4745#endif
4746
4747#ifdef WLAN_AP_STA_CONCURRENCY
4748 /* AP+STA concurrency is supported currently by default */
4749 fset |= WIFI_FEATURE_AP_STA;
4750#endif
4751
4752 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
4753 NLMSG_HDRLEN);
4754
4755 if (!skb) {
4756 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4757 return -EINVAL;
4758 }
4759 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
4760
4761 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
4762 hddLog(LOGE, FL("nla put fail"));
4763 goto nla_put_failure;
4764 }
4765
4766 return cfg80211_vendor_cmd_reply(skb);
4767
4768nla_put_failure:
4769 kfree_skb(skb);
4770 return -EINVAL;
4771}
4772
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304773static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304774wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
4775 struct wireless_dev *wdev,
4776 const void *data, int data_len)
4777{
4778 int ret = 0;
4779
4780 vos_ssr_protect(__func__);
4781 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
4782 vos_ssr_unprotect(__func__);
4783
4784 return ret;
4785}
4786
4787static int
4788__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304789 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304790 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304791{
4792 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
4793 uint8_t i, feature_sets, max_feature_sets;
4794 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
4795 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304796 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4797 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304798
4799 ENTER();
4800
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304801 ret = wlan_hdd_validate_context(pHddCtx);
4802 if (0 != ret)
4803 {
4804 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4805 "%s: HDD context is not valid, ret = %d",__func__, ret);
4806 return ret;
4807 }
4808
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304809 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
4810 data, data_len, NULL)) {
4811 hddLog(LOGE, FL("Invalid ATTR"));
4812 return -EINVAL;
4813 }
4814
4815 /* Parse and fetch max feature set */
4816 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
4817 hddLog(LOGE, FL("Attr max feature set size failed"));
4818 return -EINVAL;
4819 }
4820 max_feature_sets = nla_get_u32(
4821 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
4822 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
4823
4824 /* Fill feature combination matrix */
4825 feature_sets = 0;
4826 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4827 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4828 WIFI_FEATURE_P2P;
4829
4830 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4831 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4832 WIFI_FEATURE_SOFT_AP;
4833
4834 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4835 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
4836 WIFI_FEATURE_SOFT_AP;
4837
4838 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4839 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4840 WIFI_FEATURE_SOFT_AP |
4841 WIFI_FEATURE_P2P;
4842
4843 /* Add more feature combinations here */
4844
4845 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
4846 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
4847 hddLog(LOG1, "Feature set matrix");
4848 for (i = 0; i < feature_sets; i++)
4849 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
4850
4851 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4852 sizeof(u32) * feature_sets +
4853 NLMSG_HDRLEN);
4854
4855 if (reply_skb) {
4856 if (nla_put_u32(reply_skb,
4857 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
4858 feature_sets) ||
4859 nla_put(reply_skb,
4860 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
4861 sizeof(u32) * feature_sets, feature_set_matrix)) {
4862 hddLog(LOGE, FL("nla put fail"));
4863 kfree_skb(reply_skb);
4864 return -EINVAL;
4865 }
4866
4867 return cfg80211_vendor_cmd_reply(reply_skb);
4868 }
4869 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
4870 return -ENOMEM;
4871
4872max_buffer_err:
4873 hddLog(LOGE, FL("Feature set max buffer size reached. feature_sets(%d) max(%d)"),
4874 feature_sets, WLAN_HDD_MAX_FEATURE_SET);
4875 return -EINVAL;
4876}
4877
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304878static int
4879wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
4880 struct wireless_dev *wdev,
4881 const void *data, int data_len)
4882{
4883 int ret = 0;
4884
4885 vos_ssr_protect(__func__);
4886 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
4887 data_len);
4888 vos_ssr_unprotect(__func__);
4889
4890 return ret;
4891}
4892
Agarwal Ashish738843c2014-09-25 12:27:56 +05304893static const struct nla_policy
4894wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
4895 +1] =
4896{
4897 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
4898};
4899
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304900static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05304901 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304902 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05304903 int data_len)
4904{
4905 struct net_device *dev = wdev->netdev;
4906 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4907 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4908 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4909 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
4910 eHalStatus status;
4911 u32 dfsFlag = 0;
4912
4913 status = wlan_hdd_validate_context(pHddCtx);
4914 if (0 != status) {
4915 hddLog(VOS_TRACE_LEVEL_ERROR,
4916 FL("HDD context is not valid"));
4917 return -EINVAL;
4918 }
4919 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
4920 data, data_len,
4921 wlan_hdd_set_no_dfs_flag_config_policy)) {
4922 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4923 return -EINVAL;
4924 }
4925
4926 /* Parse and fetch required bandwidth kbps */
4927 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
4928 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
4929 return -EINVAL;
4930 }
4931
4932 dfsFlag = nla_get_u32(
4933 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
4934 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
4935 dfsFlag);
4936
4937 pHddCtx->disable_dfs_flag = dfsFlag;
4938
4939 sme_disable_dfs_channel(hHal, dfsFlag);
4940 sme_FilterScanResults(hHal, pAdapter->sessionId);
4941 return 0;
4942}
Atul Mittal115287b2014-07-08 13:26:33 +05304943
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304944static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
4945 struct wireless_dev *wdev,
4946 const void *data,
4947 int data_len)
4948{
4949 int ret = 0;
4950
4951 vos_ssr_protect(__func__);
4952 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
4953 vos_ssr_unprotect(__func__);
4954
4955 return ret;
4956
4957}
4958
Mukul Sharma2a271632014-10-13 14:59:01 +05304959const struct
4960nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
4961{
4962 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
4963 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
4964};
4965
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304966static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05304967 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05304968{
4969
4970 u8 bssid[6] = {0};
4971 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4972 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
4973 eHalStatus status = eHAL_STATUS_SUCCESS;
4974 v_U32_t isFwrRoamEnabled = FALSE;
4975 int ret;
4976
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304977 ret = wlan_hdd_validate_context(pHddCtx);
4978 if (0 != ret) {
Mukul Sharma2a271632014-10-13 14:59:01 +05304979 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304980 FL("HDD context is not valid, ret = %d"), ret);
4981 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05304982 }
4983
4984 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
4985 data, data_len,
4986 qca_wlan_vendor_attr);
4987 if (ret){
4988 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4989 return -EINVAL;
4990 }
4991
4992 /* Parse and fetch Enable flag */
4993 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
4994 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
4995 return -EINVAL;
4996 }
4997
4998 isFwrRoamEnabled = nla_get_u32(
4999 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5000
5001 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5002
5003 /* Parse and fetch bssid */
5004 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5005 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5006 return -EINVAL;
5007 }
5008
5009 memcpy(bssid, nla_data(
5010 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5011 sizeof(bssid));
5012 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5013
5014 //Update roaming
5015 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
5016 return status;
5017}
5018
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305019static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5020 struct wireless_dev *wdev, const void *data, int data_len)
5021{
5022 int ret = 0;
5023
5024 vos_ssr_protect(__func__);
5025 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5026 vos_ssr_unprotect(__func__);
5027
5028 return ret;
5029}
5030
Sunil Duttc69bccb2014-05-26 21:30:20 +05305031const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
5032{
Mukul Sharma2a271632014-10-13 14:59:01 +05305033 {
5034 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5035 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
5036 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5037 WIPHY_VENDOR_CMD_NEED_NETDEV |
5038 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305039 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05305040 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305041#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5042 {
5043 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5044 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
5045 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5046 WIPHY_VENDOR_CMD_NEED_NETDEV |
5047 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305048 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05305049 },
5050
5051 {
5052 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5053 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
5054 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5055 WIPHY_VENDOR_CMD_NEED_NETDEV |
5056 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305057 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05305058 },
5059
5060 {
5061 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5062 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
5063 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5064 WIPHY_VENDOR_CMD_NEED_NETDEV |
5065 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305066 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05305067 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305068#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305069#ifdef WLAN_FEATURE_EXTSCAN
5070 {
5071 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5072 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
5073 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5074 WIPHY_VENDOR_CMD_NEED_NETDEV |
5075 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305076 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05305077 },
5078 {
5079 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5080 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
5081 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5082 WIPHY_VENDOR_CMD_NEED_NETDEV |
5083 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305084 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05305085 },
5086 {
5087 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5088 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
5089 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5090 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305091 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05305092 },
5093 {
5094 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5095 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
5096 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5097 WIPHY_VENDOR_CMD_NEED_NETDEV |
5098 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305099 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05305100 },
5101 {
5102 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5103 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
5104 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5105 WIPHY_VENDOR_CMD_NEED_NETDEV |
5106 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305107 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05305108 },
5109 {
5110 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5111 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
5112 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5113 WIPHY_VENDOR_CMD_NEED_NETDEV |
5114 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305115 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305116 },
5117 {
5118 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5119 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
5120 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5121 WIPHY_VENDOR_CMD_NEED_NETDEV |
5122 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305123 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305124 },
5125 {
5126 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5127 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
5128 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5129 WIPHY_VENDOR_CMD_NEED_NETDEV |
5130 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305131 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305132 },
5133 {
5134 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5135 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
5136 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5137 WIPHY_VENDOR_CMD_NEED_NETDEV |
5138 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305139 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305140 },
5141#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305142/*EXT TDLS*/
5143 {
5144 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5145 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
5146 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5147 WIPHY_VENDOR_CMD_NEED_NETDEV |
5148 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305149 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05305150 },
5151 {
5152 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5153 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
5154 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5155 WIPHY_VENDOR_CMD_NEED_NETDEV |
5156 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305157 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05305158 },
5159 {
5160 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5161 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
5162 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5163 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305164 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05305165 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05305166 {
5167 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5168 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
5169 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5170 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305171 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05305172 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05305173 {
5174 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5175 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
5176 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5177 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305178 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05305179 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305180 {
5181 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5182 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
5183 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5184 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305185 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305186 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305187 {
5188 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5189 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
5190 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5191 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305192 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305193 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305194};
5195
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005196/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05305197static const
5198struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005199{
5200#ifdef FEATURE_WLAN_CH_AVOID
5201 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05305202 .vendor_id = QCA_NL80211_VENDOR_ID,
5203 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005204 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305205#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
5206#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5207 {
5208 /* Index = 1*/
5209 .vendor_id = QCA_NL80211_VENDOR_ID,
5210 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
5211 },
5212 {
5213 /* Index = 2*/
5214 .vendor_id = QCA_NL80211_VENDOR_ID,
5215 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
5216 },
5217 {
5218 /* Index = 3*/
5219 .vendor_id = QCA_NL80211_VENDOR_ID,
5220 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
5221 },
5222 {
5223 /* Index = 4*/
5224 .vendor_id = QCA_NL80211_VENDOR_ID,
5225 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
5226 },
5227 {
5228 /* Index = 5*/
5229 .vendor_id = QCA_NL80211_VENDOR_ID,
5230 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
5231 },
5232 {
5233 /* Index = 6*/
5234 .vendor_id = QCA_NL80211_VENDOR_ID,
5235 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
5236 },
5237#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305238#ifdef WLAN_FEATURE_EXTSCAN
5239 {
5240 .vendor_id = QCA_NL80211_VENDOR_ID,
5241 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
5242 },
5243 {
5244 .vendor_id = QCA_NL80211_VENDOR_ID,
5245 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
5246 },
5247 {
5248 .vendor_id = QCA_NL80211_VENDOR_ID,
5249 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
5250 },
5251 {
5252 .vendor_id = QCA_NL80211_VENDOR_ID,
5253 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
5254 },
5255 {
5256 .vendor_id = QCA_NL80211_VENDOR_ID,
5257 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
5258 },
5259 {
5260 .vendor_id = QCA_NL80211_VENDOR_ID,
5261 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
5262 },
5263 {
5264 .vendor_id = QCA_NL80211_VENDOR_ID,
5265 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
5266 },
5267 {
5268 .vendor_id = QCA_NL80211_VENDOR_ID,
5269 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
5270 },
5271 {
5272 .vendor_id = QCA_NL80211_VENDOR_ID,
5273 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
5274 },
5275 {
5276 .vendor_id = QCA_NL80211_VENDOR_ID,
5277 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
5278 },
5279 {
5280 .vendor_id = QCA_NL80211_VENDOR_ID,
5281 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
5282 },
5283 {
5284 .vendor_id = QCA_NL80211_VENDOR_ID,
5285 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
5286 },
5287 {
5288 .vendor_id = QCA_NL80211_VENDOR_ID,
5289 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
5290 },
5291#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305292/*EXT TDLS*/
5293 {
5294 .vendor_id = QCA_NL80211_VENDOR_ID,
5295 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
5296 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005297};
5298
Jeff Johnson295189b2012-06-20 16:38:30 -07005299/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305300 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305301 * This function is called by hdd_wlan_startup()
5302 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305303 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07005304 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305305struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07005306{
5307 struct wiphy *wiphy;
5308 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305309 /*
5310 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07005311 */
5312 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
5313
5314 if (!wiphy)
5315 {
5316 /* Print error and jump into err label and free the memory */
5317 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
5318 return NULL;
5319 }
5320
Sunil Duttc69bccb2014-05-26 21:30:20 +05305321
Jeff Johnson295189b2012-06-20 16:38:30 -07005322 return wiphy;
5323}
5324
5325/*
5326 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305327 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07005328 * private ioctl to change the band value
5329 */
5330int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
5331{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305332 int i, j;
5333 eNVChannelEnabledType channelEnabledState;
5334
Jeff Johnsone7245742012-09-05 17:12:55 -07005335 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305336
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305337 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005338 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305339
5340 if (NULL == wiphy->bands[i])
5341 {
5342 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5343 __func__, i);
5344 continue;
5345 }
5346
5347 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5348 {
5349 struct ieee80211_supported_band *band = wiphy->bands[i];
5350
5351 channelEnabledState = vos_nv_getChannelEnabledState(
5352 band->channels[j].hw_value);
5353
5354 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
5355 {
Abhishek Singh678227a2014-11-04 10:52:38 +05305356 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305357 continue;
5358 }
5359 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
5360 {
5361 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5362 continue;
5363 }
5364
5365 if (NV_CHANNEL_DISABLE == channelEnabledState ||
5366 NV_CHANNEL_INVALID == channelEnabledState)
5367 {
5368 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5369 }
5370 else if (NV_CHANNEL_DFS == channelEnabledState)
5371 {
5372 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5373 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
5374 }
5375 else
5376 {
5377 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
5378 |IEEE80211_CHAN_RADAR);
5379 }
5380 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005381 }
5382 return 0;
5383}
5384/*
5385 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305386 * This function is called by hdd_wlan_startup()
5387 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005388 * This function is used to initialize and register wiphy structure.
5389 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305390int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005391 struct wiphy *wiphy,
5392 hdd_config_t *pCfg
5393 )
5394{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305395 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305396 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5397
Jeff Johnsone7245742012-09-05 17:12:55 -07005398 ENTER();
5399
Jeff Johnson295189b2012-06-20 16:38:30 -07005400 /* Now bind the underlying wlan device with wiphy */
5401 set_wiphy_dev(wiphy, dev);
5402
5403 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005404
Kiet Lam6c583332013-10-14 05:37:09 +05305405#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005406 /* the flag for the other case would be initialzed in
5407 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005408 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305409#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005410
Amar Singhalfddc28c2013-09-05 13:03:40 -07005411 /* This will disable updating of NL channels from passive to
5412 * active if a beacon is received on passive channel. */
5413 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07005414
Amar Singhalfddc28c2013-09-05 13:03:40 -07005415
Amar Singhala49cbc52013-10-08 18:37:44 -07005416
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005417#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005418 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5419 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5420 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005421 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05305422 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005423#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005424
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005425#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005426 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005427#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005428 || pCfg->isFastRoamIniFeatureEnabled
5429#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005430#ifdef FEATURE_WLAN_ESE
5431 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005432#endif
5433 )
5434 {
5435 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5436 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005437#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005438#ifdef FEATURE_WLAN_TDLS
5439 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5440 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5441#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305442#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305443 if (pCfg->configPNOScanSupport)
5444 {
5445 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5446 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5447 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5448 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5449 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305450#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005451
Amar Singhalfddc28c2013-09-05 13:03:40 -07005452#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005453 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5454 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005455 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005456 driver need to determine what to do with both
5457 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005458
5459 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005460#else
5461 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005462#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005463
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305464 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5465
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05305466 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005467
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305468 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5469
Jeff Johnson295189b2012-06-20 16:38:30 -07005470 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305471 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07005472 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07005473 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5474 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005475 | BIT(NL80211_IFTYPE_AP);
5476
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305477 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005478 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305479#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5480 if( pCfg->enableMCC )
5481 {
5482 /* Currently, supports up to two channels */
5483 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005484
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305485 if( !pCfg->allowMCCGODiffBI )
5486 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005487
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305488 }
5489 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5490 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005491#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305492 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005493
Jeff Johnson295189b2012-06-20 16:38:30 -07005494 /* Before registering we need to update the ht capabilitied based
5495 * on ini values*/
5496 if( !pCfg->ShortGI20MhzEnable )
5497 {
5498 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5499 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5500 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5501 }
5502
5503 if( !pCfg->ShortGI40MhzEnable )
5504 {
5505 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5506 }
5507
5508 if( !pCfg->nChannelBondingMode5GHz )
5509 {
5510 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5511 }
5512
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305513 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305514 if (true == hdd_is_5g_supported(pHddCtx))
5515 {
5516 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5517 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305518
5519 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5520 {
5521
5522 if (NULL == wiphy->bands[i])
5523 {
5524 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5525 __func__, i);
5526 continue;
5527 }
5528
5529 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5530 {
5531 struct ieee80211_supported_band *band = wiphy->bands[i];
5532
5533 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5534 {
5535 // Enable social channels for P2P
5536 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5537 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5538 else
5539 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5540 continue;
5541 }
5542 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5543 {
5544 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5545 continue;
5546 }
5547 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005548 }
5549 /*Initialise the supported cipher suite details*/
5550 wiphy->cipher_suites = hdd_cipher_suites;
5551 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5552
5553 /*signal strength in mBm (100*dBm) */
5554 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5555
5556#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305557 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005558#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005559
Sunil Duttc69bccb2014-05-26 21:30:20 +05305560 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
5561 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005562 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
5563 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
5564
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305565 EXIT();
5566 return 0;
5567}
5568
5569/* In this function we are registering wiphy. */
5570int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
5571{
5572 ENTER();
5573 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005574 if (0 > wiphy_register(wiphy))
5575 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305576 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07005577 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
5578 return -EIO;
5579 }
5580
5581 EXIT();
5582 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305583}
Jeff Johnson295189b2012-06-20 16:38:30 -07005584
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305585/* In this function we are updating channel list when,
5586 regulatory domain is FCC and country code is US.
5587 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
5588 As per FCC smart phone is not a indoor device.
5589 GO should not opeate on indoor channels */
5590void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
5591{
5592 int j;
5593 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5594 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
5595 //Default counrtycode from NV at the time of wiphy initialization.
5596 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
5597 &defaultCountryCode[0]))
5598 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005599 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305600 }
5601 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
5602 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305603 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
5604 {
5605 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
5606 return;
5607 }
5608 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
5609 {
5610 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
5611 // Mark UNII -1 band channel as passive
5612 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
5613 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
5614 }
5615 }
5616}
5617
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305618/* This function registers for all frame which supplicant is interested in */
5619void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005620{
Jeff Johnson295189b2012-06-20 16:38:30 -07005621 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5622 /* Register for all P2P action, public action etc frames */
5623 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5624
Jeff Johnsone7245742012-09-05 17:12:55 -07005625 ENTER();
5626
Jeff Johnson295189b2012-06-20 16:38:30 -07005627 /* Right now we are registering these frame when driver is getting
5628 initialized. Once we will move to 2.6.37 kernel, in which we have
5629 frame register ops, we will move this code as a part of that */
5630 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305631 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07005632 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5633
5634 /* GAS Initial Response */
5635 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5636 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305637
Jeff Johnson295189b2012-06-20 16:38:30 -07005638 /* GAS Comeback Request */
5639 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5640 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5641
5642 /* GAS Comeback Response */
5643 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5644 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5645
5646 /* P2P Public Action */
5647 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305648 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005649 P2P_PUBLIC_ACTION_FRAME_SIZE );
5650
5651 /* P2P Action */
5652 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5653 (v_U8_t*)P2P_ACTION_FRAME,
5654 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07005655
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05305656 /* WNM BSS Transition Request frame */
5657 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5658 (v_U8_t*)WNM_BSS_ACTION_FRAME,
5659 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005660
5661 /* WNM-Notification */
5662 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5663 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5664 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005665}
5666
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305667void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005668{
Jeff Johnson295189b2012-06-20 16:38:30 -07005669 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5670 /* Register for all P2P action, public action etc frames */
5671 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5672
Jeff Johnsone7245742012-09-05 17:12:55 -07005673 ENTER();
5674
Jeff Johnson295189b2012-06-20 16:38:30 -07005675 /* Right now we are registering these frame when driver is getting
5676 initialized. Once we will move to 2.6.37 kernel, in which we have
5677 frame register ops, we will move this code as a part of that */
5678 /* GAS Initial Request */
5679
5680 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5681 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5682
5683 /* GAS Initial Response */
5684 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5685 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305686
Jeff Johnson295189b2012-06-20 16:38:30 -07005687 /* GAS Comeback Request */
5688 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5689 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5690
5691 /* GAS Comeback Response */
5692 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5693 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5694
5695 /* P2P Public Action */
5696 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305697 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005698 P2P_PUBLIC_ACTION_FRAME_SIZE );
5699
5700 /* P2P Action */
5701 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5702 (v_U8_t*)P2P_ACTION_FRAME,
5703 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005704 /* WNM-Notification */
5705 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5706 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5707 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005708}
5709
5710#ifdef FEATURE_WLAN_WAPI
5711void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
5712 const u8 *mac_addr, u8 *key , int key_Len)
5713{
5714 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5715 tCsrRoamSetKey setKey;
5716 v_BOOL_t isConnected = TRUE;
5717 int status = 0;
5718 v_U32_t roamId= 0xFF;
5719 tANI_U8 *pKeyPtr = NULL;
5720 int n = 0;
5721
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305722 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
5723 __func__, hdd_device_modetoString(pAdapter->device_mode),
5724 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005725
Gopichand Nakkalae7480202013-02-11 15:24:22 +05305726 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005727 setKey.keyId = key_index; // Store Key ID
5728 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
5729 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
5730 setKey.paeRole = 0 ; // the PAE role
5731 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
5732 {
5733 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
5734 }
5735 else
5736 {
5737 isConnected = hdd_connIsConnected(pHddStaCtx);
5738 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
5739 }
5740 setKey.keyLength = key_Len;
5741 pKeyPtr = setKey.Key;
5742 memcpy( pKeyPtr, key, key_Len);
5743
Arif Hussain6d2a3322013-11-17 19:50:10 -08005744 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005745 __func__, key_Len);
5746 for (n = 0 ; n < key_Len; n++)
5747 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
5748 __func__,n,setKey.Key[n]);
5749
5750 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
5751 if ( isConnected )
5752 {
5753 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
5754 pAdapter->sessionId, &setKey, &roamId );
5755 }
5756 if ( status != 0 )
5757 {
5758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5759 "[%4d] sme_RoamSetKey returned ERROR status= %d",
5760 __LINE__, status );
5761 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
5762 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05305763 /* Need to clear any trace of key value in the memory.
5764 * Thus zero out the memory even though it is local
5765 * variable.
5766 */
5767 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005768}
5769#endif /* FEATURE_WLAN_WAPI*/
5770
5771#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305772int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005773 beacon_data_t **ppBeacon,
5774 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005775#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305776int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005777 beacon_data_t **ppBeacon,
5778 struct cfg80211_beacon_data *params,
5779 int dtim_period)
5780#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305781{
Jeff Johnson295189b2012-06-20 16:38:30 -07005782 int size;
5783 beacon_data_t *beacon = NULL;
5784 beacon_data_t *old = NULL;
5785 int head_len,tail_len;
5786
Jeff Johnsone7245742012-09-05 17:12:55 -07005787 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005788 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305789 {
5790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5791 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005792 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305793 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005794
5795 old = pAdapter->sessionCtx.ap.beacon;
5796
5797 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305798 {
5799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5800 FL("session(%d) old and new heads points to NULL"),
5801 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005802 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305803 }
5804
5805 if (params->tail && !params->tail_len)
5806 {
5807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5808 FL("tail_len is zero but tail is not NULL"));
5809 return -EINVAL;
5810 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005811
Jeff Johnson295189b2012-06-20 16:38:30 -07005812#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
5813 /* Kernel 3.0 is not updating dtim_period for set beacon */
5814 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305815 {
5816 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5817 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005818 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305819 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005820#endif
5821
5822 if(params->head)
5823 head_len = params->head_len;
5824 else
5825 head_len = old->head_len;
5826
5827 if(params->tail || !old)
5828 tail_len = params->tail_len;
5829 else
5830 tail_len = old->tail_len;
5831
5832 size = sizeof(beacon_data_t) + head_len + tail_len;
5833
5834 beacon = kzalloc(size, GFP_KERNEL);
5835
5836 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305837 {
5838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5839 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005840 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305841 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005842
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005843#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005844 if(params->dtim_period || !old )
5845 beacon->dtim_period = params->dtim_period;
5846 else
5847 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005848#else
5849 if(dtim_period || !old )
5850 beacon->dtim_period = dtim_period;
5851 else
5852 beacon->dtim_period = old->dtim_period;
5853#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305854
Jeff Johnson295189b2012-06-20 16:38:30 -07005855 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
5856 beacon->tail = beacon->head + head_len;
5857 beacon->head_len = head_len;
5858 beacon->tail_len = tail_len;
5859
5860 if(params->head) {
5861 memcpy (beacon->head,params->head,beacon->head_len);
5862 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305863 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07005864 if(old)
5865 memcpy (beacon->head,old->head,beacon->head_len);
5866 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305867
Jeff Johnson295189b2012-06-20 16:38:30 -07005868 if(params->tail) {
5869 memcpy (beacon->tail,params->tail,beacon->tail_len);
5870 }
5871 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305872 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07005873 memcpy (beacon->tail,old->tail,beacon->tail_len);
5874 }
5875
5876 *ppBeacon = beacon;
5877
5878 kfree(old);
5879
5880 return 0;
5881
5882}
Jeff Johnson295189b2012-06-20 16:38:30 -07005883
5884v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
5885{
5886 int left = length;
5887 v_U8_t *ptr = pIes;
5888 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305889
Jeff Johnson295189b2012-06-20 16:38:30 -07005890 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305891 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005892 elem_id = ptr[0];
5893 elem_len = ptr[1];
5894 left -= 2;
5895 if(elem_len > left)
5896 {
5897 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005898 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005899 eid,elem_len,left);
5900 return NULL;
5901 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305902 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005903 {
5904 return ptr;
5905 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305906
Jeff Johnson295189b2012-06-20 16:38:30 -07005907 left -= elem_len;
5908 ptr += (elem_len + 2);
5909 }
5910 return NULL;
5911}
5912
Jeff Johnson295189b2012-06-20 16:38:30 -07005913/* Check if rate is 11g rate or not */
5914static int wlan_hdd_rate_is_11g(u8 rate)
5915{
Sanjay Devnani28322e22013-06-21 16:13:40 -07005916 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005917 u8 i;
5918 for (i = 0; i < 8; i++)
5919 {
5920 if(rate == gRateArray[i])
5921 return TRUE;
5922 }
5923 return FALSE;
5924}
5925
5926/* Check for 11g rate and set proper 11g only mode */
5927static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
5928 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
5929{
5930 u8 i, num_rates = pIe[0];
5931
5932 pIe += 1;
5933 for ( i = 0; i < num_rates; i++)
5934 {
5935 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
5936 {
5937 /* If rate set have 11g rate than change the mode to 11G */
5938 *pSapHw_mode = eSAP_DOT11_MODE_11g;
5939 if (pIe[i] & BASIC_RATE_MASK)
5940 {
5941 /* If we have 11g rate as basic rate, it means mode
5942 is 11g only mode.
5943 */
5944 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
5945 *pCheckRatesfor11g = FALSE;
5946 }
5947 }
5948 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
5949 {
5950 *require_ht = TRUE;
5951 }
5952 }
5953 return;
5954}
5955
5956static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
5957{
5958 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5959 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5960 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5961 u8 checkRatesfor11g = TRUE;
5962 u8 require_ht = FALSE;
5963 u8 *pIe=NULL;
5964
5965 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
5966
5967 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
5968 pBeacon->head_len, WLAN_EID_SUPP_RATES);
5969 if (pIe != NULL)
5970 {
5971 pIe += 1;
5972 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5973 &pConfig->SapHw_mode);
5974 }
5975
5976 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5977 WLAN_EID_EXT_SUPP_RATES);
5978 if (pIe != NULL)
5979 {
5980
5981 pIe += 1;
5982 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5983 &pConfig->SapHw_mode);
5984 }
5985
5986 if( pConfig->channel > 14 )
5987 {
5988 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
5989 }
5990
5991 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5992 WLAN_EID_HT_CAPABILITY);
5993
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305994 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005995 {
5996 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
5997 if(require_ht)
5998 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
5999 }
6000}
6001
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306002static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
6003 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
6004{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006005 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306006 v_U8_t *pIe = NULL;
6007 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6008
6009 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6010 pBeacon->tail, pBeacon->tail_len);
6011
6012 if (pIe)
6013 {
6014 ielen = pIe[1] + 2;
6015 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6016 {
6017 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
6018 }
6019 else
6020 {
6021 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
6022 return -EINVAL;
6023 }
6024 *total_ielen += ielen;
6025 }
6026 return 0;
6027}
6028
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006029static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
6030 v_U8_t *genie, v_U8_t *total_ielen)
6031{
6032 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6033 int left = pBeacon->tail_len;
6034 v_U8_t *ptr = pBeacon->tail;
6035 v_U8_t elem_id, elem_len;
6036 v_U16_t ielen = 0;
6037
6038 if ( NULL == ptr || 0 == left )
6039 return;
6040
6041 while (left >= 2)
6042 {
6043 elem_id = ptr[0];
6044 elem_len = ptr[1];
6045 left -= 2;
6046 if (elem_len > left)
6047 {
6048 hddLog( VOS_TRACE_LEVEL_ERROR,
6049 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
6050 elem_id, elem_len, left);
6051 return;
6052 }
6053 if (IE_EID_VENDOR == elem_id)
6054 {
6055 /* skipping the VSIE's which we don't want to include or
6056 * it will be included by existing code
6057 */
6058 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
6059#ifdef WLAN_FEATURE_WFD
6060 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
6061#endif
6062 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6063 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6064 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
6065 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6066 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
6067 {
6068 ielen = ptr[1] + 2;
6069 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6070 {
6071 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
6072 *total_ielen += ielen;
6073 }
6074 else
6075 {
6076 hddLog( VOS_TRACE_LEVEL_ERROR,
6077 "IE Length is too big "
6078 "IEs eid=%d elem_len=%d total_ie_lent=%d",
6079 elem_id, elem_len, *total_ielen);
6080 }
6081 }
6082 }
6083
6084 left -= elem_len;
6085 ptr += (elem_len + 2);
6086 }
6087 return;
6088}
6089
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006090#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006091static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6092 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006093#else
6094static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6095 struct cfg80211_beacon_data *params)
6096#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006097{
6098 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306099 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006100 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07006101 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006102
6103 genie = vos_mem_malloc(MAX_GENIE_LEN);
6104
6105 if(genie == NULL) {
6106
6107 return -ENOMEM;
6108 }
6109
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306110 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6111 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006112 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306113 hddLog(LOGE,
6114 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306115 ret = -EINVAL;
6116 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006117 }
6118
6119#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306120 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6121 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
6122 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306123 hddLog(LOGE,
6124 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306125 ret = -EINVAL;
6126 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006127 }
6128#endif
6129
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306130 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6131 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006132 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306133 hddLog(LOGE,
6134 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306135 ret = -EINVAL;
6136 goto done;
6137 }
6138
6139 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
6140 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006141 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07006142 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006143
6144 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6145 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
6146 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6147 {
6148 hddLog(LOGE,
6149 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006150 ret = -EINVAL;
6151 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006152 }
6153
6154 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6155 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6156 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6157 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6158 ==eHAL_STATUS_FAILURE)
6159 {
6160 hddLog(LOGE,
6161 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006162 ret = -EINVAL;
6163 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006164 }
6165
6166 // Added for ProResp IE
6167 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
6168 {
6169 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
6170 u8 probe_rsp_ie_len[3] = {0};
6171 u8 counter = 0;
6172 /* Check Probe Resp Length if it is greater then 255 then Store
6173 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
6174 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
6175 Store More then 255 bytes into One Variable.
6176 */
6177 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6178 {
6179 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6180 {
6181 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6182 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6183 }
6184 else
6185 {
6186 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6187 rem_probe_resp_ie_len = 0;
6188 }
6189 }
6190
6191 rem_probe_resp_ie_len = 0;
6192
6193 if (probe_rsp_ie_len[0] > 0)
6194 {
6195 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6196 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6197 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6198 probe_rsp_ie_len[0], NULL,
6199 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6200 {
6201 hddLog(LOGE,
6202 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006203 ret = -EINVAL;
6204 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006205 }
6206 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6207 }
6208
6209 if (probe_rsp_ie_len[1] > 0)
6210 {
6211 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6212 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6213 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6214 probe_rsp_ie_len[1], NULL,
6215 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6216 {
6217 hddLog(LOGE,
6218 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006219 ret = -EINVAL;
6220 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006221 }
6222 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6223 }
6224
6225 if (probe_rsp_ie_len[2] > 0)
6226 {
6227 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6228 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6229 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6230 probe_rsp_ie_len[2], NULL,
6231 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6232 {
6233 hddLog(LOGE,
6234 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006235 ret = -EINVAL;
6236 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006237 }
6238 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6239 }
6240
6241 if (probe_rsp_ie_len[1] == 0 )
6242 {
6243 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6244 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6245 eANI_BOOLEAN_FALSE) )
6246 {
6247 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006248 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006249 }
6250 }
6251
6252 if (probe_rsp_ie_len[2] == 0 )
6253 {
6254 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6255 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6256 eANI_BOOLEAN_FALSE) )
6257 {
6258 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006259 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006260 }
6261 }
6262
6263 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6264 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6265 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6266 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6267 == eHAL_STATUS_FAILURE)
6268 {
6269 hddLog(LOGE,
6270 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006271 ret = -EINVAL;
6272 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006273 }
6274 }
6275 else
6276 {
6277 // Reset WNI_CFG_PROBE_RSP Flags
6278 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
6279
6280 hddLog(VOS_TRACE_LEVEL_INFO,
6281 "%s: No Probe Response IE received in set beacon",
6282 __func__);
6283 }
6284
6285 // Added for AssocResp IE
6286 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
6287 {
6288 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6289 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
6290 params->assocresp_ies_len, NULL,
6291 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6292 {
6293 hddLog(LOGE,
6294 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006295 ret = -EINVAL;
6296 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006297 }
6298
6299 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6300 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
6301 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6302 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6303 == eHAL_STATUS_FAILURE)
6304 {
6305 hddLog(LOGE,
6306 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006307 ret = -EINVAL;
6308 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006309 }
6310 }
6311 else
6312 {
6313 hddLog(VOS_TRACE_LEVEL_INFO,
6314 "%s: No Assoc Response IE received in set beacon",
6315 __func__);
6316
6317 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6318 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6319 eANI_BOOLEAN_FALSE) )
6320 {
6321 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006322 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006323 }
6324 }
6325
Jeff Johnsone7245742012-09-05 17:12:55 -07006326done:
Jeff Johnson295189b2012-06-20 16:38:30 -07006327 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306328 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006329}
Jeff Johnson295189b2012-06-20 16:38:30 -07006330
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306331/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006332 * FUNCTION: wlan_hdd_validate_operation_channel
6333 * called by wlan_hdd_cfg80211_start_bss() and
6334 * wlan_hdd_cfg80211_set_channel()
6335 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306336 * channel list.
6337 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006338VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006339{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306340
Jeff Johnson295189b2012-06-20 16:38:30 -07006341 v_U32_t num_ch = 0;
6342 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6343 u32 indx = 0;
6344 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306345 v_U8_t fValidChannel = FALSE, count = 0;
6346 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306347
Jeff Johnson295189b2012-06-20 16:38:30 -07006348 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6349
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306350 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006351 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306352 /* Validate the channel */
6353 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006354 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306355 if ( channel == rfChannels[count].channelNum )
6356 {
6357 fValidChannel = TRUE;
6358 break;
6359 }
6360 }
6361 if (fValidChannel != TRUE)
6362 {
6363 hddLog(VOS_TRACE_LEVEL_ERROR,
6364 "%s: Invalid Channel [%d]", __func__, channel);
6365 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006366 }
6367 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306368 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006369 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306370 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6371 valid_ch, &num_ch))
6372 {
6373 hddLog(VOS_TRACE_LEVEL_ERROR,
6374 "%s: failed to get valid channel list", __func__);
6375 return VOS_STATUS_E_FAILURE;
6376 }
6377 for (indx = 0; indx < num_ch; indx++)
6378 {
6379 if (channel == valid_ch[indx])
6380 {
6381 break;
6382 }
6383 }
6384
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306385 if (indx >= num_ch)
6386 {
6387 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6388 {
6389 eCsrBand band;
6390 unsigned int freq;
6391
6392 sme_GetFreqBand(hHal, &band);
6393
6394 if (eCSR_BAND_5G == band)
6395 {
6396#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6397 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6398 {
6399 freq = ieee80211_channel_to_frequency(channel,
6400 IEEE80211_BAND_2GHZ);
6401 }
6402 else
6403 {
6404 freq = ieee80211_channel_to_frequency(channel,
6405 IEEE80211_BAND_5GHZ);
6406 }
6407#else
6408 freq = ieee80211_channel_to_frequency(channel);
6409#endif
6410 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6411 return VOS_STATUS_SUCCESS;
6412 }
6413 }
6414
6415 hddLog(VOS_TRACE_LEVEL_ERROR,
6416 "%s: Invalid Channel [%d]", __func__, channel);
6417 return VOS_STATUS_E_FAILURE;
6418 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006419 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306420
Jeff Johnson295189b2012-06-20 16:38:30 -07006421 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306422
Jeff Johnson295189b2012-06-20 16:38:30 -07006423}
6424
Viral Modi3a32cc52013-02-08 11:14:52 -08006425/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306426 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08006427 * This function is used to set the channel number
6428 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306429static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08006430 struct ieee80211_channel *chan,
6431 enum nl80211_channel_type channel_type
6432 )
6433{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306434 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006435 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006436 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006437 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306438 hdd_context_t *pHddCtx;
6439 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006440
6441 ENTER();
6442
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306443
Viral Modi3a32cc52013-02-08 11:14:52 -08006444 if( NULL == dev )
6445 {
6446 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006447 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006448 return -ENODEV;
6449 }
6450 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306451
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306452 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6453 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6454 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006455 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306456 "%s: device_mode = %s (%d) freq = %d", __func__,
6457 hdd_device_modetoString(pAdapter->device_mode),
6458 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306459
6460 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6461 status = wlan_hdd_validate_context(pHddCtx);
6462
6463 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006464 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6466 "%s: HDD context is not valid", __func__);
6467 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006468 }
6469
6470 /*
6471 * Do freq to chan conversion
6472 * TODO: for 11a
6473 */
6474
6475 channel = ieee80211_frequency_to_channel(freq);
6476
6477 /* Check freq range */
6478 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6479 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6480 {
6481 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006482 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006483 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6484 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6485 return -EINVAL;
6486 }
6487
6488 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6489
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306490 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6491 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006492 {
6493 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6494 {
6495 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006496 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006497 return -EINVAL;
6498 }
6499 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6500 "%s: set channel to [%d] for device mode =%d",
6501 __func__, channel,pAdapter->device_mode);
6502 }
6503 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006504 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006505 )
6506 {
6507 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6508 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6509 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6510
6511 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6512 {
6513 /* Link is up then return cant set channel*/
6514 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006515 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006516 return -EINVAL;
6517 }
6518
6519 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6520 pHddStaCtx->conn_info.operationChannel = channel;
6521 pRoamProfile->ChannelInfo.ChannelList =
6522 &pHddStaCtx->conn_info.operationChannel;
6523 }
6524 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006525 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006526 )
6527 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306528 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6529 {
6530 if(VOS_STATUS_SUCCESS !=
6531 wlan_hdd_validate_operation_channel(pAdapter,channel))
6532 {
6533 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006534 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306535 return -EINVAL;
6536 }
6537 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6538 }
6539 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006540 {
6541 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6542
6543 /* If auto channel selection is configured as enable/ 1 then ignore
6544 channel set by supplicant
6545 */
6546 if ( cfg_param->apAutoChannelSelection )
6547 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306548 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6549 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006550 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306551 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6552 __func__, hdd_device_modetoString(pAdapter->device_mode),
6553 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006554 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306555 else
6556 {
6557 if(VOS_STATUS_SUCCESS !=
6558 wlan_hdd_validate_operation_channel(pAdapter,channel))
6559 {
6560 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006561 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306562 return -EINVAL;
6563 }
6564 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6565 }
Viral Modi3a32cc52013-02-08 11:14:52 -08006566 }
6567 }
6568 else
6569 {
6570 hddLog(VOS_TRACE_LEVEL_FATAL,
6571 "%s: Invalid device mode failed to set valid channel", __func__);
6572 return -EINVAL;
6573 }
6574 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306575 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006576}
6577
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306578static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
6579 struct net_device *dev,
6580 struct ieee80211_channel *chan,
6581 enum nl80211_channel_type channel_type
6582 )
6583{
6584 int ret;
6585
6586 vos_ssr_protect(__func__);
6587 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
6588 vos_ssr_unprotect(__func__);
6589
6590 return ret;
6591}
6592
Jeff Johnson295189b2012-06-20 16:38:30 -07006593#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6594static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6595 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006596#else
6597static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6598 struct cfg80211_beacon_data *params,
6599 const u8 *ssid, size_t ssid_len,
6600 enum nl80211_hidden_ssid hidden_ssid)
6601#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006602{
6603 tsap_Config_t *pConfig;
6604 beacon_data_t *pBeacon = NULL;
6605 struct ieee80211_mgmt *pMgmt_frame;
6606 v_U8_t *pIe=NULL;
6607 v_U16_t capab_info;
6608 eCsrAuthType RSNAuthType;
6609 eCsrEncryptionType RSNEncryptType;
6610 eCsrEncryptionType mcRSNEncryptType;
6611 int status = VOS_STATUS_SUCCESS;
6612 tpWLAN_SAPEventCB pSapEventCallback;
6613 hdd_hostapd_state_t *pHostapdState;
6614 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
6615 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306616 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006617 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306618 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07006619 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08006620 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05306621 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07006622 v_BOOL_t MFPCapable = VOS_FALSE;
6623 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05306624 v_BOOL_t sapEnable11AC =
6625 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07006626 ENTER();
6627
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306628 iniConfig = pHddCtx->cfg_ini;
6629
Jeff Johnson295189b2012-06-20 16:38:30 -07006630 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
6631
6632 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6633
6634 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6635
6636 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6637
6638 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
6639
6640 //channel is already set in the set_channel Call back
6641 //pConfig->channel = pCommitConfig->channel;
6642
6643 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306644 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07006645 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
6646
6647 pConfig->dtim_period = pBeacon->dtim_period;
6648
Arif Hussain6d2a3322013-11-17 19:50:10 -08006649 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07006650 pConfig->dtim_period);
6651
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08006652 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07006653 {
6654 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006655 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05306656 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
6657 {
6658 tANI_BOOLEAN restartNeeded;
6659 pConfig->ieee80211d = 1;
6660 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
6661 sme_setRegInfo(hHal, pConfig->countryCode);
6662 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
6663 }
6664 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006665 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07006666 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07006667 pConfig->ieee80211d = 1;
6668 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
6669 sme_setRegInfo(hHal, pConfig->countryCode);
6670 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07006671 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006672 else
6673 {
6674 pConfig->ieee80211d = 0;
6675 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306676 /*
6677 * If auto channel is configured i.e. channel is 0,
6678 * so skip channel validation.
6679 */
6680 if( AUTO_CHANNEL_SELECT != pConfig->channel )
6681 {
6682 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
6683 {
6684 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006685 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306686 return -EINVAL;
6687 }
6688 }
6689 else
6690 {
6691 if(1 != pHddCtx->is_dynamic_channel_range_set)
6692 {
6693 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
6694 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
6695 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
6696 }
6697 pHddCtx->is_dynamic_channel_range_set = 0;
6698 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006699 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006700 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006701 {
6702 pConfig->ieee80211d = 0;
6703 }
6704 pConfig->authType = eSAP_AUTO_SWITCH;
6705
6706 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306707
6708 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07006709 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
6710
6711 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
6712
6713 /*Set wps station to configured*/
6714 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
6715
6716 if(pIe)
6717 {
6718 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
6719 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006720 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07006721 return -EINVAL;
6722 }
6723 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
6724 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006725 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07006726 /* Check 15 bit of WPS IE as it contain information for wps state
6727 * WPS state
6728 */
6729 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
6730 {
6731 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
6732 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
6733 {
6734 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
6735 }
6736 }
6737 }
6738 else
6739 {
6740 pConfig->wps_state = SAP_WPS_DISABLED;
6741 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306742 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07006743
c_hpothufe599e92014-06-16 11:38:55 +05306744 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6745 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6746 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
6747 eCSR_ENCRYPT_TYPE_NONE;
6748
Jeff Johnson295189b2012-06-20 16:38:30 -07006749 pConfig->RSNWPAReqIELength = 0;
6750 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306751 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006752 WLAN_EID_RSN);
6753 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306754 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006755 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6756 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6757 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306758 /* The actual processing may eventually be more extensive than
6759 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07006760 * by the app.
6761 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306762 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006763 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6764 &RSNEncryptType,
6765 &mcRSNEncryptType,
6766 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006767 &MFPCapable,
6768 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006769 pConfig->pRSNWPAReqIE[1]+2,
6770 pConfig->pRSNWPAReqIE );
6771
6772 if( VOS_STATUS_SUCCESS == status )
6773 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306774 /* Now copy over all the security attributes you have
6775 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006776 * */
6777 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6778 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6779 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6780 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306781 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006782 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006783 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6784 }
6785 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306786
Jeff Johnson295189b2012-06-20 16:38:30 -07006787 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6788 pBeacon->tail, pBeacon->tail_len);
6789
6790 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
6791 {
6792 if (pConfig->pRSNWPAReqIE)
6793 {
6794 /*Mixed mode WPA/WPA2*/
6795 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
6796 pConfig->RSNWPAReqIELength += pIe[1] + 2;
6797 }
6798 else
6799 {
6800 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6801 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6802 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306803 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006804 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6805 &RSNEncryptType,
6806 &mcRSNEncryptType,
6807 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006808 &MFPCapable,
6809 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006810 pConfig->pRSNWPAReqIE[1]+2,
6811 pConfig->pRSNWPAReqIE );
6812
6813 if( VOS_STATUS_SUCCESS == status )
6814 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306815 /* Now copy over all the security attributes you have
6816 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006817 * */
6818 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6819 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6820 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6821 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306822 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006823 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006824 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6825 }
6826 }
6827 }
6828
Jeff Johnson4416a782013-03-25 14:17:50 -07006829 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
6830 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
6831 return -EINVAL;
6832 }
6833
Jeff Johnson295189b2012-06-20 16:38:30 -07006834 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
6835
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006836#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006837 if (params->ssid != NULL)
6838 {
6839 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
6840 pConfig->SSIDinfo.ssid.length = params->ssid_len;
6841 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6842 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6843 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006844#else
6845 if (ssid != NULL)
6846 {
6847 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
6848 pConfig->SSIDinfo.ssid.length = ssid_len;
6849 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6850 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6851 }
6852#endif
6853
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306854 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07006855 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306856
Jeff Johnson295189b2012-06-20 16:38:30 -07006857 /* default value */
6858 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
6859 pConfig->num_accept_mac = 0;
6860 pConfig->num_deny_mac = 0;
6861
6862 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6863 pBeacon->tail, pBeacon->tail_len);
6864
6865 /* pIe for black list is following form:
6866 type : 1 byte
6867 length : 1 byte
6868 OUI : 4 bytes
6869 acl type : 1 byte
6870 no of mac addr in black list: 1 byte
6871 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306872 */
6873 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006874 {
6875 pConfig->SapMacaddr_acl = pIe[6];
6876 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006877 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006878 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306879 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
6880 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006881 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6882 for (i = 0; i < pConfig->num_deny_mac; i++)
6883 {
6884 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6885 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306886 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006887 }
6888 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6889 pBeacon->tail, pBeacon->tail_len);
6890
6891 /* pIe for white list is following form:
6892 type : 1 byte
6893 length : 1 byte
6894 OUI : 4 bytes
6895 acl type : 1 byte
6896 no of mac addr in white list: 1 byte
6897 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306898 */
6899 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006900 {
6901 pConfig->SapMacaddr_acl = pIe[6];
6902 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006903 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006904 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306905 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
6906 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006907 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6908 for (i = 0; i < pConfig->num_accept_mac; i++)
6909 {
6910 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6911 acl_entry++;
6912 }
6913 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306914
Jeff Johnson295189b2012-06-20 16:38:30 -07006915 wlan_hdd_set_sapHwmode(pHostapdAdapter);
6916
Jeff Johnsone7245742012-09-05 17:12:55 -07006917#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006918 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05306919 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
6920 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05306921 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
6922 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006923 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
6924 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05306925 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
6926 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07006927 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306928 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07006929 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306930 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006931
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306932 /* If ACS disable and selected channel <= 14
6933 * OR
6934 * ACS enabled and ACS operating band is choosen as 2.4
6935 * AND
6936 * VHT in 2.4G Disabled
6937 * THEN
6938 * Fallback to 11N mode
6939 */
6940 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
6941 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05306942 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306943 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006944 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306945 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
6946 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006947 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
6948 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006949 }
6950#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306951
Jeff Johnson295189b2012-06-20 16:38:30 -07006952 // ht_capab is not what the name conveys,this is used for protection bitmap
6953 pConfig->ht_capab =
6954 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
6955
6956 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
6957 {
6958 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
6959 return -EINVAL;
6960 }
6961
6962 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306963 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07006964 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
6965 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306966 pConfig->obssProtEnabled =
6967 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07006968
Chet Lanctot8cecea22014-02-11 19:09:36 -08006969#ifdef WLAN_FEATURE_11W
6970 pConfig->mfpCapable = MFPCapable;
6971 pConfig->mfpRequired = MFPRequired;
6972 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
6973 pConfig->mfpCapable, pConfig->mfpRequired);
6974#endif
6975
Arif Hussain6d2a3322013-11-17 19:50:10 -08006976 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07006977 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006978 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
6979 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
6980 (int)pConfig->channel);
6981 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
6982 pConfig->SapHw_mode, pConfig->privacy,
6983 pConfig->authType);
6984 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
6985 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
6986 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
6987 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07006988
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306989 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006990 {
6991 //Bss already started. just return.
6992 //TODO Probably it should update some beacon params.
6993 hddLog( LOGE, "Bss Already started...Ignore the request");
6994 EXIT();
6995 return 0;
6996 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306997
Agarwal Ashish51325b52014-06-16 16:50:49 +05306998 if (vos_max_concurrent_connections_reached()) {
6999 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7000 return -EINVAL;
7001 }
7002
Jeff Johnson295189b2012-06-20 16:38:30 -07007003 pConfig->persona = pHostapdAdapter->device_mode;
7004
Peng Xu2446a892014-09-05 17:21:18 +05307005 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
7006 if ( NULL != psmeConfig)
7007 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307008 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05307009 sme_GetConfigParam(hHal, psmeConfig);
7010 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307011#ifdef WLAN_FEATURE_AP_HT40_24G
7012 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7013 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
7014 && pHddCtx->cfg_ini->apHT40_24GEnabled)
7015 {
7016 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
7017 sme_UpdateConfig (hHal, psmeConfig);
7018 }
7019#endif
Peng Xu2446a892014-09-05 17:21:18 +05307020 vos_mem_free(psmeConfig);
7021 }
Peng Xuafc34e32014-09-25 13:23:55 +05307022 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05307023
Jeff Johnson295189b2012-06-20 16:38:30 -07007024 pSapEventCallback = hdd_hostapd_SAPEventCB;
7025 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
7026 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
7027 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007028 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007029 return -EINVAL;
7030 }
7031
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307032 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07007033 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7034
7035 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307036
Jeff Johnson295189b2012-06-20 16:38:30 -07007037 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307038 {
7039 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007040 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07007041 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07007042 VOS_ASSERT(0);
7043 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307044
Jeff Johnson295189b2012-06-20 16:38:30 -07007045 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05307046 /* Initialize WMM configuation */
7047 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307048 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007049
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007050#ifdef WLAN_FEATURE_P2P_DEBUG
7051 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
7052 {
7053 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
7054 {
7055 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7056 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007057 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007058 }
7059 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
7060 {
7061 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7062 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007063 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007064 }
7065 }
7066#endif
7067
Jeff Johnson295189b2012-06-20 16:38:30 -07007068 pHostapdState->bCommit = TRUE;
7069 EXIT();
7070
7071 return 0;
7072}
7073
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007074#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307075static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307076 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007077 struct beacon_parameters *params)
7078{
7079 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307080 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307081 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007082
7083 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307084
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307085 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7086 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
7087 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307088 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
7089 hdd_device_modetoString(pAdapter->device_mode),
7090 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007091
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307092 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7093 status = wlan_hdd_validate_context(pHddCtx);
7094
7095 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007096 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7098 "%s: HDD context is not valid", __func__);
7099 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007100 }
7101
Agarwal Ashish51325b52014-06-16 16:50:49 +05307102 if (vos_max_concurrent_connections_reached()) {
7103 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7104 return -EINVAL;
7105 }
7106
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307107 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007108 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007109 )
7110 {
7111 beacon_data_t *old,*new;
7112
7113 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307114
Jeff Johnson295189b2012-06-20 16:38:30 -07007115 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307116 {
7117 hddLog(VOS_TRACE_LEVEL_WARN,
7118 FL("already beacon info added to session(%d)"),
7119 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007120 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307121 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007122
7123 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7124
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307125 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07007126 {
7127 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007128 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007129 return -EINVAL;
7130 }
7131
7132 pAdapter->sessionCtx.ap.beacon = new;
7133
7134 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7135 }
7136
7137 EXIT();
7138 return status;
7139}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307140
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307141static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
7142 struct net_device *dev,
7143 struct beacon_parameters *params)
7144{
7145 int ret;
7146
7147 vos_ssr_protect(__func__);
7148 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
7149 vos_ssr_unprotect(__func__);
7150
7151 return ret;
7152}
7153
7154static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007155 struct net_device *dev,
7156 struct beacon_parameters *params)
7157{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307158 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307159 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7160 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307161 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007162
7163 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307164 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7165 TRACE_CODE_HDD_CFG80211_SET_BEACON,
7166 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
7167 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7168 __func__, hdd_device_modetoString(pAdapter->device_mode),
7169 pAdapter->device_mode);
7170
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307171 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7172 status = wlan_hdd_validate_context(pHddCtx);
7173
7174 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007175 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307176 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7177 "%s: HDD context is not valid", __func__);
7178 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007179 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307180
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307181 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007182 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307183 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007184 {
7185 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307186
Jeff Johnson295189b2012-06-20 16:38:30 -07007187 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307188
Jeff Johnson295189b2012-06-20 16:38:30 -07007189 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307190 {
7191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7192 FL("session(%d) old and new heads points to NULL"),
7193 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007194 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307195 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007196
7197 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7198
7199 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307200 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007201 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007202 return -EINVAL;
7203 }
7204
7205 pAdapter->sessionCtx.ap.beacon = new;
7206
7207 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7208 }
7209
7210 EXIT();
7211 return status;
7212}
7213
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307214static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
7215 struct net_device *dev,
7216 struct beacon_parameters *params)
7217{
7218 int ret;
7219
7220 vos_ssr_protect(__func__);
7221 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
7222 vos_ssr_unprotect(__func__);
7223
7224 return ret;
7225}
7226
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007227#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7228
7229#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307230static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007231 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007232#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307233static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007234 struct net_device *dev)
7235#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007236{
7237 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07007238 hdd_context_t *pHddCtx = NULL;
7239 hdd_scaninfo_t *pScanInfo = NULL;
7240 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307241 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307242 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007243
7244 ENTER();
7245
7246 if (NULL == pAdapter)
7247 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307248 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007249 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007250 return -ENODEV;
7251 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007252
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307253 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7254 TRACE_CODE_HDD_CFG80211_STOP_AP,
7255 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307256 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7257 status = wlan_hdd_validate_context(pHddCtx);
7258
7259 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007260 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307261 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7262 "%s: HDD context is not valid", __func__);
7263 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07007264 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007265
7266 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
7267 if (NULL == staAdapter)
7268 {
7269 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
7270 if (NULL == staAdapter)
7271 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07007272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7273 "%s: HDD adapter context for STA/P2P-CLI is Null",
7274 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007275 }
7276 }
7277
7278 pScanInfo = &pHddCtx->scan_info;
7279
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307280 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7281 __func__, hdd_device_modetoString(pAdapter->device_mode),
7282 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007283
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307284 ret = wlan_hdd_scan_abort(pAdapter);
7285
Girish Gowli4bf7a632014-06-12 13:42:11 +05307286 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07007287 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7289 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307290
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307291 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07007292 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7294 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08007295
Jeff Johnsone7245742012-09-05 17:12:55 -07007296 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307297 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07007298 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307299 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07007300 }
7301
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05307302 /* Delete all associated STAs before stopping AP/P2P GO */
7303 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05307304 hdd_hostapd_stop(dev);
7305
Jeff Johnson295189b2012-06-20 16:38:30 -07007306 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007307 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007308 )
7309 {
7310 beacon_data_t *old;
7311
7312 old = pAdapter->sessionCtx.ap.beacon;
7313
7314 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307315 {
7316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7317 FL("session(%d) beacon data points to NULL"),
7318 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007319 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307320 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007321
Jeff Johnson295189b2012-06-20 16:38:30 -07007322 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007323
7324 mutex_lock(&pHddCtx->sap_lock);
7325 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7326 {
Jeff Johnson4416a782013-03-25 14:17:50 -07007327 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007328 {
7329 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7330
7331 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7332
7333 if (!VOS_IS_STATUS_SUCCESS(status))
7334 {
7335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007336 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007337 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307338 }
7339 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007340 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307341 /* BSS stopped, clear the active sessions for this device mode */
7342 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007343 }
7344 mutex_unlock(&pHddCtx->sap_lock);
7345
7346 if(status != VOS_STATUS_SUCCESS)
7347 {
7348 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007349 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007350 return -EINVAL;
7351 }
7352
Jeff Johnson4416a782013-03-25 14:17:50 -07007353 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007354 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
7355 ==eHAL_STATUS_FAILURE)
7356 {
7357 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007358 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007359 }
7360
Jeff Johnson4416a782013-03-25 14:17:50 -07007361 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007362 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7363 eANI_BOOLEAN_FALSE) )
7364 {
7365 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007366 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007367 }
7368
7369 // Reset WNI_CFG_PROBE_RSP Flags
7370 wlan_hdd_reset_prob_rspies(pAdapter);
7371
7372 pAdapter->sessionCtx.ap.beacon = NULL;
7373 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007374#ifdef WLAN_FEATURE_P2P_DEBUG
7375 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7376 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
7377 {
7378 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
7379 "GO got removed");
7380 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
7381 }
7382#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007383 }
7384 EXIT();
7385 return status;
7386}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007387
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307388#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7389static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
7390 struct net_device *dev)
7391{
7392 int ret;
7393
7394 vos_ssr_protect(__func__);
7395 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
7396 vos_ssr_unprotect(__func__);
7397
7398 return ret;
7399}
7400#else
7401static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7402 struct net_device *dev)
7403{
7404 int ret;
7405
7406 vos_ssr_protect(__func__);
7407 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7408 vos_ssr_unprotect(__func__);
7409
7410 return ret;
7411}
7412#endif
7413
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007414#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7415
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307416static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307417 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007418 struct cfg80211_ap_settings *params)
7419{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307420 hdd_adapter_t *pAdapter;
7421 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307422 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007423
7424 ENTER();
7425
Girish Gowlib143d7a2015-02-18 19:39:55 +05307426 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007427 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05307429 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307430 return -ENODEV;
7431 }
7432
7433 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7434 if (NULL == pAdapter)
7435 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307437 "%s: HDD adapter is Null", __func__);
7438 return -ENODEV;
7439 }
7440
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307441 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7442 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
7443 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307444 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7445 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307447 "%s: HDD adapter magic is invalid", __func__);
7448 return -ENODEV;
7449 }
7450
7451 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307452 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307453
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307454 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307455 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7457 "%s: HDD context is not valid", __func__);
7458 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307459 }
7460
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307461 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7462 __func__, hdd_device_modetoString(pAdapter->device_mode),
7463 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307464
7465 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007466 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007467 )
7468 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307469 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007470
7471 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307472
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007473 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307474 {
7475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7476 FL("already beacon info added to session(%d)"),
7477 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007478 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307479 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007480
Girish Gowlib143d7a2015-02-18 19:39:55 +05307481#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7482 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7483 &new,
7484 &params->beacon);
7485#else
7486 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7487 &new,
7488 &params->beacon,
7489 params->dtim_period);
7490#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007491
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307492 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007493 {
7494 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307495 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007496 return -EINVAL;
7497 }
7498 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007499#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007500 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7501#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7502 params->channel, params->channel_type);
7503#else
7504 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7505#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007506#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007507 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
7508 params->ssid_len, params->hidden_ssid);
7509 }
7510
7511 EXIT();
7512 return status;
7513}
7514
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307515static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7516 struct net_device *dev,
7517 struct cfg80211_ap_settings *params)
7518{
7519 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007520
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307521 vos_ssr_protect(__func__);
7522 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
7523 vos_ssr_unprotect(__func__);
7524
7525 return ret;
7526}
7527
7528static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007529 struct net_device *dev,
7530 struct cfg80211_beacon_data *params)
7531{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307532 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307533 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307534 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007535
7536 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307537
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307538 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7539 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7540 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007541 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007542 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307543
7544 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7545 status = wlan_hdd_validate_context(pHddCtx);
7546
7547 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007548 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307549 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7550 "%s: HDD context is not valid", __func__);
7551 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007552 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007553
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307554 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007555 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307556 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007557 {
7558 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307559
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007560 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307561
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007562 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307563 {
7564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7565 FL("session(%d) beacon data points to NULL"),
7566 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007567 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307568 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007569
7570 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
7571
7572 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307573 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007574 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007575 return -EINVAL;
7576 }
7577
7578 pAdapter->sessionCtx.ap.beacon = new;
7579
7580 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
7581 }
7582
7583 EXIT();
7584 return status;
7585}
7586
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307587static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
7588 struct net_device *dev,
7589 struct cfg80211_beacon_data *params)
7590{
7591 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007592
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307593 vos_ssr_protect(__func__);
7594 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
7595 vos_ssr_unprotect(__func__);
7596
7597 return ret;
7598}
7599
7600#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007601
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307602static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007603 struct net_device *dev,
7604 struct bss_parameters *params)
7605{
7606 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307607 hdd_context_t *pHddCtx;
7608 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007609
7610 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307611
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307612 if (NULL == pAdapter)
7613 {
7614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7615 "%s: HDD adapter is Null", __func__);
7616 return -ENODEV;
7617 }
7618 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7619
7620 ret = wlan_hdd_validate_context(pHddCtx);
7621 if (0 != ret)
7622 {
7623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7624 "%s: HDD context is not valid", __func__);
7625 return ret;
7626 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307627 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7628 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
7629 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307630 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7631 __func__, hdd_device_modetoString(pAdapter->device_mode),
7632 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007633
7634 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007635 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307636 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007637 {
7638 /* ap_isolate == -1 means that in change bss, upper layer doesn't
7639 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307640 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07007641 {
7642 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307643 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007644 }
7645
7646 EXIT();
7647 return 0;
7648}
7649
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307650static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
7651 struct net_device *dev,
7652 struct bss_parameters *params)
7653{
7654 int ret;
7655
7656 vos_ssr_protect(__func__);
7657 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
7658 vos_ssr_unprotect(__func__);
7659
7660 return ret;
7661}
Kiet Lam10841362013-11-01 11:36:50 +05307662/* FUNCTION: wlan_hdd_change_country_code_cd
7663* to wait for contry code completion
7664*/
7665void* wlan_hdd_change_country_code_cb(void *pAdapter)
7666{
7667 hdd_adapter_t *call_back_pAdapter = pAdapter;
7668 complete(&call_back_pAdapter->change_country_code);
7669 return NULL;
7670}
7671
Jeff Johnson295189b2012-06-20 16:38:30 -07007672/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307673 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07007674 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
7675 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307676int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007677 struct net_device *ndev,
7678 enum nl80211_iftype type,
7679 u32 *flags,
7680 struct vif_params *params
7681 )
7682{
7683 struct wireless_dev *wdev;
7684 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007685 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07007686 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007687 tCsrRoamProfile *pRoamProfile = NULL;
7688 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307689 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007690 eMib_dot11DesiredBssType connectedBssType;
7691 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307692 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007693
7694 ENTER();
7695
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307696 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007697 {
7698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7699 "%s: Adapter context is null", __func__);
7700 return VOS_STATUS_E_FAILURE;
7701 }
7702
7703 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7704 if (!pHddCtx)
7705 {
7706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7707 "%s: HDD context is null", __func__);
7708 return VOS_STATUS_E_FAILURE;
7709 }
7710
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307711 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7712 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
7713 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307714 status = wlan_hdd_validate_context(pHddCtx);
7715
7716 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007717 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7719 "%s: HDD context is not valid", __func__);
7720 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007721 }
7722
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307723 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7724 __func__, hdd_device_modetoString(pAdapter->device_mode),
7725 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007726
Agarwal Ashish51325b52014-06-16 16:50:49 +05307727 if (vos_max_concurrent_connections_reached()) {
7728 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7729 return -EINVAL;
7730 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307731 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007732 wdev = ndev->ieee80211_ptr;
7733
7734#ifdef WLAN_BTAMP_FEATURE
7735 if((NL80211_IFTYPE_P2P_CLIENT == type)||
7736 (NL80211_IFTYPE_ADHOC == type)||
7737 (NL80211_IFTYPE_AP == type)||
7738 (NL80211_IFTYPE_P2P_GO == type))
7739 {
7740 pHddCtx->isAmpAllowed = VOS_FALSE;
7741 // stop AMP traffic
7742 status = WLANBAP_StopAmp();
7743 if(VOS_STATUS_SUCCESS != status )
7744 {
7745 pHddCtx->isAmpAllowed = VOS_TRUE;
7746 hddLog(VOS_TRACE_LEVEL_FATAL,
7747 "%s: Failed to stop AMP", __func__);
7748 return -EINVAL;
7749 }
7750 }
7751#endif //WLAN_BTAMP_FEATURE
7752 /* Reset the current device mode bit mask*/
7753 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7754
7755 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007756 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07007757 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07007758 )
7759 {
7760 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007761 if (!pWextState)
7762 {
7763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7764 "%s: pWextState is null", __func__);
7765 return VOS_STATUS_E_FAILURE;
7766 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007767 pRoamProfile = &pWextState->roamProfile;
7768 LastBSSType = pRoamProfile->BSSType;
7769
7770 switch (type)
7771 {
7772 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007773 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007774 hddLog(VOS_TRACE_LEVEL_INFO,
7775 "%s: setting interface Type to INFRASTRUCTURE", __func__);
7776 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07007777#ifdef WLAN_FEATURE_11AC
7778 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
7779 {
7780 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
7781 }
7782#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307783 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07007784 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007785 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007786 //Check for sub-string p2p to confirm its a p2p interface
7787 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307788 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007789 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7790 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7791 }
7792 else
7793 {
7794 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007795 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007796 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007797 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05307798
Jeff Johnson295189b2012-06-20 16:38:30 -07007799 case NL80211_IFTYPE_ADHOC:
7800 hddLog(VOS_TRACE_LEVEL_INFO,
7801 "%s: setting interface Type to ADHOC", __func__);
7802 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
7803 pRoamProfile->phyMode =
7804 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07007805 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007806 wdev->iftype = type;
7807 break;
7808
7809 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007810 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007811 {
7812 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7813 "%s: setting interface Type to %s", __func__,
7814 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
7815
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007816 //Cancel any remain on channel for GO mode
7817 if (NL80211_IFTYPE_P2P_GO == type)
7818 {
7819 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
7820 }
Mohit Khanna0f232092012-09-11 14:46:08 -07007821 if (NL80211_IFTYPE_AP == type)
7822 {
7823 /* As Loading WLAN Driver one interface being created for p2p device
7824 * address. This will take one HW STA and the max number of clients
7825 * that can connect to softAP will be reduced by one. so while changing
7826 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
7827 * interface as it is not required in SoftAP mode.
7828 */
7829
7830 // Get P2P Adapter
7831 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
7832
7833 if (pP2pAdapter)
7834 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307835 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05307836 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07007837 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
7838 }
7839 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05307840 //Disable IMPS & BMPS for SAP/GO
7841 if(VOS_STATUS_E_FAILURE ==
7842 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
7843 {
7844 //Fail to Exit BMPS
7845 VOS_ASSERT(0);
7846 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05307847
7848 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
7849
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307850#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07007851
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307852 /* A Mutex Lock is introduced while changing the mode to
7853 * protect the concurrent access for the Adapters by TDLS
7854 * module.
7855 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307856 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307857#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007858 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05307859 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07007860 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07007861 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7862 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307863#ifdef FEATURE_WLAN_TDLS
7864 mutex_unlock(&pHddCtx->tdls_lock);
7865#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007866 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
7867 (pConfig->apRandomBssidEnabled))
7868 {
7869 /* To meet Android requirements create a randomized
7870 MAC address of the form 02:1A:11:Fx:xx:xx */
7871 get_random_bytes(&ndev->dev_addr[3], 3);
7872 ndev->dev_addr[0] = 0x02;
7873 ndev->dev_addr[1] = 0x1A;
7874 ndev->dev_addr[2] = 0x11;
7875 ndev->dev_addr[3] |= 0xF0;
7876 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
7877 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08007878 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
7879 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007880 }
7881
Jeff Johnson295189b2012-06-20 16:38:30 -07007882 hdd_set_ap_ops( pAdapter->dev );
7883
Kiet Lam10841362013-11-01 11:36:50 +05307884 /* This is for only SAP mode where users can
7885 * control country through ini.
7886 * P2P GO follows station country code
7887 * acquired during the STA scanning. */
7888 if((NL80211_IFTYPE_AP == type) &&
7889 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
7890 {
7891 int status = 0;
7892 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
7893 "%s: setting country code from INI ", __func__);
7894 init_completion(&pAdapter->change_country_code);
7895 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
7896 (void *)(tSmeChangeCountryCallback)
7897 wlan_hdd_change_country_code_cb,
7898 pConfig->apCntryCode, pAdapter,
7899 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05307900 eSIR_FALSE,
7901 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05307902 if (eHAL_STATUS_SUCCESS == status)
7903 {
7904 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307905 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05307906 &pAdapter->change_country_code,
7907 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307908 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05307909 {
7910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307911 FL("SME Timed out while setting country code %ld"),
7912 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08007913
7914 if (pHddCtx->isLogpInProgress)
7915 {
7916 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7917 "%s: LOGP in Progress. Ignore!!!", __func__);
7918 return -EAGAIN;
7919 }
Kiet Lam10841362013-11-01 11:36:50 +05307920 }
7921 }
7922 else
7923 {
7924 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007925 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05307926 return -EINVAL;
7927 }
7928 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007929 status = hdd_init_ap_mode(pAdapter);
7930 if(status != VOS_STATUS_SUCCESS)
7931 {
7932 hddLog(VOS_TRACE_LEVEL_FATAL,
7933 "%s: Error initializing the ap mode", __func__);
7934 return -EINVAL;
7935 }
7936 hdd_set_conparam(1);
7937
Jeff Johnson295189b2012-06-20 16:38:30 -07007938 /*interface type changed update in wiphy structure*/
7939 if(wdev)
7940 {
7941 wdev->iftype = type;
7942 pHddCtx->change_iface = type;
7943 }
7944 else
7945 {
7946 hddLog(VOS_TRACE_LEVEL_ERROR,
7947 "%s: ERROR !!!! Wireless dev is NULL", __func__);
7948 return -EINVAL;
7949 }
7950 goto done;
7951 }
7952
7953 default:
7954 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7955 __func__);
7956 return -EOPNOTSUPP;
7957 }
7958 }
7959 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007960 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007961 )
7962 {
7963 switch(type)
7964 {
7965 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007966 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007967 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05307968
7969 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307970#ifdef FEATURE_WLAN_TDLS
7971
7972 /* A Mutex Lock is introduced while changing the mode to
7973 * protect the concurrent access for the Adapters by TDLS
7974 * module.
7975 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307976 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307977#endif
c_hpothu002231a2015-02-05 14:58:51 +05307978 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07007979 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007980 //Check for sub-string p2p to confirm its a p2p interface
7981 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007982 {
7983 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7984 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7985 }
7986 else
7987 {
7988 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007989 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007990 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007991 hdd_set_conparam(0);
7992 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007993 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
7994 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307995#ifdef FEATURE_WLAN_TDLS
7996 mutex_unlock(&pHddCtx->tdls_lock);
7997#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05307998 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007999 if( VOS_STATUS_SUCCESS != status )
8000 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07008001 /* In case of JB, for P2P-GO, only change interface will be called,
8002 * This is the right place to enable back bmps_imps()
8003 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308004 if (pHddCtx->hdd_wlan_suspended)
8005 {
8006 hdd_set_pwrparams(pHddCtx);
8007 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008008 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008009 goto done;
8010 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008011 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008012 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008013 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8014 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008015 goto done;
8016 default:
8017 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8018 __func__);
8019 return -EOPNOTSUPP;
8020
8021 }
8022
8023 }
8024 else
8025 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308026 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
8027 __func__, hdd_device_modetoString(pAdapter->device_mode),
8028 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008029 return -EOPNOTSUPP;
8030 }
8031
8032
8033 if(pRoamProfile)
8034 {
8035 if ( LastBSSType != pRoamProfile->BSSType )
8036 {
8037 /*interface type changed update in wiphy structure*/
8038 wdev->iftype = type;
8039
8040 /*the BSS mode changed, We need to issue disconnect
8041 if connected or in IBSS disconnect state*/
8042 if ( hdd_connGetConnectedBssType(
8043 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
8044 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
8045 {
8046 /*need to issue a disconnect to CSR.*/
8047 INIT_COMPLETION(pAdapter->disconnect_comp_var);
8048 if( eHAL_STATUS_SUCCESS ==
8049 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
8050 pAdapter->sessionId,
8051 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
8052 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308053 ret = wait_for_completion_interruptible_timeout(
8054 &pAdapter->disconnect_comp_var,
8055 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
8056 if (ret <= 0)
8057 {
8058 hddLog(VOS_TRACE_LEVEL_ERROR,
8059 FL("wait on disconnect_comp_var failed %ld"), ret);
8060 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008061 }
8062 }
8063 }
8064 }
8065
8066done:
8067 /*set bitmask based on updated value*/
8068 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07008069
8070 /* Only STA mode support TM now
8071 * all other mode, TM feature should be disabled */
8072 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
8073 (~VOS_STA & pHddCtx->concurrency_mode) )
8074 {
8075 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
8076 }
8077
Jeff Johnson295189b2012-06-20 16:38:30 -07008078#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308079 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05308080 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07008081 {
8082 //we are ok to do AMP
8083 pHddCtx->isAmpAllowed = VOS_TRUE;
8084 }
8085#endif //WLAN_BTAMP_FEATURE
8086 EXIT();
8087 return 0;
8088}
8089
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308090/*
8091 * FUNCTION: wlan_hdd_cfg80211_change_iface
8092 * wrapper function to protect the actual implementation from SSR.
8093 */
8094int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
8095 struct net_device *ndev,
8096 enum nl80211_iftype type,
8097 u32 *flags,
8098 struct vif_params *params
8099 )
8100{
8101 int ret;
8102
8103 vos_ssr_protect(__func__);
8104 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
8105 vos_ssr_unprotect(__func__);
8106
8107 return ret;
8108}
8109
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008110#ifdef FEATURE_WLAN_TDLS
8111static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
8112 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
8113{
8114 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8115 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8116 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008117 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308118 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308119 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008120
8121 ENTER();
8122
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308123 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008124 {
8125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8126 "Invalid arguments");
8127 return -EINVAL;
8128 }
Hoonki Lee27511902013-03-14 18:19:06 -07008129
8130 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
8131 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
8132 {
8133 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8134 "%s: TDLS mode is disabled OR not enabled in FW."
8135 MAC_ADDRESS_STR " Request declined.",
8136 __func__, MAC_ADDR_ARRAY(mac));
8137 return -ENOTSUPP;
8138 }
8139
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008140 if (pHddCtx->isLogpInProgress)
8141 {
8142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8143 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05308144 wlan_hdd_tdls_set_link_status(pAdapter,
8145 mac,
8146 eTDLS_LINK_IDLE,
8147 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008148 return -EBUSY;
8149 }
8150
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05308151 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008152
8153 if ( NULL == pTdlsPeer ) {
8154 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8155 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
8156 __func__, MAC_ADDR_ARRAY(mac), update);
8157 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008158 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008159
8160 /* in add station, we accept existing valid staId if there is */
8161 if ((0 == update) &&
8162 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
8163 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008164 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008165 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008166 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008167 " link_status %d. staId %d. add station ignored.",
8168 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
8169 return 0;
8170 }
8171 /* in change station, we accept only when staId is valid */
8172 if ((1 == update) &&
8173 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
8174 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
8175 {
8176 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8177 "%s: " MAC_ADDRESS_STR
8178 " link status %d. staId %d. change station %s.",
8179 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
8180 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
8181 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008182 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008183
8184 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308185 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008186 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8188 "%s: " MAC_ADDRESS_STR
8189 " TDLS setup is ongoing. Request declined.",
8190 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07008191 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008192 }
8193
8194 /* first to check if we reached to maximum supported TDLS peer.
8195 TODO: for now, return -EPERM looks working fine,
8196 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308197 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8198 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008199 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8201 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308202 " TDLS Max peer already connected. Request declined."
8203 " Num of peers (%d), Max allowed (%d).",
8204 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
8205 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008206 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008207 }
8208 else
8209 {
8210 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308211 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008212 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008213 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8215 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
8216 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008217 return -EPERM;
8218 }
8219 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008220 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05308221 wlan_hdd_tdls_set_link_status(pAdapter,
8222 mac,
8223 eTDLS_LINK_CONNECTING,
8224 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008225
Jeff Johnsond75fe012013-04-06 10:53:06 -07008226 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308227 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008228 {
8229 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8230 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008231 if(StaParams->htcap_present)
8232 {
8233 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8234 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
8235 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8236 "ht_capa->extended_capabilities: %0x",
8237 StaParams->HTCap.extendedHtCapInfo);
8238 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008239 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8240 "params->capability: %0x",StaParams->capability);
8241 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008242 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008243 if(StaParams->vhtcap_present)
8244 {
8245 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8246 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
8247 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
8248 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
8249 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008250 {
8251 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008253 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
8254 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8255 "[%d]: %x ", i, StaParams->supported_rates[i]);
8256 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07008257 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308258 else if ((1 == update) && (NULL == StaParams))
8259 {
8260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8261 "%s : update is true, but staParams is NULL. Error!", __func__);
8262 return -EPERM;
8263 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008264
8265 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
8266
8267 if (!update)
8268 {
8269 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
8270 pAdapter->sessionId, mac);
8271 }
8272 else
8273 {
8274 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
8275 pAdapter->sessionId, mac, StaParams);
8276 }
8277
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308278 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008279 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
8280
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308281 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008282 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308284 "%s: timeout waiting for tdls add station indication %ld",
8285 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008286 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008287 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308288
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008289 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
8290 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008291 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008292 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008293 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008294 }
8295
8296 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008297
8298error:
Atul Mittal115287b2014-07-08 13:26:33 +05308299 wlan_hdd_tdls_set_link_status(pAdapter,
8300 mac,
8301 eTDLS_LINK_IDLE,
8302 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008303 return -EPERM;
8304
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008305}
8306#endif
8307
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308308static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008309 struct net_device *dev,
8310 u8 *mac,
8311 struct station_parameters *params)
8312{
8313 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308314 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308315 hdd_context_t *pHddCtx;
8316 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008317 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308318 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008319#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008320 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008321 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308322 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008323#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008324
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308325 ENTER();
8326 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308327 if ((NULL == pAdapter))
8328 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308330 "invalid adapter ");
8331 return -EINVAL;
8332 }
8333
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308334 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8335 TRACE_CODE_HDD_CHANGE_STATION,
8336 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05308337 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308338
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308339 ret = wlan_hdd_validate_context(pHddCtx);
8340 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05308341 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308342 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8343 "%s: HDD context is not valid", __func__);
8344 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308345 }
8346
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308347 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8348
8349 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008350 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8352 "invalid HDD station context");
8353 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008354 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008355 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
8356
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008357 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8358 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07008359 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008360 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07008361 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308362 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07008363 WLANTL_STA_AUTHENTICATED);
8364
Gopichand Nakkala29149562013-05-10 21:43:41 +05308365 if (status != VOS_STATUS_SUCCESS)
8366 {
8367 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8368 "%s: Not able to change TL state to AUTHENTICATED", __func__);
8369 return -EINVAL;
8370 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008371 }
8372 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07008373 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8374 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308375#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008376 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8377 StaParams.capability = params->capability;
8378 StaParams.uapsd_queues = params->uapsd_queues;
8379 StaParams.max_sp = params->max_sp;
8380
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308381 /* Convert (first channel , number of channels) tuple to
8382 * the total list of channels. This goes with the assumption
8383 * that if the first channel is < 14, then the next channels
8384 * are an incremental of 1 else an incremental of 4 till the number
8385 * of channels.
8386 */
8387 if (0 != params->supported_channels_len) {
8388 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
8389 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
8390 {
8391 int wifi_chan_index;
8392 StaParams.supported_channels[j] = params->supported_channels[i];
8393 wifi_chan_index =
8394 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
8395 no_of_channels = params->supported_channels[i+1];
8396 for(k=1; k <= no_of_channels; k++)
8397 {
8398 StaParams.supported_channels[j+1] =
8399 StaParams.supported_channels[j] + wifi_chan_index;
8400 j+=1;
8401 }
8402 }
8403 StaParams.supported_channels_len = j;
8404 }
8405 vos_mem_copy(StaParams.supported_oper_classes,
8406 params->supported_oper_classes,
8407 params->supported_oper_classes_len);
8408 StaParams.supported_oper_classes_len =
8409 params->supported_oper_classes_len;
8410
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008411 if (0 != params->ext_capab_len)
8412 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
8413 sizeof(StaParams.extn_capability));
8414
8415 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008416 {
8417 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008418 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008419 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008420
8421 StaParams.supported_rates_len = params->supported_rates_len;
8422
8423 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
8424 * The supported_rates array , for all the structures propogating till Add Sta
8425 * to the firmware has to be modified , if the supplicant (ieee80211) is
8426 * modified to send more rates.
8427 */
8428
8429 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
8430 */
8431 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
8432 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
8433
8434 if (0 != StaParams.supported_rates_len) {
8435 int i = 0;
8436 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
8437 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008439 "Supported Rates with Length %d", StaParams.supported_rates_len);
8440 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008442 "[%d]: %0x", i, StaParams.supported_rates[i]);
8443 }
8444
8445 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008446 {
8447 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008448 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008449 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008450
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008451 if (0 != params->ext_capab_len ) {
8452 /*Define A Macro : TODO Sunil*/
8453 if ((1<<4) & StaParams.extn_capability[3]) {
8454 isBufSta = 1;
8455 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308456 /* TDLS Channel Switching Support */
8457 if ((1<<6) & StaParams.extn_capability[3]) {
8458 isOffChannelSupported = 1;
8459 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008460 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308461 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
8462 &StaParams, isBufSta,
8463 isOffChannelSupported);
8464
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308465 if (VOS_STATUS_SUCCESS != status) {
8466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8467 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
8468 return -EINVAL;
8469 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008470 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
8471
8472 if (VOS_STATUS_SUCCESS != status) {
8473 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8474 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
8475 return -EINVAL;
8476 }
8477 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008478#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05308479 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008480 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008481 return status;
8482}
8483
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308484static int wlan_hdd_change_station(struct wiphy *wiphy,
8485 struct net_device *dev,
8486 u8 *mac,
8487 struct station_parameters *params)
8488{
8489 int ret;
8490
8491 vos_ssr_protect(__func__);
8492 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
8493 vos_ssr_unprotect(__func__);
8494
8495 return ret;
8496}
8497
Jeff Johnson295189b2012-06-20 16:38:30 -07008498/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308499 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008500 * This function is used to initialize the key information
8501 */
8502#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308503static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008504 struct net_device *ndev,
8505 u8 key_index, bool pairwise,
8506 const u8 *mac_addr,
8507 struct key_params *params
8508 )
8509#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308510static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008511 struct net_device *ndev,
8512 u8 key_index, const u8 *mac_addr,
8513 struct key_params *params
8514 )
8515#endif
8516{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008517 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07008518 tCsrRoamSetKey setKey;
8519 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308520 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008521 v_U32_t roamId= 0xFF;
8522 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008523 hdd_hostapd_state_t *pHostapdState;
8524 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008525 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308526 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008527
8528 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308529
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308530 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8531 TRACE_CODE_HDD_CFG80211_ADD_KEY,
8532 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308533 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8534 status = wlan_hdd_validate_context(pHddCtx);
8535
8536 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008537 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308538 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8539 "%s: HDD context is not valid", __func__);
8540 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008541 }
8542
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308543 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8544 __func__, hdd_device_modetoString(pAdapter->device_mode),
8545 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008546
8547 if (CSR_MAX_NUM_KEY <= key_index)
8548 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008549 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008550 key_index);
8551
8552 return -EINVAL;
8553 }
8554
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008555 if (CSR_MAX_KEY_LEN < params->key_len)
8556 {
8557 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
8558 params->key_len);
8559
8560 return -EINVAL;
8561 }
8562
8563 hddLog(VOS_TRACE_LEVEL_INFO,
8564 "%s: called with key index = %d & key length %d",
8565 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008566
8567 /*extract key idx, key len and key*/
8568 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8569 setKey.keyId = key_index;
8570 setKey.keyLength = params->key_len;
8571 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
8572
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008573 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07008574 {
8575 case WLAN_CIPHER_SUITE_WEP40:
8576 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
8577 break;
8578
8579 case WLAN_CIPHER_SUITE_WEP104:
8580 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
8581 break;
8582
8583 case WLAN_CIPHER_SUITE_TKIP:
8584 {
8585 u8 *pKey = &setKey.Key[0];
8586 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
8587
8588 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
8589
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008590 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07008591
8592 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008593 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008594 |--------------|----------|----------|
8595 <---16bytes---><--8bytes--><--8bytes-->
8596
8597 */
8598 /*Sme expects the 32 bytes key to be in the below order
8599
8600 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008601 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008602 |--------------|----------|----------|
8603 <---16bytes---><--8bytes--><--8bytes-->
8604 */
8605 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008606 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07008607
8608 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008609 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008610
8611 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008612 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008613
8614
8615 break;
8616 }
8617
8618 case WLAN_CIPHER_SUITE_CCMP:
8619 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
8620 break;
8621
8622#ifdef FEATURE_WLAN_WAPI
8623 case WLAN_CIPHER_SUITE_SMS4:
8624 {
8625 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8626 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
8627 params->key, params->key_len);
8628 return 0;
8629 }
8630#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008631
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008632#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07008633 case WLAN_CIPHER_SUITE_KRK:
8634 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
8635 break;
8636#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008637
8638#ifdef WLAN_FEATURE_11W
8639 case WLAN_CIPHER_SUITE_AES_CMAC:
8640 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07008641 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07008642#endif
8643
Jeff Johnson295189b2012-06-20 16:38:30 -07008644 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008645 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07008646 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308647 status = -EOPNOTSUPP;
8648 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008649 }
8650
8651 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
8652 __func__, setKey.encType);
8653
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008654 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07008655#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8656 (!pairwise)
8657#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008658 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07008659#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008660 )
8661 {
8662 /* set group key*/
8663 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8664 "%s- %d: setting Broadcast key",
8665 __func__, __LINE__);
8666 setKey.keyDirection = eSIR_RX_ONLY;
8667 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8668 }
8669 else
8670 {
8671 /* set pairwise key*/
8672 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8673 "%s- %d: setting pairwise key",
8674 __func__, __LINE__);
8675 setKey.keyDirection = eSIR_TX_RX;
8676 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8677 }
8678 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
8679 {
8680 setKey.keyDirection = eSIR_TX_RX;
8681 /*Set the group key*/
8682 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8683 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07008684
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008685 if ( 0 != status )
8686 {
8687 hddLog(VOS_TRACE_LEVEL_ERROR,
8688 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308689 status = -EINVAL;
8690 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008691 }
8692 /*Save the keys here and call sme_RoamSetKey for setting
8693 the PTK after peer joins the IBSS network*/
8694 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
8695 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308696 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008697 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05308698 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
8699 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
8700 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008701 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008702 if( pHostapdState->bssState == BSS_START )
8703 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008704 status = WLANSAP_SetKeySta( pVosContext, &setKey);
8705
8706 if ( status != eHAL_STATUS_SUCCESS )
8707 {
8708 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8709 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8710 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308711 status = -EINVAL;
8712 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008713 }
8714 }
8715
8716 /* Saving WEP keys */
8717 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
8718 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
8719 {
8720 //Save the wep key in ap context. Issue setkey after the BSS is started.
8721 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8722 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
8723 }
8724 else
8725 {
8726 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008727 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008728 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
8729 }
8730 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008731 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
8732 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008733 {
8734 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8735 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8736
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308737#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8738 if (!pairwise)
8739#else
8740 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8741#endif
8742 {
8743 /* set group key*/
8744 if (pHddStaCtx->roam_info.deferKeyComplete)
8745 {
8746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8747 "%s- %d: Perform Set key Complete",
8748 __func__, __LINE__);
8749 hdd_PerformRoamSetKeyComplete(pAdapter);
8750 }
8751 }
8752
Jeff Johnson295189b2012-06-20 16:38:30 -07008753 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
8754
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08008755 pWextState->roamProfile.Keys.defaultIndex = key_index;
8756
8757
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008758 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008759 params->key, params->key_len);
8760
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308761
Jeff Johnson295189b2012-06-20 16:38:30 -07008762 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8763
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308764 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008765 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308766 __func__, setKey.peerMac[0], setKey.peerMac[1],
8767 setKey.peerMac[2], setKey.peerMac[3],
8768 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008769 setKey.keyDirection);
8770
Nirav Shah4f765af2015-01-21 19:51:30 +05308771 /* Wait for EAPOL M4 before setting key.
8772 * No need to consider Dynamic WEP as we will receive M8.
8773 */
8774 if ( (setKey.encType == eCSR_ENCRYPT_TYPE_AES ||
8775 setKey.encType == eCSR_ENCRYPT_TYPE_TKIP) &&
8776 ( 1
8777#if defined WLAN_FEATURE_VOWIFI_11R
8778 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_FT_RSN
8779 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_FT_RSN_PSK
8780#endif
8781#ifdef FEATURE_WLAN_ESE
8782 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_CCKM_WPA
8783 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_CCKM_RSN
8784#endif
8785 ))
Jeff Johnson295189b2012-06-20 16:38:30 -07008786 {
Nirav Shah4f765af2015-01-21 19:51:30 +05308787 vos_status = wlan_hdd_check_ula_done(pAdapter);
8788
8789 if ( vos_status != VOS_STATUS_SUCCESS )
8790 {
8791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008792 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8793 __LINE__, vos_status );
8794
Nirav Shah4f765af2015-01-21 19:51:30 +05308795 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008796
Nirav Shah4f765af2015-01-21 19:51:30 +05308797 status = -EINVAL;
8798 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008799
Nirav Shah4f765af2015-01-21 19:51:30 +05308800 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008801 }
8802
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008803#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308804 /* The supplicant may attempt to set the PTK once pre-authentication
8805 is done. Save the key in the UMAC and include it in the ADD BSS
8806 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008807 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308808 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008809 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308810 hddLog(VOS_TRACE_LEVEL_INFO_MED,
8811 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308812 status = 0;
8813 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308814 }
8815 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
8816 {
8817 hddLog(VOS_TRACE_LEVEL_ERROR,
8818 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308819 status = -EINVAL;
8820 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008821 }
8822#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07008823
8824 /* issue set key request to SME*/
8825 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8826 pAdapter->sessionId, &setKey, &roamId );
8827
8828 if ( 0 != status )
8829 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308830 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008831 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
8832 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308833 status = -EINVAL;
8834 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008835 }
8836
8837
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308838 /* in case of IBSS as there was no information available about WEP keys during
8839 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07008840 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308841 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
8842 !( ( IW_AUTH_KEY_MGMT_802_1X
8843 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07008844 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
8845 )
8846 &&
8847 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
8848 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
8849 )
8850 )
8851 {
8852 setKey.keyDirection = eSIR_RX_ONLY;
8853 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8854
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308855 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008856 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308857 __func__, setKey.peerMac[0], setKey.peerMac[1],
8858 setKey.peerMac[2], setKey.peerMac[3],
8859 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008860 setKey.keyDirection);
8861
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308862 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008863 pAdapter->sessionId, &setKey, &roamId );
8864
8865 if ( 0 != status )
8866 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308867 hddLog(VOS_TRACE_LEVEL_ERROR,
8868 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008869 __func__, status);
8870 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308871 status = -EINVAL;
8872 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008873 }
8874 }
8875 }
8876
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308877end:
8878 /* Need to clear any trace of key value in the memory.
8879 * Thus zero out the memory even though it is local
8880 * variable.
8881 */
8882 vos_mem_zero(&setKey, sizeof(setKey));
8883
8884 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008885}
8886
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308887#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8888static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8889 struct net_device *ndev,
8890 u8 key_index, bool pairwise,
8891 const u8 *mac_addr,
8892 struct key_params *params
8893 )
8894#else
8895static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8896 struct net_device *ndev,
8897 u8 key_index, const u8 *mac_addr,
8898 struct key_params *params
8899 )
8900#endif
8901{
8902 int ret;
8903 vos_ssr_protect(__func__);
8904#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8905 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
8906 mac_addr, params);
8907#else
8908 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
8909 params);
8910#endif
8911 vos_ssr_unprotect(__func__);
8912
8913 return ret;
8914}
8915
Jeff Johnson295189b2012-06-20 16:38:30 -07008916/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308917 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008918 * This function is used to get the key information
8919 */
8920#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308921static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308922 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008923 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308924 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008925 const u8 *mac_addr, void *cookie,
8926 void (*callback)(void *cookie, struct key_params*)
8927 )
8928#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308929static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308930 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008931 struct net_device *ndev,
8932 u8 key_index, const u8 *mac_addr, void *cookie,
8933 void (*callback)(void *cookie, struct key_params*)
8934 )
8935#endif
8936{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308937 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308938 hdd_wext_state_t *pWextState = NULL;
8939 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008940 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308941 hdd_context_t *pHddCtx;
8942 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008943
8944 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308945
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308946 if (NULL == pAdapter)
8947 {
8948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8949 "%s: HDD adapter is Null", __func__);
8950 return -ENODEV;
8951 }
8952
8953 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8954 ret = wlan_hdd_validate_context(pHddCtx);
8955 if (0 != ret)
8956 {
8957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8958 "%s: HDD context is not valid", __func__);
8959 return ret;
8960 }
8961
8962 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8963 pRoamProfile = &(pWextState->roamProfile);
8964
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308965 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8966 __func__, hdd_device_modetoString(pAdapter->device_mode),
8967 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308968
Jeff Johnson295189b2012-06-20 16:38:30 -07008969 memset(&params, 0, sizeof(params));
8970
8971 if (CSR_MAX_NUM_KEY <= key_index)
8972 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308973 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07008974 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308975 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008976
8977 switch(pRoamProfile->EncryptionType.encryptionType[0])
8978 {
8979 case eCSR_ENCRYPT_TYPE_NONE:
8980 params.cipher = IW_AUTH_CIPHER_NONE;
8981 break;
8982
8983 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
8984 case eCSR_ENCRYPT_TYPE_WEP40:
8985 params.cipher = WLAN_CIPHER_SUITE_WEP40;
8986 break;
8987
8988 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
8989 case eCSR_ENCRYPT_TYPE_WEP104:
8990 params.cipher = WLAN_CIPHER_SUITE_WEP104;
8991 break;
8992
8993 case eCSR_ENCRYPT_TYPE_TKIP:
8994 params.cipher = WLAN_CIPHER_SUITE_TKIP;
8995 break;
8996
8997 case eCSR_ENCRYPT_TYPE_AES:
8998 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
8999 break;
9000
9001 default:
9002 params.cipher = IW_AUTH_CIPHER_NONE;
9003 break;
9004 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309005
c_hpothuaaf19692014-05-17 17:01:48 +05309006 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9007 TRACE_CODE_HDD_CFG80211_GET_KEY,
9008 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309009
Jeff Johnson295189b2012-06-20 16:38:30 -07009010 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
9011 params.seq_len = 0;
9012 params.seq = NULL;
9013 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
9014 callback(cookie, &params);
9015 return 0;
9016}
9017
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309018#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9019static int wlan_hdd_cfg80211_get_key(
9020 struct wiphy *wiphy,
9021 struct net_device *ndev,
9022 u8 key_index, bool pairwise,
9023 const u8 *mac_addr, void *cookie,
9024 void (*callback)(void *cookie, struct key_params*)
9025 )
9026#else
9027static int wlan_hdd_cfg80211_get_key(
9028 struct wiphy *wiphy,
9029 struct net_device *ndev,
9030 u8 key_index, const u8 *mac_addr, void *cookie,
9031 void (*callback)(void *cookie, struct key_params*)
9032 )
9033#endif
9034{
9035 int ret;
9036
9037 vos_ssr_protect(__func__);
9038#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9039 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
9040 mac_addr, cookie, callback);
9041#else
9042 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
9043 callback);
9044#endif
9045 vos_ssr_unprotect(__func__);
9046
9047 return ret;
9048}
9049
Jeff Johnson295189b2012-06-20 16:38:30 -07009050/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309051 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009052 * This function is used to delete the key information
9053 */
9054#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309055static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009056 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309057 u8 key_index,
9058 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009059 const u8 *mac_addr
9060 )
9061#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309062static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009063 struct net_device *ndev,
9064 u8 key_index,
9065 const u8 *mac_addr
9066 )
9067#endif
9068{
9069 int status = 0;
9070
9071 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309072 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009073 //it is observed that this is invalidating peer
9074 //key index whenever re-key is done. This is affecting data link.
9075 //It should be ok to ignore del_key.
9076#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309077 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
9078 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009079 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
9080 tCsrRoamSetKey setKey;
9081 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309082
Jeff Johnson295189b2012-06-20 16:38:30 -07009083 ENTER();
9084
9085 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
9086 __func__,pAdapter->device_mode);
9087
9088 if (CSR_MAX_NUM_KEY <= key_index)
9089 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309090 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009091 key_index);
9092
9093 return -EINVAL;
9094 }
9095
9096 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9097 setKey.keyId = key_index;
9098
9099 if (mac_addr)
9100 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9101 else
9102 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
9103
9104 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
9105
9106 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009107 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309108 )
9109 {
9110
9111 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07009112 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9113 if( pHostapdState->bssState == BSS_START)
9114 {
9115 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309116
Jeff Johnson295189b2012-06-20 16:38:30 -07009117 if ( status != eHAL_STATUS_SUCCESS )
9118 {
9119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9120 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9121 __LINE__, status );
9122 }
9123 }
9124 }
9125 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309126 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07009127 )
9128 {
9129 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9130
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309131 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9132
9133 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009134 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309135 __func__, setKey.peerMac[0], setKey.peerMac[1],
9136 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07009137 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309138 if(pAdapter->sessionCtx.station.conn_info.connState ==
9139 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07009140 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309141 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009142 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309143
Jeff Johnson295189b2012-06-20 16:38:30 -07009144 if ( 0 != status )
9145 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309146 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009147 "%s: sme_RoamSetKey failure, returned %d",
9148 __func__, status);
9149 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9150 return -EINVAL;
9151 }
9152 }
9153 }
9154#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009155 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009156 return status;
9157}
9158
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309159#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9160static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9161 struct net_device *ndev,
9162 u8 key_index,
9163 bool pairwise,
9164 const u8 *mac_addr
9165 )
9166#else
9167static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9168 struct net_device *ndev,
9169 u8 key_index,
9170 const u8 *mac_addr
9171 )
9172#endif
9173{
9174 int ret;
9175
9176 vos_ssr_protect(__func__);
9177#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9178 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
9179 mac_addr);
9180#else
9181 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
9182#endif
9183 vos_ssr_unprotect(__func__);
9184
9185 return ret;
9186}
9187
Jeff Johnson295189b2012-06-20 16:38:30 -07009188/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309189 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009190 * This function is used to set the default tx key index
9191 */
9192#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309193static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009194 struct net_device *ndev,
9195 u8 key_index,
9196 bool unicast, bool multicast)
9197#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309198static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009199 struct net_device *ndev,
9200 u8 key_index)
9201#endif
9202{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309203 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309204 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309205 hdd_wext_state_t *pWextState;
9206 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309207 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009208
9209 ENTER();
9210
Gopichand Nakkala29149562013-05-10 21:43:41 +05309211 if ((NULL == pAdapter))
9212 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309214 "invalid adapter");
9215 return -EINVAL;
9216 }
9217
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309218 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9219 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
9220 pAdapter->sessionId, key_index));
9221
Gopichand Nakkala29149562013-05-10 21:43:41 +05309222 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9223 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9224
9225 if ((NULL == pWextState) || (NULL == pHddStaCtx))
9226 {
9227 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9228 "invalid Wext state or HDD context");
9229 return -EINVAL;
9230 }
9231
Arif Hussain6d2a3322013-11-17 19:50:10 -08009232 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009233 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309234
Jeff Johnson295189b2012-06-20 16:38:30 -07009235 if (CSR_MAX_NUM_KEY <= key_index)
9236 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309237 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009238 key_index);
9239
9240 return -EINVAL;
9241 }
9242
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309243 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9244 status = wlan_hdd_validate_context(pHddCtx);
9245
9246 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009247 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309248 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9249 "%s: HDD context is not valid", __func__);
9250 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009251 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309252
Jeff Johnson295189b2012-06-20 16:38:30 -07009253 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07009254 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309255 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009256 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309257 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08009258 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309259 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08009260 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07009261 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309262 {
9263 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07009264 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309265
Jeff Johnson295189b2012-06-20 16:38:30 -07009266 tCsrRoamSetKey setKey;
9267 v_U32_t roamId= 0xFF;
9268 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309269
9270 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009271 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309272
Jeff Johnson295189b2012-06-20 16:38:30 -07009273 Keys->defaultIndex = (u8)key_index;
9274 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9275 setKey.keyId = key_index;
9276 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309277
9278 vos_mem_copy(&setKey.Key[0],
9279 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009280 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309281
Gopichand Nakkala29149562013-05-10 21:43:41 +05309282 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309283
9284 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07009285 &pHddStaCtx->conn_info.bssId[0],
9286 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309287
Gopichand Nakkala29149562013-05-10 21:43:41 +05309288 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
9289 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
9290 eCSR_ENCRYPT_TYPE_WEP104)
9291 {
9292 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
9293 even though ap is configured for WEP-40 encryption. In this canse the key length
9294 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
9295 type(104) and switching encryption type to 40*/
9296 pWextState->roamProfile.EncryptionType.encryptionType[0] =
9297 eCSR_ENCRYPT_TYPE_WEP40;
9298 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
9299 eCSR_ENCRYPT_TYPE_WEP40;
9300 }
9301
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309302 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07009303 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309304
Jeff Johnson295189b2012-06-20 16:38:30 -07009305 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309306 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009307 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309308
Jeff Johnson295189b2012-06-20 16:38:30 -07009309 if ( 0 != status )
9310 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309311 hddLog(VOS_TRACE_LEVEL_ERROR,
9312 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009313 status);
9314 return -EINVAL;
9315 }
9316 }
9317 }
9318
9319 /* In SoftAp mode setting key direction for default mode */
9320 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
9321 {
9322 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
9323 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
9324 (eCSR_ENCRYPT_TYPE_AES !=
9325 pWextState->roamProfile.EncryptionType.encryptionType[0])
9326 )
9327 {
9328 /* Saving key direction for default key index to TX default */
9329 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9330 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
9331 }
9332 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309333
Jeff Johnson295189b2012-06-20 16:38:30 -07009334 return status;
9335}
9336
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309337#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9338static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9339 struct net_device *ndev,
9340 u8 key_index,
9341 bool unicast, bool multicast)
9342#else
9343static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9344 struct net_device *ndev,
9345 u8 key_index)
9346#endif
9347{
9348 int ret;
9349 vos_ssr_protect(__func__);
9350#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9351 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
9352 multicast);
9353#else
9354 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
9355#endif
9356 vos_ssr_unprotect(__func__);
9357
9358 return ret;
9359}
9360
Jeff Johnson295189b2012-06-20 16:38:30 -07009361/*
9362 * FUNCTION: wlan_hdd_cfg80211_inform_bss
9363 * This function is used to inform the BSS details to nl80211 interface.
9364 */
9365static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
9366 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
9367{
9368 struct net_device *dev = pAdapter->dev;
9369 struct wireless_dev *wdev = dev->ieee80211_ptr;
9370 struct wiphy *wiphy = wdev->wiphy;
9371 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
9372 int chan_no;
9373 int ie_length;
9374 const char *ie;
9375 unsigned int freq;
9376 struct ieee80211_channel *chan;
9377 int rssi = 0;
9378 struct cfg80211_bss *bss = NULL;
9379
9380 ENTER();
9381
9382 if( NULL == pBssDesc )
9383 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009384 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009385 return bss;
9386 }
9387
9388 chan_no = pBssDesc->channelId;
9389 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
9390 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
9391
9392 if( NULL == ie )
9393 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009394 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009395 return bss;
9396 }
9397
9398#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9399 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9400 {
9401 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9402 }
9403 else
9404 {
9405 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9406 }
9407#else
9408 freq = ieee80211_channel_to_frequency(chan_no);
9409#endif
9410
9411 chan = __ieee80211_get_channel(wiphy, freq);
9412
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05309413 if (!chan) {
9414 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
9415 return NULL;
9416 }
9417
Abhishek Singhaee43942014-06-16 18:55:47 +05309418 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07009419
Abhishek Singhaee43942014-06-16 18:55:47 +05309420 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309421 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07009422 pBssDesc->capabilityInfo,
9423 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05309424 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07009425}
9426
9427
9428
9429/*
9430 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
9431 * This function is used to inform the BSS details to nl80211 interface.
9432 */
9433struct cfg80211_bss*
9434wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
9435 tSirBssDescription *bss_desc
9436 )
9437{
9438 /*
9439 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
9440 already exists in bss data base of cfg80211 for that particular BSS ID.
9441 Using cfg80211_inform_bss_frame to update the bss entry instead of
9442 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
9443 now there is no possibility to get the mgmt(probe response) frame from PE,
9444 converting bss_desc to ieee80211_mgmt(probe response) and passing to
9445 cfg80211_inform_bss_frame.
9446 */
9447 struct net_device *dev = pAdapter->dev;
9448 struct wireless_dev *wdev = dev->ieee80211_ptr;
9449 struct wiphy *wiphy = wdev->wiphy;
9450 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009451#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9452 qcom_ie_age *qie_age = NULL;
9453 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
9454#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009455 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009456#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009457 const char *ie =
9458 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
9459 unsigned int freq;
9460 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309461 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009462 struct cfg80211_bss *bss_status = NULL;
9463 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
9464 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07009465 hdd_context_t *pHddCtx;
9466 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07009467#ifdef WLAN_OPEN_SOURCE
9468 struct timespec ts;
9469#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009470
Wilson Yangf80a0542013-10-07 13:02:37 -07009471 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9472 status = wlan_hdd_validate_context(pHddCtx);
9473
9474 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309475 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009476 {
9477 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9478 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9479 return NULL;
9480 }
9481
9482
9483 if (0 != status)
9484 {
9485 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9486 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009487 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009488 }
9489
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309490 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07009491 if (!mgmt)
9492 {
9493 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9494 "%s: memory allocation failed ", __func__);
9495 return NULL;
9496 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009497
Jeff Johnson295189b2012-06-20 16:38:30 -07009498 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07009499
9500#ifdef WLAN_OPEN_SOURCE
9501 /* Android does not want the timestamp from the frame.
9502 Instead it wants a monotonic increasing value */
9503 get_monotonic_boottime(&ts);
9504 mgmt->u.probe_resp.timestamp =
9505 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
9506#else
9507 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009508 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
9509 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07009510
9511#endif
9512
Jeff Johnson295189b2012-06-20 16:38:30 -07009513 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
9514 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009515
9516#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9517 /* GPS Requirement: need age ie per entry. Using vendor specific. */
9518 /* Assuming this is the last IE, copy at the end */
9519 ie_length -=sizeof(qcom_ie_age);
9520 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
9521 qie_age->element_id = QCOM_VENDOR_IE_ID;
9522 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
9523 qie_age->oui_1 = QCOM_OUI1;
9524 qie_age->oui_2 = QCOM_OUI2;
9525 qie_age->oui_3 = QCOM_OUI3;
9526 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
9527 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
9528#endif
9529
Jeff Johnson295189b2012-06-20 16:38:30 -07009530 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05309531 if (bss_desc->fProbeRsp)
9532 {
9533 mgmt->frame_control |=
9534 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
9535 }
9536 else
9537 {
9538 mgmt->frame_control |=
9539 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
9540 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009541
9542#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309543 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009544 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
9545 {
9546 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9547 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309548 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009549 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
9550
9551 {
9552 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9553 }
9554 else
9555 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309556 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
9557 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07009558 kfree(mgmt);
9559 return NULL;
9560 }
9561#else
9562 freq = ieee80211_channel_to_frequency(chan_no);
9563#endif
9564 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009565 /*when the band is changed on the fly using the GUI, three things are done
9566 * 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)
9567 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
9568 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
9569 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
9570 * and discards the channels correponding to previous band and calls back with zero bss results.
9571 * 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
9572 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
9573 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
9574 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
9575 * So drop the bss and continue to next bss.
9576 */
9577 if(chan == NULL)
9578 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309579 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07009580 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009581 return NULL;
9582 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009583 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309584 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07009585 * */
9586 if (( eConnectionState_Associated ==
9587 pAdapter->sessionCtx.station.conn_info.connState ) &&
9588 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
9589 pAdapter->sessionCtx.station.conn_info.bssId,
9590 WNI_CFG_BSSID_LEN)))
9591 {
9592 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
9593 rssi = (pAdapter->rssi * 100);
9594 }
9595 else
9596 {
9597 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
9598 }
9599
Nirav Shah20ac06f2013-12-12 18:14:06 +05309600 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
9601 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
9602 chan->center_freq, (int)(rssi/100));
9603
Jeff Johnson295189b2012-06-20 16:38:30 -07009604 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
9605 frame_len, rssi, GFP_KERNEL);
9606 kfree(mgmt);
9607 return bss_status;
9608}
9609
9610/*
9611 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
9612 * This function is used to update the BSS data base of CFG8011
9613 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309614struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009615 tCsrRoamInfo *pRoamInfo
9616 )
9617{
9618 tCsrRoamConnectedProfile roamProfile;
9619 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9620 struct cfg80211_bss *bss = NULL;
9621
9622 ENTER();
9623
9624 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
9625 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
9626
9627 if (NULL != roamProfile.pBssDesc)
9628 {
Girish Gowlif4b68022014-08-28 23:18:57 +05309629 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9630 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009631
9632 if (NULL == bss)
9633 {
9634 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
9635 __func__);
9636 }
9637
9638 sme_RoamFreeConnectProfile(hHal, &roamProfile);
9639 }
9640 else
9641 {
9642 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
9643 __func__);
9644 }
9645 return bss;
9646}
9647
9648/*
9649 * FUNCTION: wlan_hdd_cfg80211_update_bss
9650 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309651static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
9652 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07009653 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309654{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309655 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009656 tCsrScanResultInfo *pScanResult;
9657 eHalStatus status = 0;
9658 tScanResultHandle pResult;
9659 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009660 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009661
9662 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309663
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309664 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9665 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
9666 NO_SESSION, pAdapter->sessionId));
9667
Wilson Yangf80a0542013-10-07 13:02:37 -07009668 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9669
9670 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009671 {
Wilson Yangf80a0542013-10-07 13:02:37 -07009672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9673 "%s:LOGP in Progress. Ignore!!!",__func__);
9674 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009675 }
9676
Wilson Yangf80a0542013-10-07 13:02:37 -07009677
9678 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309679 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009680 {
9681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9682 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9683 return VOS_STATUS_E_PERM;
9684 }
9685
9686
Jeff Johnson295189b2012-06-20 16:38:30 -07009687 /*
9688 * start getting scan results and populate cgf80211 BSS database
9689 */
9690 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
9691
9692 /* no scan results */
9693 if (NULL == pResult)
9694 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309695 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
9696 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009697 return status;
9698 }
9699
9700 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
9701
9702 while (pScanResult)
9703 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309704 /*
9705 * cfg80211_inform_bss() is not updating ie field of bss entry, if
9706 * entry already exists in bss data base of cfg80211 for that
9707 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
9708 * bss entry instead of cfg80211_inform_bss, But this call expects
9709 * mgmt packet as input. As of now there is no possibility to get
9710 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07009711 * ieee80211_mgmt(probe response) and passing to c
9712 * fg80211_inform_bss_frame.
9713 * */
9714
9715 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9716 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309717
Jeff Johnson295189b2012-06-20 16:38:30 -07009718
9719 if (NULL == bss_status)
9720 {
9721 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009722 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009723 }
9724 else
9725 {
Yue Maf49ba872013-08-19 12:04:25 -07009726 cfg80211_put_bss(
9727#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
9728 wiphy,
9729#endif
9730 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009731 }
9732
9733 pScanResult = sme_ScanResultGetNext(hHal, pResult);
9734 }
9735
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309736 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07009737
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309738 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009739}
9740
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009741void
9742hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
9743{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309744 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08009745 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009746} /****** end hddPrintMacAddr() ******/
9747
9748void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009749hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009750{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309751 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009752 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009753 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
9754 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
9755 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009756} /****** end hddPrintPmkId() ******/
9757
9758//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
9759//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
9760
9761//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
9762//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
9763
9764#define dump_bssid(bssid) \
9765 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009766 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
9767 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009768 }
9769
9770#define dump_pmkid(pMac, pmkid) \
9771 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009772 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
9773 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009774 }
9775
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009776#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009777/*
9778 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
9779 * This function is used to notify the supplicant of a new PMKSA candidate.
9780 */
9781int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309782 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009783 int index, bool preauth )
9784{
Jeff Johnsone7245742012-09-05 17:12:55 -07009785#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009786 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009787 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009788
9789 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07009790 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009791
9792 if( NULL == pRoamInfo )
9793 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009794 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009795 return -EINVAL;
9796 }
9797
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009798 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
9799 {
9800 dump_bssid(pRoamInfo->bssid);
9801 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009802 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009803 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009804#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309805 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009806}
9807#endif //FEATURE_WLAN_LFR
9808
Yue Maef608272013-04-08 23:09:17 -07009809#ifdef FEATURE_WLAN_LFR_METRICS
9810/*
9811 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
9812 * 802.11r/LFR metrics reporting function to report preauth initiation
9813 *
9814 */
9815#define MAX_LFR_METRICS_EVENT_LENGTH 100
9816VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
9817 tCsrRoamInfo *pRoamInfo)
9818{
9819 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9820 union iwreq_data wrqu;
9821
9822 ENTER();
9823
9824 if (NULL == pAdapter)
9825 {
9826 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9827 return VOS_STATUS_E_FAILURE;
9828 }
9829
9830 /* create the event */
9831 memset(&wrqu, 0, sizeof(wrqu));
9832 memset(metrics_notification, 0, sizeof(metrics_notification));
9833
9834 wrqu.data.pointer = metrics_notification;
9835 wrqu.data.length = scnprintf(metrics_notification,
9836 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
9837 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9838
9839 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9840
9841 EXIT();
9842
9843 return VOS_STATUS_SUCCESS;
9844}
9845
9846/*
9847 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
9848 * 802.11r/LFR metrics reporting function to report preauth completion
9849 * or failure
9850 */
9851VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
9852 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
9853{
9854 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9855 union iwreq_data wrqu;
9856
9857 ENTER();
9858
9859 if (NULL == pAdapter)
9860 {
9861 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9862 return VOS_STATUS_E_FAILURE;
9863 }
9864
9865 /* create the event */
9866 memset(&wrqu, 0, sizeof(wrqu));
9867 memset(metrics_notification, 0, sizeof(metrics_notification));
9868
9869 scnprintf(metrics_notification, sizeof(metrics_notification),
9870 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
9871 MAC_ADDR_ARRAY(pRoamInfo->bssid));
9872
9873 if (1 == preauth_status)
9874 strncat(metrics_notification, " TRUE", 5);
9875 else
9876 strncat(metrics_notification, " FALSE", 6);
9877
9878 wrqu.data.pointer = metrics_notification;
9879 wrqu.data.length = strlen(metrics_notification);
9880
9881 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9882
9883 EXIT();
9884
9885 return VOS_STATUS_SUCCESS;
9886}
9887
9888/*
9889 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
9890 * 802.11r/LFR metrics reporting function to report handover initiation
9891 *
9892 */
9893VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
9894 tCsrRoamInfo *pRoamInfo)
9895{
9896 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9897 union iwreq_data wrqu;
9898
9899 ENTER();
9900
9901 if (NULL == pAdapter)
9902 {
9903 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9904 return VOS_STATUS_E_FAILURE;
9905 }
9906
9907 /* create the event */
9908 memset(&wrqu, 0, sizeof(wrqu));
9909 memset(metrics_notification, 0, sizeof(metrics_notification));
9910
9911 wrqu.data.pointer = metrics_notification;
9912 wrqu.data.length = scnprintf(metrics_notification,
9913 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
9914 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9915
9916 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9917
9918 EXIT();
9919
9920 return VOS_STATUS_SUCCESS;
9921}
9922#endif
9923
Jeff Johnson295189b2012-06-20 16:38:30 -07009924/*
9925 * FUNCTION: hdd_cfg80211_scan_done_callback
9926 * scanning callback function, called after finishing scan
9927 *
9928 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309929static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07009930 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
9931{
9932 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309933 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009934 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009935 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9936 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07009937 struct cfg80211_scan_request *req = NULL;
9938 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309939 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309940 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +05309941 tANI_U8 i;
Jeff Johnson295189b2012-06-20 16:38:30 -07009942
9943 ENTER();
9944
9945 hddLog(VOS_TRACE_LEVEL_INFO,
9946 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08009947 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009948 __func__, halHandle, pContext, (int) scanId, (int) status);
9949
Kiet Lamac06e2c2013-10-23 16:25:07 +05309950 pScanInfo->mScanPendingCounter = 0;
9951
Jeff Johnson295189b2012-06-20 16:38:30 -07009952 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309953 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009954 &pScanInfo->scan_req_completion_event,
9955 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309956 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009957 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309958 hddLog(VOS_TRACE_LEVEL_ERROR,
9959 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07009960 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009961 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009962 }
9963
Yue Maef608272013-04-08 23:09:17 -07009964 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07009965 {
9966 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009967 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009968 }
9969
9970 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309971 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07009972 {
9973 hddLog(VOS_TRACE_LEVEL_INFO,
9974 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009975 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07009976 (int) scanId);
9977 }
9978
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309979 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009980 pAdapter);
9981
9982 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309983 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009984
9985
9986 /* If any client wait scan result through WEXT
9987 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009988 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07009989 {
9990 /* The other scan request waiting for current scan finish
9991 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009992 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009993 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009994 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07009995 }
9996 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009997 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009998 {
9999 struct net_device *dev = pAdapter->dev;
10000 union iwreq_data wrqu;
10001 int we_event;
10002 char *msg;
10003
10004 memset(&wrqu, '\0', sizeof(wrqu));
10005 we_event = SIOCGIWSCAN;
10006 msg = NULL;
10007 wireless_send_event(dev, we_event, &wrqu, msg);
10008 }
10009 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010010 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010011
10012 /* Get the Scan Req */
10013 req = pAdapter->request;
10014
10015 if (!req)
10016 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010017 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010018 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010019 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010020 }
10021
Jeff Johnson295189b2012-06-20 16:38:30 -070010022 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070010023 /* Scan is no longer pending */
10024 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010025
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010026 /* last_scan_timestamp is used to decide if new scan
10027 * is needed or not on station interface. If last station
10028 * scan time and new station scan time is less then
10029 * last_scan_timestamp ; driver will return cached scan.
10030 */
10031 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
10032 {
10033 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
10034
10035 if ( req->n_channels )
10036 {
10037 for (i = 0; i < req->n_channels ; i++ )
10038 {
10039 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
10040 }
10041 /* store no of channel scanned */
10042 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
10043 }
10044
10045 }
10046
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070010047 /*
10048 * cfg80211_scan_done informing NL80211 about completion
10049 * of scanning
10050 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010051 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
10052 {
10053 aborted = true;
10054 }
10055 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080010056 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010057
Siddharth Bhal76972212014-10-15 16:22:51 +053010058 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
10059 /* Generate new random mac addr for next scan */
10060 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
10061 hdd_processSpoofMacAddrRequest(pHddCtx);
10062 }
10063
Jeff Johnsone7245742012-09-05 17:12:55 -070010064allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010065 /* release the wake lock at the end of the scan*/
10066 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -070010067
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010068 /* Acquire wakelock to handle the case where APP's tries to suspend
10069 * immediatly after the driver gets connect request(i.e after scan)
10070 * from supplicant, this result in app's is suspending and not able
10071 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010072 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010073
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010074#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010075 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010076#endif
10077
Jeff Johnson295189b2012-06-20 16:38:30 -070010078 EXIT();
10079 return 0;
10080}
10081
10082/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053010083 * FUNCTION: hdd_isConnectionInProgress
10084 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010085 *
10086 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010087v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010088{
10089 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10090 hdd_station_ctx_t *pHddStaCtx = NULL;
10091 hdd_adapter_t *pAdapter = NULL;
10092 VOS_STATUS status = 0;
10093 v_U8_t staId = 0;
10094 v_U8_t *staMac = NULL;
10095
c_hpothu9b781ba2013-12-30 20:57:45 +053010096 if (TRUE == pHddCtx->btCoexModeSet)
10097 {
10098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053010099 FL("BTCoex Mode operation in progress"));
10100 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053010101 }
10102
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010103 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10104
10105 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10106 {
10107 pAdapter = pAdapterNode->pAdapter;
10108
10109 if( pAdapter )
10110 {
10111 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010112 "%s: Adapter with device mode %s (%d) exists",
10113 __func__, hdd_device_modetoString(pAdapter->device_mode),
10114 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010115 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053010116 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10117 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
10118 (eConnectionState_Connecting ==
10119 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
10120 {
10121 hddLog(VOS_TRACE_LEVEL_ERROR,
10122 "%s: %p(%d) Connection is in progress", __func__,
10123 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10124 return VOS_TRUE;
10125 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010126 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053010127 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010128 {
10129 hddLog(VOS_TRACE_LEVEL_ERROR,
10130 "%s: %p(%d) Reassociation is in progress", __func__,
10131 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10132 return VOS_TRUE;
10133 }
10134 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010135 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10136 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010137 {
10138 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10139 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010140 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010141 {
10142 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
10143 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010144 "%s: client " MAC_ADDRESS_STR
10145 " is in the middle of WPS/EAPOL exchange.", __func__,
10146 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010147 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010148 }
10149 }
10150 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
10151 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
10152 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010153 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10154 ptSapContext pSapCtx = NULL;
10155 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10156 if(pSapCtx == NULL){
10157 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10158 FL("psapCtx is NULL"));
10159 return VOS_FALSE;
10160 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010161 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
10162 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010163 if ((pSapCtx->aStaInfo[staId].isUsed) &&
10164 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010165 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010166 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010167
10168 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010169 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
10170 "middle of WPS/EAPOL exchange.", __func__,
10171 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010172 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010173 }
10174 }
10175 }
10176 }
10177 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10178 pAdapterNode = pNext;
10179 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053010180 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010181}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010182
10183/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010184 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070010185 * this scan respond to scan trigger and update cfg80211 scan database
10186 * later, scan dump command can be used to recieve scan results
10187 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010188int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010189#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10190 struct net_device *dev,
10191#endif
10192 struct cfg80211_scan_request *request)
10193{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010194 hdd_adapter_t *pAdapter = NULL;
10195 hdd_context_t *pHddCtx = NULL;
10196 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010197 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010198 tCsrScanRequest scanRequest;
10199 tANI_U8 *channelList = NULL, i;
10200 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010201 int status;
10202 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010203 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010204 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010205
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010206#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
10207 struct net_device *dev = NULL;
10208 if (NULL == request)
10209 {
10210 hddLog(VOS_TRACE_LEVEL_ERROR,
10211 "%s: scan req param null", __func__);
10212 return -EINVAL;
10213 }
10214 dev = request->wdev->netdev;
10215#endif
10216
10217 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
10218 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
10219 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10220
Jeff Johnson295189b2012-06-20 16:38:30 -070010221 ENTER();
10222
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010223
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010224 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10225 __func__, hdd_device_modetoString(pAdapter->device_mode),
10226 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010227
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010228 status = wlan_hdd_validate_context(pHddCtx);
10229
10230 if (0 != status)
10231 {
10232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10233 "%s: HDD context is not valid", __func__);
10234 return status;
10235 }
10236
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010237 if (NULL == pwextBuf)
10238 {
10239 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
10240 __func__);
10241 return -EIO;
10242 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010243 cfg_param = pHddCtx->cfg_ini;
10244 pScanInfo = &pHddCtx->scan_info;
10245
Jeff Johnson295189b2012-06-20 16:38:30 -070010246#ifdef WLAN_BTAMP_FEATURE
10247 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010248 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070010249 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010250 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010251 "%s: No scanning when AMP is on", __func__);
10252 return -EOPNOTSUPP;
10253 }
10254#endif
10255 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010256 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010257 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010258 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010259 "%s: Not scanning on device_mode = %s (%d)",
10260 __func__, hdd_device_modetoString(pAdapter->device_mode),
10261 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010262 return -EOPNOTSUPP;
10263 }
10264
10265 if (TRUE == pScanInfo->mScanPending)
10266 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010267 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
10268 {
10269 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
10270 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010271 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010272 }
10273
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010274 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070010275 //Channel and action frame is pending
10276 //Otherwise Cancel Remain On Channel and allow Scan
10277 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010278 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070010279 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010280 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010281 return -EBUSY;
10282 }
10283
Jeff Johnson295189b2012-06-20 16:38:30 -070010284 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
10285 {
10286 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080010287 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010288 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010289 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010290 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
10291 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010292 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010293 "%s: MAX TM Level Scan not allowed", __func__);
10294 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010295 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010296 }
10297 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
10298
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010299 /* Check if scan is allowed at this point of time.
10300 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010301 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010302 {
10303 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
10304 return -EBUSY;
10305 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010306
Jeff Johnson295189b2012-06-20 16:38:30 -070010307 vos_mem_zero( &scanRequest, sizeof(scanRequest));
10308
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010309 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
10310 (int)request->n_ssids);
10311
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010312
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010313 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
10314 * Becasue of this, driver is assuming that this is not wildcard scan and so
10315 * is not aging out the scan results.
10316 */
10317 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010318 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010319 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010320 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010321
10322 if ((request->ssids) && (0 < request->n_ssids))
10323 {
10324 tCsrSSIDInfo *SsidInfo;
10325 int j;
10326 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
10327 /* Allocate num_ssid tCsrSSIDInfo structure */
10328 SsidInfo = scanRequest.SSIDs.SSIDList =
10329 ( tCsrSSIDInfo *)vos_mem_malloc(
10330 request->n_ssids*sizeof(tCsrSSIDInfo));
10331
10332 if(NULL == scanRequest.SSIDs.SSIDList)
10333 {
10334 hddLog(VOS_TRACE_LEVEL_ERROR,
10335 "%s: memory alloc failed SSIDInfo buffer", __func__);
10336 return -ENOMEM;
10337 }
10338
10339 /* copy all the ssid's and their length */
10340 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
10341 {
10342 /* get the ssid length */
10343 SsidInfo->SSID.length = request->ssids[j].ssid_len;
10344 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
10345 SsidInfo->SSID.length);
10346 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
10347 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
10348 j, SsidInfo->SSID.ssId);
10349 }
10350 /* set the scan type to active */
10351 scanRequest.scanType = eSIR_ACTIVE_SCAN;
10352 }
10353 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070010354 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010355 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10356 TRACE_CODE_HDD_CFG80211_SCAN,
10357 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070010358 /* set the scan type to active */
10359 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010360 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010361 else
10362 {
10363 /*Set the scan type to default type, in this case it is ACTIVE*/
10364 scanRequest.scanType = pScanInfo->scan_mode;
10365 }
10366 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
10367 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070010368
10369 /* set BSSType to default type */
10370 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
10371
10372 /*TODO: scan the requested channels only*/
10373
10374 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010375 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070010376 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010377 hddLog(VOS_TRACE_LEVEL_WARN,
10378 "No of Scan Channels exceeded limit: %d", request->n_channels);
10379 request->n_channels = MAX_CHANNEL;
10380 }
10381
10382 hddLog(VOS_TRACE_LEVEL_INFO,
10383 "No of Scan Channels: %d", request->n_channels);
10384
10385
10386 if( request->n_channels )
10387 {
10388 char chList [(request->n_channels*5)+1];
10389 int len;
10390 channelList = vos_mem_malloc( request->n_channels );
10391 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053010392 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010393 hddLog(VOS_TRACE_LEVEL_ERROR,
10394 "%s: memory alloc failed channelList", __func__);
10395 status = -ENOMEM;
10396 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053010397 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010398
10399 for( i = 0, len = 0; i < request->n_channels ; i++ )
10400 {
10401 channelList[i] = request->channels[i]->hw_value;
10402 len += snprintf(chList+len, 5, "%d ", channelList[i]);
10403 }
10404
Nirav Shah20ac06f2013-12-12 18:14:06 +053010405 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010406 "Channel-List: %s ", chList);
10407 }
c_hpothu53512302014-04-15 18:49:53 +053010408
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010409 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
10410 scanRequest.ChannelInfo.ChannelList = channelList;
10411
10412 /* set requestType to full scan */
10413 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10414
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010415 /* if there is back to back scan happening in driver with in
10416 * nDeferScanTimeInterval interval driver should defer new scan request
10417 * and should provide last cached scan results instead of new channel list.
10418 * This rule is not applicable if scan is p2p scan.
10419 * This condition will work only in case when last request no of channels
10420 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053010421 * This should be done only in connected state
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010422 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010423
Agarwal Ashish57e84372014-12-05 18:26:53 +053010424 if ((VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
10425 {
10426 if ( pScanInfo->last_scan_timestamp !=0 &&
10427 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
10428 {
10429 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
10430 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
10431 vos_mem_compare(pScanInfo->last_scan_channelList,
10432 channelList, pScanInfo->last_scan_numChannels))
10433 {
10434 hddLog(VOS_TRACE_LEVEL_WARN,
10435 " New and old station scan time differ is less then %u",
10436 pHddCtx->cfg_ini->nDeferScanTimeInterval);
10437
10438 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010439 pAdapter);
10440
Agarwal Ashish57e84372014-12-05 18:26:53 +053010441 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010442 "Return old cached scan as all channels and no of channels are same");
10443
Agarwal Ashish57e84372014-12-05 18:26:53 +053010444 if (0 > ret)
10445 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010446
Agarwal Ashish57e84372014-12-05 18:26:53 +053010447 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010448
10449 status = eHAL_STATUS_SUCCESS;
10450 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053010451 }
10452 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010453 }
10454
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010455 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10456 * search (Flush on both full scan and social scan but not on single
10457 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10458 */
10459
10460 /* Supplicant does single channel scan after 8-way handshake
10461 * and in that case driver shoudnt flush scan results. If
10462 * driver flushes the scan results here and unfortunately if
10463 * the AP doesnt respond to our probe req then association
10464 * fails which is not desired
10465 */
10466
10467 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
10468 {
10469 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
10470 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
10471 pAdapter->sessionId );
10472 }
10473
10474 if( request->ie_len )
10475 {
10476 /* save this for future association (join requires this) */
10477 /*TODO: Array needs to be converted to dynamic allocation,
10478 * as multiple ie.s can be sent in cfg80211_scan_request structure
10479 * CR 597966
10480 */
10481 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
10482 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
10483 pScanInfo->scanAddIE.length = request->ie_len;
10484
10485 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10486 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10487 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010488 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010489 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070010490 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010491 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
10492 memcpy( pwextBuf->roamProfile.addIEScan,
10493 request->ie, request->ie_len);
10494 }
10495 else
10496 {
10497 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
10498 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070010499 }
10500
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010501 }
10502 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
10503 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
10504
10505 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
10506 request->ie_len);
10507 if (pP2pIe != NULL)
10508 {
10509#ifdef WLAN_FEATURE_P2P_DEBUG
10510 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
10511 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
10512 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053010513 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010514 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
10515 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10516 "Go nego completed to Connection is started");
10517 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10518 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053010519 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010520 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
10521 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010522 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010523 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
10524 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10525 "Disconnected state to Connection is started");
10526 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10527 "for 4way Handshake");
10528 }
10529#endif
10530
10531 /* no_cck will be set during p2p find to disable 11b rates */
10532 if(TRUE == request->no_cck)
10533 {
10534 hddLog(VOS_TRACE_LEVEL_INFO,
10535 "%s: This is a P2P Search", __func__);
10536 scanRequest.p2pSearch = 1;
10537
10538 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053010539 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010540 /* set requestType to P2P Discovery */
10541 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
10542 }
10543
10544 /*
10545 Skip Dfs Channel in case of P2P Search
10546 if it is set in ini file
10547 */
10548 if(cfg_param->skipDfsChnlInP2pSearch)
10549 {
10550 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010551 }
10552 else
10553 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010554 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010555 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010556
Agarwal Ashish4f616132013-12-30 23:32:50 +053010557 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010558 }
10559 }
10560
10561 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
10562
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010563#ifdef FEATURE_WLAN_TDLS
10564 /* if tdls disagree scan right now, return immediately.
10565 tdls will schedule the scan when scan is allowed. (return SUCCESS)
10566 or will reject the scan if any TDLS is in progress. (return -EBUSY)
10567 */
10568 status = wlan_hdd_tdls_scan_callback (pAdapter,
10569 wiphy,
10570#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10571 dev,
10572#endif
10573 request);
10574 if(status <= 0)
10575 {
10576 if(!status)
10577 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
10578 "scan rejected %d", __func__, status);
10579 else
10580 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
10581 __func__, status);
10582
10583 return status;
10584 }
10585#endif
10586
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010587 /* acquire the wakelock to avoid the apps suspend during the scan. To
10588 * address the following issues.
10589 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
10590 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
10591 * for long time, this result in apps running at full power for long time.
10592 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
10593 * be stuck in full power because of resume BMPS
10594 */
10595 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -070010596
Nirav Shah20ac06f2013-12-12 18:14:06 +053010597 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10598 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010599 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
10600 scanRequest.requestType, scanRequest.scanType,
10601 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053010602 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
10603
Siddharth Bhal76972212014-10-15 16:22:51 +053010604 if (pHddCtx->spoofMacAddr.isEnabled)
10605 {
10606 hddLog(VOS_TRACE_LEVEL_INFO,
10607 "%s: MAC Spoofing enabled for current scan", __func__);
10608 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
10609 * to fill TxBds for probe request during current scan
10610 */
10611 WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
10612 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
10613 }
10614
Jeff Johnsone7245742012-09-05 17:12:55 -070010615 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010616 pAdapter->sessionId, &scanRequest, &scanId,
10617 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070010618
Jeff Johnson295189b2012-06-20 16:38:30 -070010619 if (eHAL_STATUS_SUCCESS != status)
10620 {
10621 hddLog(VOS_TRACE_LEVEL_ERROR,
10622 "%s: sme_ScanRequest returned error %d", __func__, status);
10623 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010624 if(eHAL_STATUS_RESOURCES == status)
10625 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010626 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
10627 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010628 status = -EBUSY;
10629 } else {
10630 status = -EIO;
10631 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010632 hdd_allow_suspend();
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010633
10634#ifdef FEATURE_WLAN_TDLS
10635 wlan_hdd_tdls_scan_done_callback(pAdapter);
10636#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010637 goto free_mem;
10638 }
10639
10640 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010641 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070010642 pAdapter->request = request;
10643 pScanInfo->scanId = scanId;
10644
10645 complete(&pScanInfo->scan_req_completion_event);
10646
10647free_mem:
10648 if( scanRequest.SSIDs.SSIDList )
10649 {
10650 vos_mem_free(scanRequest.SSIDs.SSIDList);
10651 }
10652
10653 if( channelList )
10654 vos_mem_free( channelList );
10655
10656 EXIT();
10657
10658 return status;
10659}
10660
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010661int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
10662#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10663 struct net_device *dev,
10664#endif
10665 struct cfg80211_scan_request *request)
10666{
10667 int ret;
10668
10669 vos_ssr_protect(__func__);
10670 ret = __wlan_hdd_cfg80211_scan(wiphy,
10671#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10672 dev,
10673#endif
10674 request);
10675 vos_ssr_unprotect(__func__);
10676
10677 return ret;
10678}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010679
10680void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
10681{
10682 v_U8_t iniDot11Mode =
10683 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
10684 eHddDot11Mode hddDot11Mode = iniDot11Mode;
10685
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010686 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
10687 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010688 switch ( iniDot11Mode )
10689 {
10690 case eHDD_DOT11_MODE_AUTO:
10691 case eHDD_DOT11_MODE_11ac:
10692 case eHDD_DOT11_MODE_11ac_ONLY:
10693#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053010694 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
10695 sme_IsFeatureSupportedByFW(DOT11AC) )
10696 hddDot11Mode = eHDD_DOT11_MODE_11ac;
10697 else
10698 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010699#else
10700 hddDot11Mode = eHDD_DOT11_MODE_11n;
10701#endif
10702 break;
10703 case eHDD_DOT11_MODE_11n:
10704 case eHDD_DOT11_MODE_11n_ONLY:
10705 hddDot11Mode = eHDD_DOT11_MODE_11n;
10706 break;
10707 default:
10708 hddDot11Mode = iniDot11Mode;
10709 break;
10710 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010711#ifdef WLAN_FEATURE_AP_HT40_24G
10712 if (operationChannel > SIR_11B_CHANNEL_END)
10713#endif
10714 {
10715 /* This call decides required channel bonding mode */
10716 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010717 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
10718 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010719 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010720}
10721
Jeff Johnson295189b2012-06-20 16:38:30 -070010722/*
10723 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010724 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010725 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010726int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010727 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010728{
10729 int status = 0;
10730 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080010731 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010732 v_U32_t roamId;
10733 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070010734 eCsrAuthType RSNAuthType;
10735
10736 ENTER();
10737
10738 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080010739 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10740
10741 status = wlan_hdd_validate_context(pHddCtx);
10742 if (status)
10743 {
10744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10745 "%s: HDD context is not valid!", __func__);
10746 return status;
10747 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010748
Jeff Johnson295189b2012-06-20 16:38:30 -070010749 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
10750 {
10751 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
10752 return -EINVAL;
10753 }
10754
10755 pRoamProfile = &pWextState->roamProfile;
10756
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010757 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070010758 {
Jeff Johnsone7245742012-09-05 17:12:55 -070010759 hdd_station_ctx_t *pHddStaCtx;
10760 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010761
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010762 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070010763 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
10764 {
10765 /*QoS not enabled in cfg file*/
10766 pRoamProfile->uapsd_mask = 0;
10767 }
10768 else
10769 {
10770 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010771 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070010772 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
10773 }
10774
10775 pRoamProfile->SSIDs.numOfSSIDs = 1;
10776 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
10777 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010778 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070010779 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
10780 ssid, ssid_len);
10781
10782 if (bssid)
10783 {
10784 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
10785 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
10786 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010787 /* Save BSSID in seperate variable as well, as RoamProfile
10788 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070010789 case of join failure we should send valid BSSID to supplicant
10790 */
10791 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
10792 WNI_CFG_BSSID_LEN);
10793 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070010794 else
10795 {
10796 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
10797 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010798
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010799 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
10800 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010801 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
10802 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010803 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010804 /*set gen ie*/
10805 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
10806 /*set auth*/
10807 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
10808 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010809#ifdef FEATURE_WLAN_WAPI
10810 if (pAdapter->wapi_info.nWapiMode)
10811 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010812 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010813 switch (pAdapter->wapi_info.wapiAuthMode)
10814 {
10815 case WAPI_AUTH_MODE_PSK:
10816 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010817 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010818 pAdapter->wapi_info.wapiAuthMode);
10819 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
10820 break;
10821 }
10822 case WAPI_AUTH_MODE_CERT:
10823 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010824 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010825 pAdapter->wapi_info.wapiAuthMode);
10826 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
10827 break;
10828 }
10829 } // End of switch
10830 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
10831 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
10832 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010833 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010834 pRoamProfile->AuthType.numEntries = 1;
10835 pRoamProfile->EncryptionType.numEntries = 1;
10836 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10837 pRoamProfile->mcEncryptionType.numEntries = 1;
10838 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10839 }
10840 }
10841#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010842#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010843 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010844 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10845 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
10846 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010847 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
10848 sizeof (tSirGtkOffloadParams));
10849 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010850 }
10851#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010852 pRoamProfile->csrPersona = pAdapter->device_mode;
10853
Jeff Johnson32d95a32012-09-10 13:15:23 -070010854 if( operatingChannel )
10855 {
10856 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
10857 pRoamProfile->ChannelInfo.numOfChannels = 1;
10858 }
Chet Lanctot186b5732013-03-18 10:26:30 -070010859 else
10860 {
10861 pRoamProfile->ChannelInfo.ChannelList = NULL;
10862 pRoamProfile->ChannelInfo.numOfChannels = 0;
10863 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010864 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
10865 {
10866 hdd_select_cbmode(pAdapter,operatingChannel);
10867 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010868
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010869 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
10870 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010871 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010872 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010873 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
10874 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010875 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10876 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053010877 {
10878 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10879 "%s: Set HDD connState to eConnectionState_Connecting",
10880 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010881 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
10882 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053010883 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010884 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010885 pAdapter->sessionId, pRoamProfile, &roamId);
10886
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010887 if ((eHAL_STATUS_SUCCESS != status) &&
10888 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10889 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010890
10891 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010892 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
10893 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
10894 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010895 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010896 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010897 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010898
10899 pRoamProfile->ChannelInfo.ChannelList = NULL;
10900 pRoamProfile->ChannelInfo.numOfChannels = 0;
10901
Jeff Johnson295189b2012-06-20 16:38:30 -070010902 }
10903 else
10904 {
10905 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
10906 return -EINVAL;
10907 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010908 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010909 return status;
10910}
10911
10912/*
10913 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
10914 * This function is used to set the authentication type (OPEN/SHARED).
10915 *
10916 */
10917static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
10918 enum nl80211_auth_type auth_type)
10919{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010920 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010921 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10922
10923 ENTER();
10924
10925 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010926 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070010927 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010928 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010929 hddLog(VOS_TRACE_LEVEL_INFO,
10930 "%s: set authentication type to AUTOSWITCH", __func__);
10931 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
10932 break;
10933
10934 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010935#ifdef WLAN_FEATURE_VOWIFI_11R
10936 case NL80211_AUTHTYPE_FT:
10937#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010938 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010939 "%s: set authentication type to OPEN", __func__);
10940 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
10941 break;
10942
10943 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010944 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010945 "%s: set authentication type to SHARED", __func__);
10946 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
10947 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010948#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010949 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010950 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010951 "%s: set authentication type to CCKM WPA", __func__);
10952 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
10953 break;
10954#endif
10955
10956
10957 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010958 hddLog(VOS_TRACE_LEVEL_ERROR,
10959 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010960 auth_type);
10961 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
10962 return -EINVAL;
10963 }
10964
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010965 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010966 pHddStaCtx->conn_info.authType;
10967 return 0;
10968}
10969
10970/*
10971 * FUNCTION: wlan_hdd_set_akm_suite
10972 * This function is used to set the key mgmt type(PSK/8021x).
10973 *
10974 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010975static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010976 u32 key_mgmt
10977 )
10978{
10979 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10980 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053010981 /* Should be in ieee802_11_defs.h */
10982#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
10983#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070010984 /*set key mgmt type*/
10985 switch(key_mgmt)
10986 {
10987 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053010988 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010989#ifdef WLAN_FEATURE_VOWIFI_11R
10990 case WLAN_AKM_SUITE_FT_PSK:
10991#endif
10992 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070010993 __func__);
10994 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
10995 break;
10996
10997 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053010998 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010999#ifdef WLAN_FEATURE_VOWIFI_11R
11000 case WLAN_AKM_SUITE_FT_8021X:
11001#endif
11002 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070011003 __func__);
11004 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11005 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011006#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011007#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
11008#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
11009 case WLAN_AKM_SUITE_CCKM:
11010 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
11011 __func__);
11012 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
11013 break;
11014#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070011015#ifndef WLAN_AKM_SUITE_OSEN
11016#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
11017 case WLAN_AKM_SUITE_OSEN:
11018 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
11019 __func__);
11020 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11021 break;
11022#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011023
11024 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011025 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011026 __func__, key_mgmt);
11027 return -EINVAL;
11028
11029 }
11030 return 0;
11031}
11032
11033/*
11034 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011035 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070011036 * (NONE/WEP40/WEP104/TKIP/CCMP).
11037 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011038static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
11039 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070011040 bool ucast
11041 )
11042{
11043 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011044 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011045 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11046
11047 ENTER();
11048
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011049 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011050 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011051 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070011052 __func__, cipher);
11053 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11054 }
11055 else
11056 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011057
Jeff Johnson295189b2012-06-20 16:38:30 -070011058 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011059 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011060 {
11061 case IW_AUTH_CIPHER_NONE:
11062 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11063 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011064
Jeff Johnson295189b2012-06-20 16:38:30 -070011065 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011066 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070011067 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011068
Jeff Johnson295189b2012-06-20 16:38:30 -070011069 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011070 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070011071 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011072
Jeff Johnson295189b2012-06-20 16:38:30 -070011073 case WLAN_CIPHER_SUITE_TKIP:
11074 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
11075 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011076
Jeff Johnson295189b2012-06-20 16:38:30 -070011077 case WLAN_CIPHER_SUITE_CCMP:
11078 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11079 break;
11080#ifdef FEATURE_WLAN_WAPI
11081 case WLAN_CIPHER_SUITE_SMS4:
11082 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
11083 break;
11084#endif
11085
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011086#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011087 case WLAN_CIPHER_SUITE_KRK:
11088 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
11089 break;
11090#endif
11091 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011092 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011093 __func__, cipher);
11094 return -EOPNOTSUPP;
11095 }
11096 }
11097
11098 if (ucast)
11099 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011100 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011101 __func__, encryptionType);
11102 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11103 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011104 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011105 encryptionType;
11106 }
11107 else
11108 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011109 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011110 __func__, encryptionType);
11111 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
11112 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
11113 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
11114 }
11115
11116 return 0;
11117}
11118
11119
11120/*
11121 * FUNCTION: wlan_hdd_cfg80211_set_ie
11122 * This function is used to parse WPA/RSN IE's.
11123 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011124int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
11125 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070011126 size_t ie_len
11127 )
11128{
11129 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11130 u8 *genie = ie;
11131 v_U16_t remLen = ie_len;
11132#ifdef FEATURE_WLAN_WAPI
11133 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
11134 u16 *tmp;
11135 v_U16_t akmsuiteCount;
11136 int *akmlist;
11137#endif
11138 ENTER();
11139
11140 /* clear previous assocAddIE */
11141 pWextState->assocAddIE.length = 0;
11142 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011143 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011144
11145 while (remLen >= 2)
11146 {
11147 v_U16_t eLen = 0;
11148 v_U8_t elementId;
11149 elementId = *genie++;
11150 eLen = *genie++;
11151 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011152
Arif Hussain6d2a3322013-11-17 19:50:10 -080011153 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070011154 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011155
11156 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070011157 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011158 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011159 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 -070011160 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011161 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011162 "%s: Invalid WPA IE", __func__);
11163 return -EINVAL;
11164 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011165 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070011166 {
11167 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011168 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011169 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011170
Jeff Johnson295189b2012-06-20 16:38:30 -070011171 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11172 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011173 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
11174 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011175 VOS_ASSERT(0);
11176 return -ENOMEM;
11177 }
11178 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11179 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11180 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011181
Jeff Johnson295189b2012-06-20 16:38:30 -070011182 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
11183 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11184 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11185 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011186 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
11187 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011188 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
11189 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11190 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
11191 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
11192 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
11193 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011194 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053011195 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011196 {
11197 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011198 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011199 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011200
Jeff Johnson295189b2012-06-20 16:38:30 -070011201 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11202 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011203 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11204 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011205 VOS_ASSERT(0);
11206 return -ENOMEM;
11207 }
11208 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11209 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11210 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011211
Jeff Johnson295189b2012-06-20 16:38:30 -070011212 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11213 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11214 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011215#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011216 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
11217 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011218 /*Consider WFD IE, only for P2P Client */
11219 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11220 {
11221 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011222 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011223 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011224
Jeff Johnson295189b2012-06-20 16:38:30 -070011225 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11226 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011227 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11228 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011229 VOS_ASSERT(0);
11230 return -ENOMEM;
11231 }
11232 // WFD IE is saved to Additional IE ; it should be accumulated to handle
11233 // WPS IE + P2P IE + WFD IE
11234 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11235 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011236
Jeff Johnson295189b2012-06-20 16:38:30 -070011237 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11238 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11239 }
11240#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011241 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011242 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011243 HS20_OUI_TYPE_SIZE)) )
11244 {
11245 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011246 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011247 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011248
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011249 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11250 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011251 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11252 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011253 VOS_ASSERT(0);
11254 return -ENOMEM;
11255 }
11256 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11257 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011258
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011259 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11260 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11261 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011262 /* Appending OSEN Information Element in Assiciation Request */
11263 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
11264 OSEN_OUI_TYPE_SIZE)) )
11265 {
11266 v_U16_t curAddIELen = pWextState->assocAddIE.length;
11267 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
11268 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011269
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011270 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11271 {
11272 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11273 "Need bigger buffer space");
11274 VOS_ASSERT(0);
11275 return -ENOMEM;
11276 }
11277 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11278 pWextState->assocAddIE.length += eLen + 2;
11279
11280 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
11281 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11282 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11283 }
11284
11285 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070011286 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
11287
11288 /* populating as ADDIE in beacon frames */
11289 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11290 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
11291 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
11292 {
11293 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11294 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
11295 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11296 {
11297 hddLog(LOGE,
11298 "Coldn't pass "
11299 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
11300 }
11301 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
11302 else
11303 hddLog(LOGE,
11304 "Could not pass on "
11305 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
11306
11307 /* IBSS mode doesn't contain params->proberesp_ies still
11308 beaconIE's need to be populated in probe response frames */
11309 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
11310 {
11311 u16 rem_probe_resp_ie_len = eLen + 2;
11312 u8 probe_rsp_ie_len[3] = {0};
11313 u8 counter = 0;
11314
11315 /* Check Probe Resp Length if it is greater then 255 then
11316 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
11317 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
11318 not able Store More then 255 bytes into One Variable */
11319
11320 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
11321 {
11322 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
11323 {
11324 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
11325 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
11326 }
11327 else
11328 {
11329 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
11330 rem_probe_resp_ie_len = 0;
11331 }
11332 }
11333
11334 rem_probe_resp_ie_len = 0;
11335
11336 if (probe_rsp_ie_len[0] > 0)
11337 {
11338 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11339 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
11340 (tANI_U8*)(genie - 2),
11341 probe_rsp_ie_len[0], NULL,
11342 eANI_BOOLEAN_FALSE)
11343 == eHAL_STATUS_FAILURE)
11344 {
11345 hddLog(LOGE,
11346 "Could not pass"
11347 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
11348 }
11349 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
11350 }
11351
11352 if (probe_rsp_ie_len[1] > 0)
11353 {
11354 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11355 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
11356 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11357 probe_rsp_ie_len[1], NULL,
11358 eANI_BOOLEAN_FALSE)
11359 == eHAL_STATUS_FAILURE)
11360 {
11361 hddLog(LOGE,
11362 "Could not pass"
11363 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
11364 }
11365 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
11366 }
11367
11368 if (probe_rsp_ie_len[2] > 0)
11369 {
11370 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11371 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
11372 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11373 probe_rsp_ie_len[2], NULL,
11374 eANI_BOOLEAN_FALSE)
11375 == eHAL_STATUS_FAILURE)
11376 {
11377 hddLog(LOGE,
11378 "Could not pass"
11379 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
11380 }
11381 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
11382 }
11383
11384 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11385 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
11386 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11387 {
11388 hddLog(LOGE,
11389 "Could not pass"
11390 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
11391 }
11392 }
11393 else
11394 {
11395 // Reset WNI_CFG_PROBE_RSP Flags
11396 wlan_hdd_reset_prob_rspies(pAdapter);
11397
11398 hddLog(VOS_TRACE_LEVEL_INFO,
11399 "%s: No Probe Response IE received in set beacon",
11400 __func__);
11401 }
11402 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011403 break;
11404 case DOT11F_EID_RSN:
11405 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
11406 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11407 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
11408 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
11409 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
11410 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011411 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
11412 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011413 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011414 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011415 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011416 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011417
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011418 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11419 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011420 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11421 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011422 VOS_ASSERT(0);
11423 return -ENOMEM;
11424 }
11425 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11426 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011427
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011428 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11429 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11430 break;
11431 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011432#ifdef FEATURE_WLAN_WAPI
11433 case WLAN_EID_WAPI:
11434 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011435 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011436 pAdapter->wapi_info.nWapiMode);
11437 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011438 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070011439 akmsuiteCount = WPA_GET_LE16(tmp);
11440 tmp = tmp + 1;
11441 akmlist = (int *)(tmp);
11442 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
11443 {
11444 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
11445 }
11446 else
11447 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011448 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070011449 VOS_ASSERT(0);
11450 return -EINVAL;
11451 }
11452
11453 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
11454 {
11455 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011456 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011457 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011458 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011459 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011460 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011461 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011462 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011463 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
11464 }
11465 break;
11466#endif
11467 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011468 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011469 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011470 /* when Unknown IE is received we should break and continue
11471 * to the next IE in the buffer instead we were returning
11472 * so changing this to break */
11473 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011474 }
11475 genie += eLen;
11476 remLen -= eLen;
11477 }
11478 EXIT();
11479 return 0;
11480}
11481
11482/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053011483 * FUNCTION: hdd_isWPAIEPresent
11484 * Parse the received IE to find the WPA IE
11485 *
11486 */
11487static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
11488{
11489 v_U8_t eLen = 0;
11490 v_U16_t remLen = ie_len;
11491 v_U8_t elementId = 0;
11492
11493 while (remLen >= 2)
11494 {
11495 elementId = *ie++;
11496 eLen = *ie++;
11497 remLen -= 2;
11498 if (eLen > remLen)
11499 {
11500 hddLog(VOS_TRACE_LEVEL_ERROR,
11501 "%s: IE length is wrong %d", __func__, eLen);
11502 return FALSE;
11503 }
11504 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
11505 {
11506 /* OUI - 0x00 0X50 0XF2
11507 WPA Information Element - 0x01
11508 WPA version - 0x01*/
11509 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
11510 return TRUE;
11511 }
11512 ie += eLen;
11513 remLen -= eLen;
11514 }
11515 return FALSE;
11516}
11517
11518/*
Jeff Johnson295189b2012-06-20 16:38:30 -070011519 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011520 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011521 * parameters during connect operation.
11522 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011523int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011524 struct cfg80211_connect_params *req
11525 )
11526{
11527 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011528 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011529 ENTER();
11530
11531 /*set wpa version*/
11532 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
11533
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011534 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011535 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053011536 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011537 {
11538 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11539 }
11540 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
11541 {
11542 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11543 }
11544 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011545
11546 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011547 pWextState->wpaVersion);
11548
11549 /*set authentication type*/
11550 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
11551
11552 if (0 > status)
11553 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011554 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011555 "%s: failed to set authentication type ", __func__);
11556 return status;
11557 }
11558
11559 /*set key mgmt type*/
11560 if (req->crypto.n_akm_suites)
11561 {
11562 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
11563 if (0 > status)
11564 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011565 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070011566 __func__);
11567 return status;
11568 }
11569 }
11570
11571 /*set pairwise cipher type*/
11572 if (req->crypto.n_ciphers_pairwise)
11573 {
11574 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
11575 req->crypto.ciphers_pairwise[0], true);
11576 if (0 > status)
11577 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011578 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011579 "%s: failed to set unicast cipher type", __func__);
11580 return status;
11581 }
11582 }
11583 else
11584 {
11585 /*Reset previous cipher suite to none*/
11586 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
11587 if (0 > status)
11588 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011589 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011590 "%s: failed to set unicast cipher type", __func__);
11591 return status;
11592 }
11593 }
11594
11595 /*set group cipher type*/
11596 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
11597 false);
11598
11599 if (0 > status)
11600 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011601 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070011602 __func__);
11603 return status;
11604 }
11605
Chet Lanctot186b5732013-03-18 10:26:30 -070011606#ifdef WLAN_FEATURE_11W
11607 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
11608#endif
11609
Jeff Johnson295189b2012-06-20 16:38:30 -070011610 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
11611 if (req->ie_len)
11612 {
11613 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
11614 if ( 0 > status)
11615 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011616 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011617 __func__);
11618 return status;
11619 }
11620 }
11621
11622 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011623 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011624 {
11625 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
11626 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
11627 )
11628 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011629 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070011630 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
11631 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011632 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011633 __func__);
11634 return -EOPNOTSUPP;
11635 }
11636 else
11637 {
11638 u8 key_len = req->key_len;
11639 u8 key_idx = req->key_idx;
11640
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011641 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011642 && (CSR_MAX_NUM_KEY > key_idx)
11643 )
11644 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011645 hddLog(VOS_TRACE_LEVEL_INFO,
11646 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011647 __func__, key_idx, key_len);
11648 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011649 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011650 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011651 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011652 (u8)key_len;
11653 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
11654 }
11655 }
11656 }
11657 }
11658
11659 return status;
11660}
11661
11662/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011663 * FUNCTION: wlan_hdd_try_disconnect
11664 * This function is used to disconnect from previous
11665 * connection
11666 */
11667static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
11668{
11669 long ret = 0;
11670 hdd_station_ctx_t *pHddStaCtx;
11671 eMib_dot11DesiredBssType connectedBssType;
11672
11673 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11674
11675 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
11676
11677 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
11678 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
11679 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
11680 {
11681 /* Issue disconnect to CSR */
11682 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11683 if( eHAL_STATUS_SUCCESS ==
11684 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11685 pAdapter->sessionId,
11686 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11687 {
11688 ret = wait_for_completion_interruptible_timeout(
11689 &pAdapter->disconnect_comp_var,
11690 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11691 if (0 >= ret)
11692 {
11693 hddLog(LOGE, FL("Failed to receive disconnect event"));
11694 return -EALREADY;
11695 }
11696 }
11697 }
11698 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
11699 {
11700 ret = wait_for_completion_interruptible_timeout(
11701 &pAdapter->disconnect_comp_var,
11702 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11703 if (0 >= ret)
11704 {
11705 hddLog(LOGE, FL("Failed to receive disconnect event"));
11706 return -EALREADY;
11707 }
11708 }
11709
11710 return 0;
11711}
11712
11713/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053011714 * FUNCTION: __wlan_hdd_cfg80211_connect
11715 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011716 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011717static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011718 struct net_device *ndev,
11719 struct cfg80211_connect_params *req
11720 )
11721{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011722 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011723 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011724 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053011725 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011726
11727 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011728
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011729 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11730 TRACE_CODE_HDD_CFG80211_CONNECT,
11731 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011732 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011733 "%s: device_mode = %s (%d)", __func__,
11734 hdd_device_modetoString(pAdapter->device_mode),
11735 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011736
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011737 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011738 if (!pHddCtx)
11739 {
11740 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11741 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011742 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011743 }
11744
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011745 status = wlan_hdd_validate_context(pHddCtx);
11746
11747 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011748 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11750 "%s: HDD context is not valid", __func__);
11751 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011752 }
11753
Agarwal Ashish51325b52014-06-16 16:50:49 +053011754 if (vos_max_concurrent_connections_reached()) {
11755 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11756 return -ECONNREFUSED;
11757 }
11758
Jeff Johnson295189b2012-06-20 16:38:30 -070011759#ifdef WLAN_BTAMP_FEATURE
11760 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011761 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070011762 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011763 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011764 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011765 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070011766 }
11767#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011768
11769 //If Device Mode is Station Concurrent Sessions Exit BMps
11770 //P2P Mode will be taken care in Open/close adapter
11771 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011772 (vos_concurrent_open_sessions_running())) {
11773 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
11774 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011775 }
11776
11777 /*Try disconnecting if already in connected state*/
11778 status = wlan_hdd_try_disconnect(pAdapter);
11779 if ( 0 > status)
11780 {
11781 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11782 " connection"));
11783 return -EALREADY;
11784 }
11785
Jeff Johnson295189b2012-06-20 16:38:30 -070011786 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011787 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070011788
11789 if ( 0 > status)
11790 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011791 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070011792 __func__);
11793 return status;
11794 }
Mohit Khanna765234a2012-09-11 15:08:35 -070011795 if ( req->channel )
11796 {
11797 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
11798 req->ssid_len, req->bssid,
11799 req->channel->hw_value);
11800 }
11801 else
11802 {
11803 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011804 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070011805 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011806
11807 if (0 > status)
11808 {
11809 //ReEnable BMPS if disabled
11810 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
11811 (NULL != pHddCtx))
11812 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011813 if (pHddCtx->hdd_wlan_suspended)
11814 {
11815 hdd_set_pwrparams(pHddCtx);
11816 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011817 //ReEnable Bmps and Imps back
11818 hdd_enable_bmps_imps(pHddCtx);
11819 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011820 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011821 return status;
11822 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011823 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011824 EXIT();
11825 return status;
11826}
11827
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011828static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
11829 struct net_device *ndev,
11830 struct cfg80211_connect_params *req)
11831{
11832 int ret;
11833 vos_ssr_protect(__func__);
11834 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
11835 vos_ssr_unprotect(__func__);
11836
11837 return ret;
11838}
Jeff Johnson295189b2012-06-20 16:38:30 -070011839
11840/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011841 * FUNCTION: wlan_hdd_disconnect
11842 * This function is used to issue a disconnect request to SME
11843 */
11844int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
11845{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011846 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011847 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011848 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011849 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011850
11851 status = wlan_hdd_validate_context(pHddCtx);
11852
11853 if (0 != status)
11854 {
11855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11856 "%s: HDD context is not valid", __func__);
11857 return status;
11858 }
11859
11860 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011861
Agarwal Ashish47d18112014-08-04 19:55:07 +053011862 /* Need to apply spin lock before decreasing active sessions
11863 * as there can be chance for double decrement if context switch
11864 * Calls hdd_DisConnectHandler.
11865 */
11866
11867 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011868 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11869 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011870 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11871 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053011872 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
11873 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011874
Abhishek Singhf4669da2014-05-26 15:07:49 +053011875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053011876 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
11877
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011878 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011879
Mihir Shete182a0b22014-08-18 16:08:48 +053011880 /*
11881 * stop tx queues before deleting STA/BSS context from the firmware.
11882 * tx has to be disabled because the firmware can get busy dropping
11883 * the tx frames after BSS/STA has been deleted and will not send
11884 * back a response resulting in WDI timeout
11885 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053011886 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053011887 netif_tx_disable(pAdapter->dev);
11888 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011889
Mihir Shete182a0b22014-08-18 16:08:48 +053011890 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011891 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11892 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011893 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
11894 {
11895 hddLog(VOS_TRACE_LEVEL_INFO,
11896 FL("status = %d, already disconnected"),
11897 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011898
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011899 }
11900 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011901 {
11902 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011903 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011904 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011905 result = -EINVAL;
11906 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011907 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011908 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011909 &pAdapter->disconnect_comp_var,
11910 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011911 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011912 {
11913 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011914 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011915 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011916 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011917 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011918 {
11919 hddLog(VOS_TRACE_LEVEL_ERROR,
11920 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011921 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011922 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011923disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011924 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11925 FL("Set HDD connState to eConnectionState_NotConnected"));
11926 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
11927
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011928 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011929}
11930
11931
11932/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011933 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070011934 * This function is used to issue a disconnect request to SME
11935 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011936static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011937 struct net_device *dev,
11938 u16 reason
11939 )
11940{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011941 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011942 tCsrRoamProfile *pRoamProfile =
11943 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011944 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011945 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11946 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011947#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011948 tANI_U8 staIdx;
11949#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011950
Jeff Johnson295189b2012-06-20 16:38:30 -070011951 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011952
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011953 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11954 TRACE_CODE_HDD_CFG80211_DISCONNECT,
11955 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011956 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
11957 __func__, hdd_device_modetoString(pAdapter->device_mode),
11958 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011959
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011960 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
11961 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070011962
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011963 status = wlan_hdd_validate_context(pHddCtx);
11964
11965 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011966 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011967 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11968 "%s: HDD context is not valid", __func__);
11969 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011970 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011971
Jeff Johnson295189b2012-06-20 16:38:30 -070011972 if (NULL != pRoamProfile)
11973 {
11974 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011975 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
11976 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070011977 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011978 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070011979 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011980 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070011981 switch(reason)
11982 {
11983 case WLAN_REASON_MIC_FAILURE:
11984 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
11985 break;
11986
11987 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
11988 case WLAN_REASON_DISASSOC_AP_BUSY:
11989 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
11990 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
11991 break;
11992
11993 case WLAN_REASON_PREV_AUTH_NOT_VALID:
11994 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053011995 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070011996 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
11997 break;
11998
Jeff Johnson295189b2012-06-20 16:38:30 -070011999 default:
12000 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
12001 break;
12002 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012003 pScanInfo = &pHddCtx->scan_info;
12004 if (pScanInfo->mScanPending)
12005 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012006 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012007 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012008 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012009 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012010 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012011
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012012#ifdef FEATURE_WLAN_TDLS
12013 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012014 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012015 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012016 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
12017 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012018 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012019 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012020 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012021 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012022 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012023 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012024 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012025 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012026 pAdapter->sessionId,
12027 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012028 }
12029 }
12030#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012031 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012032 status = wlan_hdd_disconnect(pAdapter, reasonCode);
12033 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070012034 {
12035 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012036 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012037 __func__, (int)status );
12038 return -EINVAL;
12039 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012040 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012041 else
12042 {
12043 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
12044 "called while in %d state", __func__,
12045 pHddStaCtx->conn_info.connState);
12046 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012047 }
12048 else
12049 {
12050 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
12051 }
12052
12053 return status;
12054}
12055
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012056static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
12057 struct net_device *dev,
12058 u16 reason
12059 )
12060{
12061 int ret;
12062 vos_ssr_protect(__func__);
12063 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
12064 vos_ssr_unprotect(__func__);
12065
12066 return ret;
12067}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012068
Jeff Johnson295189b2012-06-20 16:38:30 -070012069/*
12070 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012071 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012072 * settings in IBSS mode.
12073 */
12074static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012075 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012076 struct cfg80211_ibss_params *params
12077 )
12078{
12079 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012080 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012081 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12082 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012083
Jeff Johnson295189b2012-06-20 16:38:30 -070012084 ENTER();
12085
12086 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070012087 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070012088
12089 if (params->ie_len && ( NULL != params->ie) )
12090 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012091 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12092 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012093 {
12094 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12095 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12096 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012097 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012098 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012099 tDot11fIEWPA dot11WPAIE;
12100 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012101 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012102
Wilson Yang00256342013-10-10 23:13:38 -070012103 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012104 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12105 params->ie_len, DOT11F_EID_WPA);
12106 if ( NULL != ie )
12107 {
12108 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12109 // Unpack the WPA IE
12110 //Skip past the EID byte and length byte - and four byte WiFi OUI
12111 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
12112 &ie[2+4],
12113 ie[1] - 4,
12114 &dot11WPAIE);
12115 /*Extract the multicast cipher, the encType for unicast
12116 cipher for wpa-none is none*/
12117 encryptionType =
12118 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
12119 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012120 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012121
Jeff Johnson295189b2012-06-20 16:38:30 -070012122 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
12123
12124 if (0 > status)
12125 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012126 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012127 __func__);
12128 return status;
12129 }
12130 }
12131
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012132 pWextState->roamProfile.AuthType.authType[0] =
12133 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012134 eCSR_AUTH_TYPE_OPEN_SYSTEM;
12135
12136 if (params->privacy)
12137 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012138 /* Security enabled IBSS, At this time there is no information available
12139 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070012140 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012141 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070012142 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012143 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070012144 *enable privacy bit in beacons */
12145
12146 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12147 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012148 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
12149 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070012150 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12151 pWextState->roamProfile.EncryptionType.numEntries = 1;
12152 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070012153 return status;
12154}
12155
12156/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012157 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012158 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012159 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012160static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012161 struct net_device *dev,
12162 struct cfg80211_ibss_params *params
12163 )
12164{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012165 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012166 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12167 tCsrRoamProfile *pRoamProfile;
12168 int status;
krunal sonie9002db2013-11-25 14:24:17 -080012169 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012170 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12171 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012172
12173 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012174
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012175 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12176 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
12177 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012178 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012179 "%s: device_mode = %s (%d)", __func__,
12180 hdd_device_modetoString(pAdapter->device_mode),
12181 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012182
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012183 status = wlan_hdd_validate_context(pHddCtx);
12184
12185 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012186 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12188 "%s: HDD context is not valid", __func__);
12189 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012190 }
12191
12192 if (NULL == pWextState)
12193 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012194 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012195 __func__);
12196 return -EIO;
12197 }
12198
Agarwal Ashish51325b52014-06-16 16:50:49 +053012199 if (vos_max_concurrent_connections_reached()) {
12200 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12201 return -ECONNREFUSED;
12202 }
12203
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012204 /*Try disconnecting if already in connected state*/
12205 status = wlan_hdd_try_disconnect(pAdapter);
12206 if ( 0 > status)
12207 {
12208 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12209 " IBSS connection"));
12210 return -EALREADY;
12211 }
12212
Jeff Johnson295189b2012-06-20 16:38:30 -070012213 pRoamProfile = &pWextState->roamProfile;
12214
12215 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
12216 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012217 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012218 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012219 return -EINVAL;
12220 }
12221
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012222 /* BSSID is provided by upper layers hence no need to AUTO generate */
12223 if (NULL != params->bssid) {
12224 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12225 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
12226 hddLog (VOS_TRACE_LEVEL_ERROR,
12227 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12228 return -EIO;
12229 }
12230 }
krunal sonie9002db2013-11-25 14:24:17 -080012231 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
12232 {
12233 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12234 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
12235 {
12236 hddLog (VOS_TRACE_LEVEL_ERROR,
12237 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12238 return -EIO;
12239 }
12240 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
12241 if (!params->bssid)
12242 {
12243 hddLog (VOS_TRACE_LEVEL_ERROR,
12244 "%s:Failed memory allocation", __func__);
12245 return -EIO;
12246 }
12247 vos_mem_copy((v_U8_t *)params->bssid,
12248 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
12249 VOS_MAC_ADDR_SIZE);
12250 alloc_bssid = VOS_TRUE;
12251 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012252
Jeff Johnson295189b2012-06-20 16:38:30 -070012253 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070012254 if (NULL !=
12255#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12256 params->chandef.chan)
12257#else
12258 params->channel)
12259#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012260 {
12261 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012262 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12263 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
12264 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12265 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012266
12267 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012268 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070012269 ieee80211_frequency_to_channel(
12270#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12271 params->chandef.chan->center_freq);
12272#else
12273 params->channel->center_freq);
12274#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012275
12276 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12277 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070012278 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012279 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
12280 __func__);
12281 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012282 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012283
12284 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012285 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012286 if (channelNum == validChan[indx])
12287 {
12288 break;
12289 }
12290 }
12291 if (indx >= numChans)
12292 {
12293 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012294 __func__, channelNum);
12295 return -EINVAL;
12296 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012297 /* Set the Operational Channel */
12298 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
12299 channelNum);
12300 pRoamProfile->ChannelInfo.numOfChannels = 1;
12301 pHddStaCtx->conn_info.operationChannel = channelNum;
12302 pRoamProfile->ChannelInfo.ChannelList =
12303 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070012304 }
12305
12306 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012307 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070012308 if (status < 0)
12309 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012310 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070012311 __func__);
12312 return status;
12313 }
12314
12315 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012316 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012317 params->ssid_len, params->bssid,
12318 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012319
12320 if (0 > status)
12321 {
12322 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
12323 return status;
12324 }
12325
krunal sonie9002db2013-11-25 14:24:17 -080012326 if (NULL != params->bssid &&
12327 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
12328 alloc_bssid == VOS_TRUE)
12329 {
12330 vos_mem_free(params->bssid);
12331 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012332 return 0;
12333}
12334
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012335static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
12336 struct net_device *dev,
12337 struct cfg80211_ibss_params *params
12338 )
12339{
12340 int ret = 0;
12341
12342 vos_ssr_protect(__func__);
12343 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
12344 vos_ssr_unprotect(__func__);
12345
12346 return ret;
12347}
12348
Jeff Johnson295189b2012-06-20 16:38:30 -070012349/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012350 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012351 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012352 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012353static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012354 struct net_device *dev
12355 )
12356{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012357 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012358 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12359 tCsrRoamProfile *pRoamProfile;
12360 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012361 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012362
12363 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012364
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012365 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12366 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
12367 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012368 status = wlan_hdd_validate_context(pHddCtx);
12369
12370 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012371 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12373 "%s: HDD context is not valid", __func__);
12374 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012375 }
12376
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012377 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
12378 hdd_device_modetoString(pAdapter->device_mode),
12379 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012380 if (NULL == pWextState)
12381 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012382 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012383 __func__);
12384 return -EIO;
12385 }
12386
12387 pRoamProfile = &pWextState->roamProfile;
12388
12389 /* Issue disconnect only if interface type is set to IBSS */
12390 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
12391 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012392 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070012393 __func__);
12394 return -EINVAL;
12395 }
12396
12397 /* Issue Disconnect request */
12398 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12399 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12400 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
12401
12402 return 0;
12403}
12404
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012405static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
12406 struct net_device *dev
12407 )
12408{
12409 int ret = 0;
12410
12411 vos_ssr_protect(__func__);
12412 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
12413 vos_ssr_unprotect(__func__);
12414
12415 return ret;
12416}
12417
Jeff Johnson295189b2012-06-20 16:38:30 -070012418/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012419 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070012420 * This function is used to set the phy parameters
12421 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
12422 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012423static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012424 u32 changed)
12425{
12426 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
12427 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012428 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012429
12430 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012431 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12432 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
12433 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012434 status = wlan_hdd_validate_context(pHddCtx);
12435
12436 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012437 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12439 "%s: HDD context is not valid", __func__);
12440 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012441 }
12442
Jeff Johnson295189b2012-06-20 16:38:30 -070012443 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
12444 {
12445 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
12446 WNI_CFG_RTS_THRESHOLD_STAMAX :
12447 wiphy->rts_threshold;
12448
12449 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012450 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070012451 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012452 hddLog(VOS_TRACE_LEVEL_ERROR,
12453 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012454 __func__, rts_threshold);
12455 return -EINVAL;
12456 }
12457
12458 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
12459 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012460 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012461 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012462 hddLog(VOS_TRACE_LEVEL_ERROR,
12463 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012464 __func__, rts_threshold);
12465 return -EIO;
12466 }
12467
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012468 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012469 rts_threshold);
12470 }
12471
12472 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
12473 {
12474 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
12475 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
12476 wiphy->frag_threshold;
12477
12478 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012479 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012480 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012481 hddLog(VOS_TRACE_LEVEL_ERROR,
12482 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012483 frag_threshold);
12484 return -EINVAL;
12485 }
12486
12487 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
12488 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012489 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012490 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012491 hddLog(VOS_TRACE_LEVEL_ERROR,
12492 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012493 __func__, frag_threshold);
12494 return -EIO;
12495 }
12496
12497 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
12498 frag_threshold);
12499 }
12500
12501 if ((changed & WIPHY_PARAM_RETRY_SHORT)
12502 || (changed & WIPHY_PARAM_RETRY_LONG))
12503 {
12504 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
12505 wiphy->retry_short :
12506 wiphy->retry_long;
12507
12508 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
12509 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
12510 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012511 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012512 __func__, retry_value);
12513 return -EINVAL;
12514 }
12515
12516 if (changed & WIPHY_PARAM_RETRY_SHORT)
12517 {
12518 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
12519 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012520 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012521 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012522 hddLog(VOS_TRACE_LEVEL_ERROR,
12523 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012524 __func__, retry_value);
12525 return -EIO;
12526 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012527 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012528 __func__, retry_value);
12529 }
12530 else if (changed & WIPHY_PARAM_RETRY_SHORT)
12531 {
12532 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
12533 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012534 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012535 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012536 hddLog(VOS_TRACE_LEVEL_ERROR,
12537 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012538 __func__, retry_value);
12539 return -EIO;
12540 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012541 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012542 __func__, retry_value);
12543 }
12544 }
12545
12546 return 0;
12547}
12548
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012549static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
12550 u32 changed)
12551{
12552 int ret;
12553
12554 vos_ssr_protect(__func__);
12555 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
12556 vos_ssr_unprotect(__func__);
12557
12558 return ret;
12559}
12560
Jeff Johnson295189b2012-06-20 16:38:30 -070012561/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012562 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012563 * This function is used to set the txpower
12564 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012565static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012566#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12567 struct wireless_dev *wdev,
12568#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012569#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012570 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012571#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012572 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012573#endif
12574 int dbm)
12575{
12576 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012577 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012578 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12579 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012580 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012581
12582 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012583 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12584 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
12585 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012586 status = wlan_hdd_validate_context(pHddCtx);
12587
12588 if (0 != status)
12589 {
12590 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12591 "%s: HDD context is not valid", __func__);
12592 return status;
12593 }
12594
12595 hHal = pHddCtx->hHal;
12596
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012597 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
12598 dbm, ccmCfgSetCallback,
12599 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012600 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012601 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012602 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
12603 return -EIO;
12604 }
12605
12606 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
12607 dbm);
12608
12609 switch(type)
12610 {
12611 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
12612 /* Fall through */
12613 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
12614 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
12615 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012616 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
12617 __func__);
12618 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012619 }
12620 break;
12621 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012622 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012623 __func__);
12624 return -EOPNOTSUPP;
12625 break;
12626 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012627 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
12628 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070012629 return -EIO;
12630 }
12631
12632 return 0;
12633}
12634
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012635static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
12636#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12637 struct wireless_dev *wdev,
12638#endif
12639#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12640 enum tx_power_setting type,
12641#else
12642 enum nl80211_tx_power_setting type,
12643#endif
12644 int dbm)
12645{
12646 int ret;
12647 vos_ssr_protect(__func__);
12648 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
12649#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12650 wdev,
12651#endif
12652#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12653 type,
12654#else
12655 type,
12656#endif
12657 dbm);
12658 vos_ssr_unprotect(__func__);
12659
12660 return ret;
12661}
12662
Jeff Johnson295189b2012-06-20 16:38:30 -070012663/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012664 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012665 * This function is used to read the txpower
12666 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012667static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012668#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12669 struct wireless_dev *wdev,
12670#endif
12671 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070012672{
12673
12674 hdd_adapter_t *pAdapter;
12675 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012676 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012677
Jeff Johnsone7245742012-09-05 17:12:55 -070012678 ENTER();
12679
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012680 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012681
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012682 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012683 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12685 "%s: HDD context is not valid", __func__);
12686 *dbm = 0;
12687 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012688 }
12689
Jeff Johnson295189b2012-06-20 16:38:30 -070012690 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
12691 if (NULL == pAdapter)
12692 {
12693 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
12694 return -ENOENT;
12695 }
12696
12697 wlan_hdd_get_classAstats(pAdapter);
12698 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
12699
Jeff Johnsone7245742012-09-05 17:12:55 -070012700 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012701 return 0;
12702}
12703
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012704static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
12705#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12706 struct wireless_dev *wdev,
12707#endif
12708 int *dbm)
12709{
12710 int ret;
12711
12712 vos_ssr_protect(__func__);
12713 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
12714#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12715 wdev,
12716#endif
12717 dbm);
12718 vos_ssr_unprotect(__func__);
12719
12720 return ret;
12721}
12722
12723
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012724static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070012725 u8* mac, struct station_info *sinfo)
12726{
12727 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12728 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12729 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053012730 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070012731
12732 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
12733 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012734
12735 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
12736 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
12737 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
12738 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
12739 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
12740 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
12741 tANI_U16 maxRate = 0;
12742 tANI_U16 myRate;
12743 tANI_U16 currentRate = 0;
12744 tANI_U8 maxSpeedMCS = 0;
12745 tANI_U8 maxMCSIdx = 0;
12746 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053012747 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012748 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012749 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012750
Leo Chang6f8870f2013-03-26 18:11:36 -070012751#ifdef WLAN_FEATURE_11AC
12752 tANI_U32 vht_mcs_map;
12753 eDataRate11ACMaxMcs vhtMaxMcs;
12754#endif /* WLAN_FEATURE_11AC */
12755
Jeff Johnsone7245742012-09-05 17:12:55 -070012756 ENTER();
12757
Jeff Johnson295189b2012-06-20 16:38:30 -070012758 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
12759 (0 == ssidlen))
12760 {
12761 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
12762 " Invalid ssidlen, %d", __func__, ssidlen);
12763 /*To keep GUI happy*/
12764 return 0;
12765 }
12766
Mukul Sharma811205f2014-07-09 21:07:30 +053012767 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
12768 {
12769 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12770 "%s: Roaming in progress, so unable to proceed this request", __func__);
12771 return 0;
12772 }
12773
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012774 status = wlan_hdd_validate_context(pHddCtx);
12775
12776 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012777 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012778 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12779 "%s: HDD context is not valid", __func__);
12780 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012781 }
12782
Jeff Johnson295189b2012-06-20 16:38:30 -070012783
Kiet Lam3b17fc82013-09-27 05:24:08 +053012784 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
12785 sinfo->filled |= STATION_INFO_SIGNAL;
12786
c_hpothu09f19542014-05-30 21:53:31 +053012787 wlan_hdd_get_station_stats(pAdapter);
12788 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
12789
12790 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053012791 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
12792 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053012793 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053012794 {
12795 rate_flags = pAdapter->maxRateFlags;
12796 }
c_hpothu44ff4e02014-05-08 00:13:57 +053012797
Jeff Johnson295189b2012-06-20 16:38:30 -070012798 //convert to the UI units of 100kbps
12799 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
12800
12801#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070012802 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 -070012803 sinfo->signal,
12804 pCfg->reportMaxLinkSpeed,
12805 myRate,
12806 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012807 (int) pCfg->linkSpeedRssiMid,
12808 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070012809 (int) rate_flags,
12810 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012811#endif //LINKSPEED_DEBUG_ENABLED
12812
12813 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
12814 {
12815 // we do not want to necessarily report the current speed
12816 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
12817 {
12818 // report the max possible speed
12819 rssidx = 0;
12820 }
12821 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
12822 {
12823 // report the max possible speed with RSSI scaling
12824 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
12825 {
12826 // report the max possible speed
12827 rssidx = 0;
12828 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012829 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070012830 {
12831 // report middle speed
12832 rssidx = 1;
12833 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012834 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
12835 {
12836 // report middle speed
12837 rssidx = 2;
12838 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012839 else
12840 {
12841 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012842 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070012843 }
12844 }
12845 else
12846 {
12847 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
12848 hddLog(VOS_TRACE_LEVEL_ERROR,
12849 "%s: Invalid value for reportMaxLinkSpeed: %u",
12850 __func__, pCfg->reportMaxLinkSpeed);
12851 rssidx = 0;
12852 }
12853
12854 maxRate = 0;
12855
12856 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012857 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
12858 OperationalRates, &ORLeng))
12859 {
12860 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12861 /*To keep GUI happy*/
12862 return 0;
12863 }
12864
Jeff Johnson295189b2012-06-20 16:38:30 -070012865 for (i = 0; i < ORLeng; i++)
12866 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012867 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012868 {
12869 /* Validate Rate Set */
12870 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
12871 {
12872 currentRate = supported_data_rate[j].supported_rate[rssidx];
12873 break;
12874 }
12875 }
12876 /* Update MAX rate */
12877 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12878 }
12879
12880 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012881 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
12882 ExtendedRates, &ERLeng))
12883 {
12884 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12885 /*To keep GUI happy*/
12886 return 0;
12887 }
12888
Jeff Johnson295189b2012-06-20 16:38:30 -070012889 for (i = 0; i < ERLeng; i++)
12890 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012891 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012892 {
12893 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
12894 {
12895 currentRate = supported_data_rate[j].supported_rate[rssidx];
12896 break;
12897 }
12898 }
12899 /* Update MAX rate */
12900 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12901 }
c_hpothu79aab322014-07-14 21:11:01 +053012902
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012903 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053012904 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012905 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053012906 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070012907 {
c_hpothu79aab322014-07-14 21:11:01 +053012908 if (rate_flags & eHAL_TX_RATE_VHT80)
12909 mode = 2;
12910 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
12911 mode = 1;
12912 else
12913 mode = 0;
12914
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012915 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
12916 MCSRates, &MCSLeng))
12917 {
12918 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12919 /*To keep GUI happy*/
12920 return 0;
12921 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012922 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070012923#ifdef WLAN_FEATURE_11AC
12924 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012925 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070012926 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012927 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012928 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070012929 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070012930 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012931 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070012932 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012933 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070012934 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012935 maxMCSIdx = 7;
12936 }
12937 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
12938 {
12939 maxMCSIdx = 8;
12940 }
12941 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
12942 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012943 //VHT20 is supporting 0~8
12944 if (rate_flags & eHAL_TX_RATE_VHT20)
12945 maxMCSIdx = 8;
12946 else
12947 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070012948 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012949
c_hpothu79aab322014-07-14 21:11:01 +053012950 if (0 != rssidx)/*check for scaled */
12951 {
12952 //get middle rate MCS index if rssi=1/2
12953 for (i=0; i <= maxMCSIdx; i++)
12954 {
12955 if (sinfo->signal <= rssiMcsTbl[mode][i])
12956 {
12957 maxMCSIdx = i;
12958 break;
12959 }
12960 }
12961 }
12962
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012963 if (rate_flags & eHAL_TX_RATE_VHT80)
12964 {
12965 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
12966 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
12967 }
12968 else if (rate_flags & eHAL_TX_RATE_VHT40)
12969 {
12970 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
12971 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
12972 }
12973 else if (rate_flags & eHAL_TX_RATE_VHT20)
12974 {
12975 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
12976 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
12977 }
12978
Leo Chang6f8870f2013-03-26 18:11:36 -070012979 maxSpeedMCS = 1;
12980 if (currentRate > maxRate)
12981 {
12982 maxRate = currentRate;
12983 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012984
Leo Chang6f8870f2013-03-26 18:11:36 -070012985 }
12986 else
12987#endif /* WLAN_FEATURE_11AC */
12988 {
12989 if (rate_flags & eHAL_TX_RATE_HT40)
12990 {
12991 rateFlag |= 1;
12992 }
12993 if (rate_flags & eHAL_TX_RATE_SGI)
12994 {
12995 rateFlag |= 2;
12996 }
12997
Girish Gowli01abcee2014-07-31 20:18:55 +053012998 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053012999 if (rssidx == 1 || rssidx == 2)
13000 {
13001 //get middle rate MCS index if rssi=1/2
13002 for (i=0; i <= 7; i++)
13003 {
13004 if (sinfo->signal <= rssiMcsTbl[mode][i])
13005 {
13006 temp = i+1;
13007 break;
13008 }
13009 }
13010 }
c_hpothu79aab322014-07-14 21:11:01 +053013011
13012 for (i = 0; i < MCSLeng; i++)
13013 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013014 for (j = 0; j < temp; j++)
13015 {
13016 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
13017 {
13018 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
13019 break;
13020 }
13021 }
13022 if ((j < temp) && (currentRate > maxRate))
13023 {
13024 maxRate = currentRate;
13025 maxSpeedMCS = 1;
13026 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
13027 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013028 }
13029 }
13030 }
13031
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013032 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
13033 {
13034 maxRate = myRate;
13035 maxSpeedMCS = 1;
13036 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13037 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013038 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053013039 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070013040 {
13041 maxRate = myRate;
13042 if (rate_flags & eHAL_TX_RATE_LEGACY)
13043 {
13044 maxSpeedMCS = 0;
13045 }
13046 else
13047 {
13048 maxSpeedMCS = 1;
13049 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13050 }
13051 }
13052
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013053 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070013054 {
13055 sinfo->txrate.legacy = maxRate;
13056#ifdef LINKSPEED_DEBUG_ENABLED
13057 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
13058#endif //LINKSPEED_DEBUG_ENABLED
13059 }
13060 else
13061 {
13062 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070013063#ifdef WLAN_FEATURE_11AC
13064 sinfo->txrate.nss = 1;
13065 if (rate_flags & eHAL_TX_RATE_VHT80)
13066 {
13067 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013068 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070013069 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013070 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070013071 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013072 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13073 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13074 }
13075 else if (rate_flags & eHAL_TX_RATE_VHT20)
13076 {
13077 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13078 }
13079#endif /* WLAN_FEATURE_11AC */
13080 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
13081 {
13082 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13083 if (rate_flags & eHAL_TX_RATE_HT40)
13084 {
13085 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13086 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013087 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013088 if (rate_flags & eHAL_TX_RATE_SGI)
13089 {
13090 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13091 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013092
Jeff Johnson295189b2012-06-20 16:38:30 -070013093#ifdef LINKSPEED_DEBUG_ENABLED
13094 pr_info("Reporting MCS rate %d flags %x\n",
13095 sinfo->txrate.mcs,
13096 sinfo->txrate.flags );
13097#endif //LINKSPEED_DEBUG_ENABLED
13098 }
13099 }
13100 else
13101 {
13102 // report current rate instead of max rate
13103
13104 if (rate_flags & eHAL_TX_RATE_LEGACY)
13105 {
13106 //provide to the UI in units of 100kbps
13107 sinfo->txrate.legacy = myRate;
13108#ifdef LINKSPEED_DEBUG_ENABLED
13109 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
13110#endif //LINKSPEED_DEBUG_ENABLED
13111 }
13112 else
13113 {
13114 //must be MCS
13115 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013116#ifdef WLAN_FEATURE_11AC
13117 sinfo->txrate.nss = 1;
13118 if (rate_flags & eHAL_TX_RATE_VHT80)
13119 {
13120 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13121 }
13122 else
13123#endif /* WLAN_FEATURE_11AC */
13124 {
13125 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13126 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013127 if (rate_flags & eHAL_TX_RATE_SGI)
13128 {
13129 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13130 }
13131 if (rate_flags & eHAL_TX_RATE_HT40)
13132 {
13133 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13134 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013135#ifdef WLAN_FEATURE_11AC
13136 else if (rate_flags & eHAL_TX_RATE_VHT80)
13137 {
13138 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
13139 }
13140#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070013141#ifdef LINKSPEED_DEBUG_ENABLED
13142 pr_info("Reporting actual MCS rate %d flags %x\n",
13143 sinfo->txrate.mcs,
13144 sinfo->txrate.flags );
13145#endif //LINKSPEED_DEBUG_ENABLED
13146 }
13147 }
13148 sinfo->filled |= STATION_INFO_TX_BITRATE;
13149
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013150 sinfo->tx_packets =
13151 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
13152 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
13153 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
13154 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
13155
13156 sinfo->tx_retries =
13157 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
13158 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
13159 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
13160 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
13161
13162 sinfo->tx_failed =
13163 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
13164 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
13165 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
13166 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
13167
13168 sinfo->filled |=
13169 STATION_INFO_TX_PACKETS |
13170 STATION_INFO_TX_RETRIES |
13171 STATION_INFO_TX_FAILED;
13172
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013173 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13174 TRACE_CODE_HDD_CFG80211_GET_STA,
13175 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013176 EXIT();
13177 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013178}
13179
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013180static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13181 u8* mac, struct station_info *sinfo)
13182{
13183 int ret;
13184
13185 vos_ssr_protect(__func__);
13186 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
13187 vos_ssr_unprotect(__func__);
13188
13189 return ret;
13190}
13191
13192static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070013193 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070013194{
13195 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013196 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013197 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013198 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013199
Jeff Johnsone7245742012-09-05 17:12:55 -070013200 ENTER();
13201
Jeff Johnson295189b2012-06-20 16:38:30 -070013202 if (NULL == pAdapter)
13203 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013204 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013205 return -ENODEV;
13206 }
13207
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013208 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13209 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
13210 pAdapter->sessionId, timeout));
13211
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013212 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013213 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013214
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013215 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013216 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013217 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13218 "%s: HDD context is not valid", __func__);
13219 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013220 }
13221
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013222 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
13223 (TRUE == pHddCtx->hdd_wlan_suspended) &&
13224 (pHddCtx->cfg_ini->fhostArpOffload) &&
13225 (eConnectionState_Associated ==
13226 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13227 {
Amar Singhald53568e2013-09-26 11:03:45 -070013228
13229 hddLog(VOS_TRACE_LEVEL_INFO,
13230 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053013231 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013232 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13233 {
13234 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013235 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013236 __func__, vos_status);
13237 }
13238 }
13239
Jeff Johnson295189b2012-06-20 16:38:30 -070013240 /**The get power cmd from the supplicant gets updated by the nl only
13241 *on successful execution of the function call
13242 *we are oppositely mapped w.r.t mode in the driver
13243 **/
13244 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
13245
Jeff Johnsone7245742012-09-05 17:12:55 -070013246 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013247 if (VOS_STATUS_E_FAILURE == vos_status)
13248 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13250 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013251 return -EINVAL;
13252 }
13253 return 0;
13254}
13255
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013256static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
13257 struct net_device *dev, bool mode, int timeout)
13258{
13259 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013260
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013261 vos_ssr_protect(__func__);
13262 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
13263 vos_ssr_unprotect(__func__);
13264
13265 return ret;
13266}
Jeff Johnson295189b2012-06-20 16:38:30 -070013267#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013268static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
13269 struct net_device *netdev,
13270 u8 key_index)
13271{
13272 ENTER();
13273 return 0;
13274}
13275
Jeff Johnson295189b2012-06-20 16:38:30 -070013276static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013277 struct net_device *netdev,
13278 u8 key_index)
13279{
13280 int ret;
13281 vos_ssr_protect(__func__);
13282 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
13283 vos_ssr_unprotect(__func__);
13284 return ret;
13285}
13286#endif //LINUX_VERSION_CODE
13287
13288#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13289static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13290 struct net_device *dev,
13291 struct ieee80211_txq_params *params)
13292{
13293 ENTER();
13294 return 0;
13295}
13296#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13297static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13298 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013299{
Jeff Johnsone7245742012-09-05 17:12:55 -070013300 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013301 return 0;
13302}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013303#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070013304
13305#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13306static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013307 struct net_device *dev,
13308 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013309{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013310 int ret;
13311
13312 vos_ssr_protect(__func__);
13313 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
13314 vos_ssr_unprotect(__func__);
13315 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013316}
13317#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13318static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
13319 struct ieee80211_txq_params *params)
13320{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013321 int ret;
13322
13323 vos_ssr_protect(__func__);
13324 ret = __wlan_hdd_set_txq_params(wiphy, params);
13325 vos_ssr_unprotect(__func__);
13326 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013327}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013328#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013329
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013330static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013331 struct net_device *dev,
13332 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070013333{
13334 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013335 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013336 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013337 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013338 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013339 v_CONTEXT_t pVosContext = NULL;
13340 ptSapContext pSapCtx = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070013341 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013342
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013343 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070013344 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013345 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013346 return -EINVAL;
13347 }
13348
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013349 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13350 TRACE_CODE_HDD_CFG80211_DEL_STA,
13351 pAdapter->sessionId, pAdapter->device_mode));
13352
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013353 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13354 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070013355
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013356 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013357 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13359 "%s: HDD context is not valid", __func__);
13360 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013361 }
13362
Jeff Johnson295189b2012-06-20 16:38:30 -070013363 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013364 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013365 )
13366 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013367 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13368 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13369 if(pSapCtx == NULL){
13370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13371 FL("psapCtx is NULL"));
13372 return -ENOENT;
13373 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013374 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013375 {
13376 v_U16_t i;
13377 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13378 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013379 if ((pSapCtx->aStaInfo[i].isUsed) &&
13380 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070013381 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013382 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013383 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013384 ETHER_ADDR_LEN);
13385
Jeff Johnson295189b2012-06-20 16:38:30 -070013386 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013387 "%s: Delete STA with MAC::"
13388 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013389 __func__,
13390 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
13391 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013392 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013393 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013394 }
13395 }
13396 }
13397 else
13398 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013399
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013400 vos_status = hdd_softap_GetStaId(pAdapter,
13401 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013402 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13403 {
13404 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013405 "%s: Skip this DEL STA as this is not used::"
13406 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013407 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013408 return -ENOENT;
13409 }
13410
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013411 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013412 {
13413 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013414 "%s: Skip this DEL STA as deauth is in progress::"
13415 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013416 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013417 return -ENOENT;
13418 }
13419
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013420 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013421
Jeff Johnson295189b2012-06-20 16:38:30 -070013422 hddLog(VOS_TRACE_LEVEL_INFO,
13423 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013424 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013425 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013426 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013427
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013428 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013429 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13430 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013431 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013432 hddLog(VOS_TRACE_LEVEL_INFO,
13433 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013434 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013435 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013436 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013437 return -ENOENT;
13438 }
13439
Jeff Johnson295189b2012-06-20 16:38:30 -070013440 }
13441 }
13442
13443 EXIT();
13444
13445 return 0;
13446}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013447
13448#ifdef CFG80211_DEL_STA_V2
13449static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13450 struct net_device *dev,
13451 struct station_del_parameters *param)
13452#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013453static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13454 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013455#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013456{
13457 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013458 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070013459
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013460 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013461
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013462#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013463 if (NULL == param) {
13464 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013465 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013466 return -EINVAL;
13467 }
13468
13469 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
13470 param->subtype, &delStaParams);
13471
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013472#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053013473 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013474 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013475#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013476 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
13477
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013478 vos_ssr_unprotect(__func__);
13479
13480 return ret;
13481}
13482
13483static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013484 struct net_device *dev, u8 *mac, struct station_parameters *params)
13485{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013486 hdd_adapter_t *pAdapter;
13487 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013488 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013489#ifdef FEATURE_WLAN_TDLS
13490 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013491
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013492 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013493 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13494 if (NULL == pAdapter)
13495 {
13496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13497 "%s: Adapter is NULL",__func__);
13498 return -EINVAL;
13499 }
13500 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13501 status = wlan_hdd_validate_context(pHddCtx);
13502 if (0 != status)
13503 {
13504 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13505 "%s: HDD context is not valid",__func__);
13506 return status;
13507 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013508
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013509 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13510 TRACE_CODE_HDD_CFG80211_ADD_STA,
13511 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013512 mask = params->sta_flags_mask;
13513
13514 set = params->sta_flags_set;
13515
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013516#ifdef WLAN_FEATURE_TDLS_DEBUG
13517 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13518 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
13519 __func__, mask, set, MAC_ADDR_ARRAY(mac));
13520#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013521
13522 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13523 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013524 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013525 }
13526 }
13527#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013528 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013529}
13530
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013531static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
13532 struct net_device *dev, u8 *mac, struct station_parameters *params)
13533{
13534 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013535
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013536 vos_ssr_protect(__func__);
13537 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
13538 vos_ssr_unprotect(__func__);
13539
13540 return ret;
13541}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013542#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070013543
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013544static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070013545 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013546{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013547 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13548 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013549 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013550 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013551 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013552 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070013553
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013554 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013555 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013556 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013557 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013558 return -EINVAL;
13559 }
13560
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013561 if (!pmksa) {
13562 hddLog(LOGE, FL("pmksa is NULL"));
13563 return -EINVAL;
13564 }
13565
13566 if (!pmksa->bssid || !pmksa->pmkid) {
13567 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
13568 pmksa->bssid, pmksa->pmkid);
13569 return -EINVAL;
13570 }
13571
13572 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
13573 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13574
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013575 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13576 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013577
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013578 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013579 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013580 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13581 "%s: HDD context is not valid", __func__);
13582 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013583 }
13584
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013585 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013586 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13587
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013588 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
13589 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013590
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013591 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013592 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013593 &pmk_id, 1, FALSE);
13594
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013595 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13596 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
13597 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013598
13599 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013600}
13601
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013602static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
13603 struct cfg80211_pmksa *pmksa)
13604{
13605 int ret;
13606
13607 vos_ssr_protect(__func__);
13608 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
13609 vos_ssr_unprotect(__func__);
13610
13611 return ret;
13612}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013613
Wilson Yang6507c4e2013-10-01 20:11:19 -070013614
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013615static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070013616 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013617{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013618 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13619 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013620 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013621 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013622
Wilson Yang6507c4e2013-10-01 20:11:19 -070013623 /* Validate pAdapter */
13624 if (NULL == pAdapter)
13625 {
13626 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
13627 return -EINVAL;
13628 }
13629
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013630 if (!pmksa) {
13631 hddLog(LOGE, FL("pmksa is NULL"));
13632 return -EINVAL;
13633 }
13634
13635 if (!pmksa->bssid) {
13636 hddLog(LOGE, FL("pmksa->bssid is NULL"));
13637 return -EINVAL;
13638 }
13639
Kiet Lam98c46a12014-10-31 15:34:57 -070013640 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
13641 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13642
Wilson Yang6507c4e2013-10-01 20:11:19 -070013643 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13644 status = wlan_hdd_validate_context(pHddCtx);
13645
13646 if (0 != status)
13647 {
13648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13649 "%s: HDD context is not valid", __func__);
13650 return status;
13651 }
13652
13653 /*Retrieve halHandle*/
13654 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13655
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013656 /* Delete the PMKID CSR cache */
13657 if (eHAL_STATUS_SUCCESS !=
13658 sme_RoamDelPMKIDfromCache(halHandle,
13659 pAdapter->sessionId, pmksa->bssid, FALSE)) {
13660 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
13661 MAC_ADDR_ARRAY(pmksa->bssid));
13662 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013663 }
13664
Wilson Yangef657d32014-01-15 19:19:23 -080013665 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013666}
13667
Wilson Yang6507c4e2013-10-01 20:11:19 -070013668
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013669static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
13670 struct cfg80211_pmksa *pmksa)
13671{
13672 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013673
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013674 vos_ssr_protect(__func__);
13675 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
13676 vos_ssr_unprotect(__func__);
13677
13678 return ret;
13679
13680}
13681
13682static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013683{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013684 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13685 tHalHandle halHandle;
13686 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013687 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013688
13689 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
13690
13691 /* Validate pAdapter */
13692 if (NULL == pAdapter)
13693 {
13694 hddLog(VOS_TRACE_LEVEL_ERROR,
13695 "%s: Invalid Adapter" ,__func__);
13696 return -EINVAL;
13697 }
13698
13699 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13700 status = wlan_hdd_validate_context(pHddCtx);
13701
13702 if (0 != status)
13703 {
13704 hddLog(VOS_TRACE_LEVEL_ERROR,
13705 "%s: HDD context is not valid", __func__);
13706 return status;
13707 }
13708
13709 /*Retrieve halHandle*/
13710 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13711
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013712 /* Flush the PMKID cache in CSR */
13713 if (eHAL_STATUS_SUCCESS !=
13714 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
13715 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
13716 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013717 }
13718
Wilson Yangef657d32014-01-15 19:19:23 -080013719 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013720}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013721
13722static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
13723{
13724 int ret;
13725
13726 vos_ssr_protect(__func__);
13727 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
13728 vos_ssr_unprotect(__func__);
13729
13730 return ret;
13731}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013732#endif
13733
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013734#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013735static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13736 struct net_device *dev,
13737 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013738{
13739 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13740 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013741 hdd_context_t *pHddCtx;
13742 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013743
13744 if (NULL == pAdapter)
13745 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013746 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013747 return -ENODEV;
13748 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013749 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13750 ret = wlan_hdd_validate_context(pHddCtx);
13751 if (0 != ret)
13752 {
13753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13754 "%s: HDD context is not valid", __func__);
13755 return ret;
13756 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013757 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013758 if (NULL == pHddStaCtx)
13759 {
13760 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
13761 return -EINVAL;
13762 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013763
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013764 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13765 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
13766 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013767 // Added for debug on reception of Re-assoc Req.
13768 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
13769 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013770 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013771 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080013772 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013773 }
13774
13775#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080013776 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013777 ftie->ie_len);
13778#endif
13779
13780 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013781 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13782 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013783 ftie->ie_len);
13784 return 0;
13785}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013786
13787static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13788 struct net_device *dev,
13789 struct cfg80211_update_ft_ies_params *ftie)
13790{
13791 int ret;
13792
13793 vos_ssr_protect(__func__);
13794 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
13795 vos_ssr_unprotect(__func__);
13796
13797 return ret;
13798}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013799#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013800
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013801#ifdef FEATURE_WLAN_SCAN_PNO
13802
13803void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
13804 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
13805{
13806 int ret;
13807 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
13808 hdd_context_t *pHddCtx;
13809
Nirav Shah80830bf2013-12-31 16:35:12 +053013810 ENTER();
13811
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013812 if (NULL == pAdapter)
13813 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013815 "%s: HDD adapter is Null", __func__);
13816 return ;
13817 }
13818
13819 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13820 if (NULL == pHddCtx)
13821 {
13822 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13823 "%s: HDD context is Null!!!", __func__);
13824 return ;
13825 }
13826
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013827 spin_lock(&pHddCtx->schedScan_lock);
13828 if (TRUE == pHddCtx->isWiphySuspended)
13829 {
13830 pHddCtx->isSchedScanUpdatePending = TRUE;
13831 spin_unlock(&pHddCtx->schedScan_lock);
13832 hddLog(VOS_TRACE_LEVEL_INFO,
13833 "%s: Update cfg80211 scan database after it resume", __func__);
13834 return ;
13835 }
13836 spin_unlock(&pHddCtx->schedScan_lock);
13837
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013838 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
13839
13840 if (0 > ret)
13841 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
13842
13843 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13845 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013846}
13847
13848/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013849 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013850 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013851 */
13852static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
13853{
13854 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13855 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013856 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013857 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13858 int status = 0;
13859 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13860
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013861 /* The current firmware design does not allow PNO during any
13862 * active sessions. Hence, determine the active sessions
13863 * and return a failure.
13864 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013865 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
13866 {
13867 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013868 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013869
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013870 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
13871 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
13872 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
13873 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
13874 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053013875 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013876 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013877 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013878 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013879 }
13880 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13881 pAdapterNode = pNext;
13882 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013883 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013884}
13885
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013886void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
13887{
13888 hdd_adapter_t *pAdapter = callbackContext;
13889 hdd_context_t *pHddCtx;
13890
13891 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
13892 {
13893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13894 FL("Invalid adapter or adapter has invalid magic"));
13895 return;
13896 }
13897
13898 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13899 if (0 != wlan_hdd_validate_context(pHddCtx))
13900 {
13901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13902 FL("HDD context is not valid"));
13903 return;
13904 }
13905
c_hpothub53c45d2014-08-18 16:53:14 +053013906 if (VOS_STATUS_SUCCESS != status)
13907 {
13908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013909 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053013910 pHddCtx->isPnoEnable = FALSE;
13911 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013912
13913 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
13914 complete(&pAdapter->pno_comp_var);
13915}
13916
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013917/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013918 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
13919 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013920 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013921static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013922 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13923{
13924 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053013925 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013926 hdd_context_t *pHddCtx;
13927 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013928 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053013929 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
13930 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013931 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13932 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013933 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013934 hdd_config_t *pConfig = NULL;
13935 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013936
13937 if (NULL == pAdapter)
13938 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013939 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013940 "%s: HDD adapter is Null", __func__);
13941 return -ENODEV;
13942 }
13943
13944 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013945 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013946
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013947 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013948 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13950 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013951 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013952 }
13953
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013954 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013955 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13956 if (NULL == hHal)
13957 {
13958 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13959 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013960 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013961 }
Sushant Kaushik2fe89932014-09-03 10:58:09 +053013962 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013963 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053013964 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013965 {
13966 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13967 "%s: aborting the existing scan is unsuccessfull", __func__);
13968 return -EBUSY;
13969 }
13970
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013971 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013972 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013973 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013974 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013975 return -EBUSY;
13976 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013977
c_hpothu37f21312014-04-09 21:49:54 +053013978 if (TRUE == pHddCtx->isPnoEnable)
13979 {
13980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13981 FL("already PNO is enabled"));
13982 return -EBUSY;
13983 }
c_hpothu225aa7c2014-10-22 17:45:13 +053013984
13985 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
13986 {
13987 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13988 "%s: abort ROC failed ", __func__);
13989 return -EBUSY;
13990 }
13991
c_hpothu37f21312014-04-09 21:49:54 +053013992 pHddCtx->isPnoEnable = TRUE;
13993
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053013994 pnoRequest.enable = 1; /*Enable PNO */
13995 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013996
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053013997 if (( !pnoRequest.ucNetworksCount ) ||
13998 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013999 {
14000 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014001 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014002 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014003 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014004 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014005 goto error;
14006 }
14007
14008 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
14009 {
14010 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014011 "%s: Incorrect number of channels %d",
14012 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014013 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014014 goto error;
14015 }
14016
14017 /* Framework provides one set of channels(all)
14018 * common for all saved profile */
14019 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14020 channels_allowed, &num_channels_allowed))
14021 {
14022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14023 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014024 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014025 goto error;
14026 }
14027 /* Checking each channel against allowed channel list */
14028 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053014029 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014030 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014031 char chList [(request->n_channels*5)+1];
14032 int len;
14033 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014034 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014035 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014036 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014037 if (request->channels[i]->hw_value == channels_allowed[indx])
14038 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014039 if ((!pConfig->enableDFSPnoChnlScan) &&
14040 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
14041 {
14042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14043 "%s : Dropping DFS channel : %d",
14044 __func__,channels_allowed[indx]);
14045 num_ignore_dfs_ch++;
14046 break;
14047 }
14048
Nirav Shah80830bf2013-12-31 16:35:12 +053014049 valid_ch[num_ch++] = request->channels[i]->hw_value;
14050 len += snprintf(chList+len, 5, "%d ",
14051 request->channels[i]->hw_value);
14052 break ;
14053 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014054 }
14055 }
Nirav Shah80830bf2013-12-31 16:35:12 +053014056 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014057
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014058 /*If all channels are DFS and dropped, then ignore the PNO request*/
14059 if (num_ignore_dfs_ch == request->n_channels)
14060 {
14061 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14062 "%s : All requested channels are DFS channels", __func__);
14063 ret = -EINVAL;
14064 goto error;
14065 }
14066 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014067
14068 pnoRequest.aNetworks =
14069 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14070 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014071 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014072 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14073 FL("failed to allocate memory aNetworks %u"),
14074 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14075 goto error;
14076 }
14077 vos_mem_zero(pnoRequest.aNetworks,
14078 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14079
14080 /* Filling per profile params */
14081 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
14082 {
14083 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014084 request->match_sets[i].ssid.ssid_len;
14085
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014086 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
14087 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014088 {
14089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014090 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014091 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014092 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014093 goto error;
14094 }
14095
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014096 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014097 request->match_sets[i].ssid.ssid,
14098 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014099 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14100 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014101 i, pnoRequest.aNetworks[i].ssId.ssId);
14102 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
14103 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
14104 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014105
14106 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014107 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
14108 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014109
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014110 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014111 }
14112
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014113 for (i = 0; i < request->n_ssids; i++)
14114 {
14115 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014116 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014117 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014118 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014119 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014120 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014121 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014122 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014123 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014124 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014125 break;
14126 }
14127 j++;
14128 }
14129 }
14130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14131 "Number of hidden networks being Configured = %d",
14132 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080014134 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014135
14136 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14137 if (pnoRequest.p24GProbeTemplate == NULL)
14138 {
14139 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14140 FL("failed to allocate memory p24GProbeTemplate %u"),
14141 SIR_PNO_MAX_PB_REQ_SIZE);
14142 goto error;
14143 }
14144
14145 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14146 if (pnoRequest.p5GProbeTemplate == NULL)
14147 {
14148 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14149 FL("failed to allocate memory p5GProbeTemplate %u"),
14150 SIR_PNO_MAX_PB_REQ_SIZE);
14151 goto error;
14152 }
14153
14154 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14155 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14156
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053014157 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
14158 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014159 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014160 pnoRequest.us24GProbeTemplateLen = request->ie_len;
14161 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
14162 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014163
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014164 pnoRequest.us5GProbeTemplateLen = request->ie_len;
14165 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
14166 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014167 }
14168
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014169 /* Driver gets only one time interval which is hardcoded in
14170 * supplicant for 10000ms. Taking power consumption into account 6 timers
14171 * will be used, Timervalue is increased exponentially i.e 10,20,40,
14172 * 80,160,320 secs. And number of scan cycle for each timer
14173 * is configurable through INI param gPNOScanTimerRepeatValue.
14174 * If it is set to 0 only one timer will be used and PNO scan cycle
14175 * will be repeated after each interval specified by supplicant
14176 * till PNO is disabled.
14177 */
14178 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014179 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014180 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014181 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014182 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
14183
14184 tempInterval = (request->interval)/1000;
14185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14186 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
14187 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014188 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014189 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014190 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014191 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014192 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014193 tempInterval *= 2;
14194 }
14195 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014196 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014197
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014198 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014199
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014200 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014201 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
14202 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014203 pAdapter->pno_req_status = 0;
14204
Nirav Shah80830bf2013-12-31 16:35:12 +053014205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14206 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014207 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
14208 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053014209
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014210 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014211 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014212 hdd_cfg80211_sched_scan_done_callback, pAdapter);
14213 if (eHAL_STATUS_SUCCESS != status)
14214 {
14215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014216 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014217 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014218 goto error;
14219 }
14220
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014221 ret = wait_for_completion_timeout(
14222 &pAdapter->pno_comp_var,
14223 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
14224 if (0 >= ret)
14225 {
14226 // Did not receive the response for PNO enable in time.
14227 // Assuming the PNO enable was success.
14228 // Returning error from here, because we timeout, results
14229 // in side effect of Wifi (Wifi Setting) not to work.
14230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14231 FL("Timed out waiting for PNO to be Enabled"));
14232 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014233 }
14234
14235 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053014236 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014237
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014238error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014239 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14240 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053014241 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014242 if (pnoRequest.aNetworks)
14243 vos_mem_free(pnoRequest.aNetworks);
14244 if (pnoRequest.p24GProbeTemplate)
14245 vos_mem_free(pnoRequest.p24GProbeTemplate);
14246 if (pnoRequest.p5GProbeTemplate)
14247 vos_mem_free(pnoRequest.p5GProbeTemplate);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014248 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014249}
14250
14251/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014252 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
14253 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014254 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014255static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
14256 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14257{
14258 int ret;
14259
14260 vos_ssr_protect(__func__);
14261 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
14262 vos_ssr_unprotect(__func__);
14263
14264 return ret;
14265}
14266
14267/*
14268 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
14269 * Function to disable PNO
14270 */
14271static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014272 struct net_device *dev)
14273{
14274 eHalStatus status = eHAL_STATUS_FAILURE;
14275 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14276 hdd_context_t *pHddCtx;
14277 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014278 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014279 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014280
14281 ENTER();
14282
14283 if (NULL == pAdapter)
14284 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014286 "%s: HDD adapter is Null", __func__);
14287 return -ENODEV;
14288 }
14289
14290 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014291
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014292 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014293 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014295 "%s: HDD context is Null", __func__);
14296 return -ENODEV;
14297 }
14298
14299 /* The return 0 is intentional when isLogpInProgress and
14300 * isLoadUnloadInProgress. We did observe a crash due to a return of
14301 * failure in sched_scan_stop , especially for a case where the unload
14302 * of the happens at the same time. The function __cfg80211_stop_sched_scan
14303 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
14304 * success. If it returns a failure , then its next invocation due to the
14305 * clean up of the second interface will have the dev pointer corresponding
14306 * to the first one leading to a crash.
14307 */
14308 if (pHddCtx->isLogpInProgress)
14309 {
14310 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14311 "%s: LOGP in Progress. Ignore!!!", __func__);
14312 return ret;
14313 }
14314
Mihir Shete18156292014-03-11 15:38:30 +053014315 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014316 {
14317 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14318 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14319 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014320 }
14321
14322 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14323 if (NULL == hHal)
14324 {
14325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14326 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014327 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014328 }
14329
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014330 pnoRequest.enable = 0; /* Disable PNO */
14331 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014332
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014333 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014334 pAdapter->sessionId,
14335 NULL, pAdapter);
14336 if (eHAL_STATUS_SUCCESS != status)
14337 {
14338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14339 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014340 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014341 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014342 }
c_hpothu37f21312014-04-09 21:49:54 +053014343 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014344
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014345error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014347 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014348
14349 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014350 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014351}
14352
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014353/*
14354 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
14355 * NL interface to disable PNO
14356 */
14357static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
14358 struct net_device *dev)
14359{
14360 int ret;
14361
14362 vos_ssr_protect(__func__);
14363 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
14364 vos_ssr_unprotect(__func__);
14365
14366 return ret;
14367}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014368#endif /*FEATURE_WLAN_SCAN_PNO*/
14369
14370
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014371#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014372#if TDLS_MGMT_VERSION2
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014373static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014374 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014375 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
14376#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014377static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014378 u8 *peer, u8 action_code, u8 dialog_token,
14379 u16 status_code, const u8 *buf, size_t len)
14380#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014381{
14382
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014383 hdd_adapter_t *pAdapter;
14384 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014385 u8 peerMac[6];
14386 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070014387 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080014388 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070014389 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014390 int ret;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014391#if !(TDLS_MGMT_VERSION2)
14392 u32 peer_capability = 0;
14393#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014394 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014395
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014396 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14397 if (NULL == pAdapter)
14398 {
14399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14400 "%s: Adapter is NULL",__func__);
14401 return -EINVAL;
14402 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014403 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14404 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
14405 pAdapter->sessionId, action_code));
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014406 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014407 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014408 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014410 "Invalid arguments");
14411 return -EINVAL;
14412 }
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014413 if (pHddCtx->isLogpInProgress)
14414 {
14415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14416 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053014417 wlan_hdd_tdls_set_link_status(pAdapter,
14418 peer,
14419 eTDLS_LINK_IDLE,
14420 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014421 return -EBUSY;
14422 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014423 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
14424 {
14425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14426 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14427 return -EAGAIN;
14428 }
Hoonki Lee27511902013-03-14 18:19:06 -070014429 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014430 {
Hoonki Lee27511902013-03-14 18:19:06 -070014431 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
14432 "%s: TDLS mode is disabled OR not enabled in FW."
14433 MAC_ADDRESS_STR " action %d declined.",
14434 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014435 return -ENOTSUPP;
14436 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014437
Hoonki Lee27511902013-03-14 18:19:06 -070014438 /* other than teardown frame, other mgmt frames are not sent if disabled */
14439 if (SIR_MAC_TDLS_TEARDOWN != action_code)
14440 {
14441 /* if tdls_mode is disabled to respond to peer's request */
14442 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
14443 {
14444 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
14445 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014446 " TDLS mode is disabled. action %d declined.",
14447 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070014448
14449 return -ENOTSUPP;
14450 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014451
14452 if (vos_max_concurrent_connections_reached())
14453 {
14454 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14455 return -EINVAL;
14456 }
Hoonki Lee27511902013-03-14 18:19:06 -070014457 }
14458
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014459 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
14460 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014461 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014462 {
14463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014464 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014465 " TDLS setup is ongoing. action %d declined.",
14466 __func__, MAC_ADDR_ARRAY(peer), action_code);
14467 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014468 }
14469 }
14470
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014471 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
14472 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080014473 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014474 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14475 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014476 {
14477 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
14478 we return error code at 'add_station()'. Hence we have this
14479 check again in addtion to add_station().
14480 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014481 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014482 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14484 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014485 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
14486 __func__, MAC_ADDR_ARRAY(peer), action_code,
14487 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053014488 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080014489 }
14490 else
14491 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014492 /* maximum reached. tweak to send error code to peer and return
14493 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014494 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014495 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14496 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014497 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
14498 __func__, MAC_ADDR_ARRAY(peer), status_code,
14499 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070014500 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014501 /* fall through to send setup resp with failure status
14502 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014503 }
14504 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014505 else
14506 {
14507 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014508 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014509 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014510 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014512 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
14513 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014514 return -EPERM;
14515 }
14516 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014517 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014518 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014519
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014520#ifdef WLAN_FEATURE_TDLS_DEBUG
14521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014522 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014523 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
14524 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014525#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014526
Hoonki Leea34dd892013-02-05 22:56:02 -080014527 /*Except teardown responder will not be used so just make 0*/
14528 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014529 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080014530 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014531
14532 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014533 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014534
14535 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
14536 responder = pTdlsPeer->is_responder;
14537 else
Hoonki Leea34dd892013-02-05 22:56:02 -080014538 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014540 "%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 -070014541 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
14542 dialog_token, status_code, len);
14543 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080014544 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014545 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014546
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014547 /* For explicit trigger of DIS_REQ come out of BMPS for
14548 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070014549 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014550 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
14551 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070014552 {
14553 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
14554 {
14555 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014556 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070014557 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
14558 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014559 if (SIR_MAC_TDLS_DIS_REQ != action_code)
14560 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070014561 }
14562
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014563 /* make sure doesn't call send_mgmt() while it is pending */
14564 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
14565 {
14566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014567 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014568 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014569 ret = -EBUSY;
14570 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014571 }
14572
14573 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014574 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
14575
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014576 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053014577 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014578
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014579 if (VOS_STATUS_SUCCESS != status)
14580 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14582 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014583 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014584 ret = -EINVAL;
14585 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014586 }
14587
Hoonki Leed37cbb32013-04-20 00:31:14 -070014588 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
14589 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
14590
14591 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014592 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070014593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014594 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070014595 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014596 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080014597
14598 if (pHddCtx->isLogpInProgress)
14599 {
14600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14601 "%s: LOGP in Progress. Ignore!!!", __func__);
14602 return -EAGAIN;
14603 }
14604
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014605 ret = -EINVAL;
14606 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014607 }
14608
Gopichand Nakkala05922802013-03-14 12:23:19 -070014609 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070014610 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014611 ret = max_sta_failed;
14612 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070014613 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014614
Hoonki Leea34dd892013-02-05 22:56:02 -080014615 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
14616 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014617 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080014618 }
14619 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
14620 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014621 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080014622 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014623
14624 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014625
14626tx_failed:
14627 /* add_station will be called before sending TDLS_SETUP_REQ and
14628 * TDLS_SETUP_RSP and as part of add_station driver will enable
14629 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
14630 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
14631 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
14632 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
14633 */
14634
14635 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
14636 (SIR_MAC_TDLS_SETUP_RSP == action_code))
14637 wlan_hdd_tdls_check_bmps(pAdapter);
14638 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014639}
14640
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014641#if TDLS_MGMT_VERSION2
14642static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14643 u8 *peer, u8 action_code, u8 dialog_token,
14644 u16 status_code, u32 peer_capability,
14645 const u8 *buf, size_t len)
14646#else
14647static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14648 u8 *peer, u8 action_code, u8 dialog_token,
14649 u16 status_code, const u8 *buf, size_t len)
14650#endif
14651{
14652 int ret;
14653
14654 vos_ssr_protect(__func__);
14655#if TDLS_MGMT_VERSION2
14656 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14657 status_code, peer_capability, buf, len);
14658#else
14659 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14660 status_code, buf, len);
14661#endif
14662 vos_ssr_unprotect(__func__);
14663
14664 return ret;
14665}
Atul Mittal115287b2014-07-08 13:26:33 +053014666
14667int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
14668 u8 *peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014669 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053014670 cfg80211_exttdls_callback callback)
14671{
14672
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014673 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053014674 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014675 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053014676 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14677 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
14678 __func__, MAC_ADDR_ARRAY(peer));
14679
14680 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14681 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14682
14683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14684 " %s TDLS External control and Implicit Trigger not enabled ",
14685 __func__);
14686 return -ENOTSUPP;
14687 }
14688
14689 /* To cater the requirement of establishing the TDLS link
14690 * irrespective of the data traffic , get an entry of TDLS peer.
14691 */
14692 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
14693 if (pTdlsPeer == NULL) {
14694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14695 "%s: peer " MAC_ADDRESS_STR " not existing",
14696 __func__, MAC_ADDR_ARRAY(peer));
14697 return -EINVAL;
14698 }
14699
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053014700 /* check FW TDLS Off Channel capability */
14701 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
14702 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014703 {
14704 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
14705 pTdlsPeer->peerParams.global_operating_class =
14706 tdls_peer_params->global_operating_class;
14707 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
14708 pTdlsPeer->peerParams.min_bandwidth_kbps =
14709 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014710 /* check configured channel is valid, non dfs and
14711 * not current operating channel */
14712 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
14713 tdls_peer_params->channel)) &&
14714 (pHddStaCtx) &&
14715 (tdls_peer_params->channel !=
14716 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014717 {
14718 pTdlsPeer->isOffChannelConfigured = TRUE;
14719 }
14720 else
14721 {
14722 pTdlsPeer->isOffChannelConfigured = FALSE;
14723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14724 "%s: Configured Tdls Off Channel is not valid", __func__);
14725
14726 }
14727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014728 "%s: tdls_off_channel %d isOffChannelConfigured %d "
14729 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014730 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014731 pTdlsPeer->isOffChannelConfigured,
14732 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014733 }
14734 else
14735 {
14736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053014737 "%s: TDLS off channel FW capability %d or "
14738 "Invalid TDLS Peer Params", __func__,
14739 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014740 }
14741
Atul Mittal115287b2014-07-08 13:26:33 +053014742 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
14743
14744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14745 " %s TDLS Add Force Peer Failed",
14746 __func__);
14747 return -EINVAL;
14748 }
14749 /*EXT TDLS*/
14750
14751 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
14752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14753 " %s TDLS set callback Failed",
14754 __func__);
14755 return -EINVAL;
14756 }
14757
14758 return(0);
14759
14760}
14761
14762int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
14763{
14764
14765 hddTdlsPeer_t *pTdlsPeer;
14766 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14767 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14768 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
14769 __func__, MAC_ADDR_ARRAY(peer));
14770
14771 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14772 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14773
14774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14775 " %s TDLS External control and Implicit Trigger not enabled ",
14776 __func__);
14777 return -ENOTSUPP;
14778 }
14779
14780
14781 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
14782
14783 if ( NULL == pTdlsPeer ) {
14784 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
14785 " peer not exsting",
14786 __func__, MAC_ADDR_ARRAY(peer));
14787 return -EINVAL;
14788 }
14789 else {
14790 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
14791 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014792 /* if channel switch is configured, reset
14793 the channel for this peer */
14794 if (TRUE == pTdlsPeer->isOffChannelConfigured)
14795 {
14796 pTdlsPeer->peerParams.channel = 0;
14797 pTdlsPeer->isOffChannelConfigured = FALSE;
14798 }
Atul Mittal115287b2014-07-08 13:26:33 +053014799 }
14800
14801 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
14802 return -EINVAL;
14803
14804 /*EXT TDLS*/
14805
14806 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
14807
14808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14809 " %s TDLS set callback Failed",
14810 __func__);
14811 return -EINVAL;
14812 }
14813 return(0);
14814
14815}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014816static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014817 u8 *peer, enum nl80211_tdls_operation oper)
14818{
14819 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14820 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014821 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014822 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014823
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014824 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14825 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
14826 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014827 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014828 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014829 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014830 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014831 return -EINVAL;
14832 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014833
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014834 status = wlan_hdd_validate_context(pHddCtx);
14835
14836 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014837 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14839 "%s: HDD context is not valid", __func__);
14840 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014841 }
14842
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014843
14844 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014845 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014846 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014848 "TDLS Disabled in INI OR not enabled in FW. "
14849 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014850 return -ENOTSUPP;
14851 }
14852
14853 switch (oper) {
14854 case NL80211_TDLS_ENABLE_LINK:
14855 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014856 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014857 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014858 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053014859 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014860 tANI_U16 numCurrTdlsPeers = 0;
14861 hddTdlsPeer_t *connPeer = NULL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014862
Sunil Dutt41de4e22013-11-14 18:09:02 +053014863 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053014864 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053014865 if ( NULL == pTdlsPeer ) {
14866 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
14867 " (oper %d) not exsting. ignored",
14868 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
14869 return -EINVAL;
14870 }
14871
14872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14873 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
14874 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
14875 "NL80211_TDLS_ENABLE_LINK");
14876
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070014877 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
14878 {
14879 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
14880 MAC_ADDRESS_STR " failed",
14881 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
14882 return -EINVAL;
14883 }
14884
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014885 /* TDLS Off Channel, Disable tdls channel switch,
14886 when there are more than one tdls link */
14887 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14888 if (numCurrTdlsPeers == 1)
14889 {
14890 /* get connected peer and send disable tdls off chan */
14891 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
14892 if (connPeer && (connPeer->isOffChannelConfigured == TRUE))
14893 {
14894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14895 "%s: More then one peer connected, Disable "
14896 "TDLS channel switch", __func__);
14897
14898 sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
14899 pAdapter->sessionId,
14900 connPeer->peerMac,
14901 connPeer->peerParams.channel,
14902 TDLS_OFF_CHANNEL_BW_OFFSET,
14903 TDLS_CHANNEL_SWITCH_DISABLE);
14904 }
14905 else
14906 {
14907 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14908 "%s: No TDLS Connected Peer or "
14909 "isOffChannelConfigured %d",
14910 __func__,
14911 (connPeer ? connPeer->isOffChannelConfigured : -1));
14912 }
14913 }
14914
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014915 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014916 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014917 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053014918
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014919 if (0 != wlan_hdd_tdls_get_link_establish_params(
14920 pAdapter, peer,&tdlsLinkEstablishParams)) {
14921 return -EINVAL;
14922 }
14923 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014924
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014925 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
14926 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
14927 /* Send TDLS peer UAPSD capabilities to the firmware and
14928 * register with the TL on after the response for this operation
14929 * is received .
14930 */
14931 ret = wait_for_completion_interruptible_timeout(
14932 &pAdapter->tdls_link_establish_req_comp,
14933 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
14934 if (ret <= 0)
14935 {
14936 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14937 "%s: Link Establish Request Faled Status %ld",
14938 __func__, ret);
14939 return -EINVAL;
14940 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014941 }
Atul Mittal115287b2014-07-08 13:26:33 +053014942 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
14943 eTDLS_LINK_CONNECTED,
14944 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053014945 staDesc.ucSTAId = pTdlsPeer->staId;
14946 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
14947 WLANTL_UpdateTdlsSTAClient(pHddCtx->pvosContext,
14948 &staDesc);
14949
14950
Gopichand Nakkala471708b2013-06-04 20:03:01 +053014951 /* Mark TDLS client Authenticated .*/
14952 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
14953 pTdlsPeer->staId,
14954 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014955 if (VOS_STATUS_SUCCESS == status)
14956 {
Hoonki Lee14621352013-04-16 17:51:19 -070014957 if (pTdlsPeer->is_responder == 0)
14958 {
14959 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
14960
14961 wlan_hdd_tdls_timer_restart(pAdapter,
14962 &pTdlsPeer->initiatorWaitTimeoutTimer,
14963 WAIT_TIME_TDLS_INITIATOR);
14964 /* suspend initiator TX until it receives direct packet from the
14965 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
14966 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
14967 &staId, NULL);
14968 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014969 wlan_hdd_tdls_increment_peer_count(pAdapter);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014970
14971 /* TDLS Off Channel, Enable tdls channel switch,
14972 when their is only one tdls link and it supports */
14973 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14974 if ((numCurrTdlsPeers == 1) &&
14975 (TRUE == pTdlsPeer->isOffChannelSupported) &&
14976 (TRUE == pTdlsPeer->isOffChannelConfigured))
14977 {
14978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14979 "%s: Send TDLS channel switch request for channel %d",
14980 __func__, pTdlsPeer->peerParams.channel);
14981 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
14982 pAdapter->sessionId,
14983 pTdlsPeer->peerMac,
14984 pTdlsPeer->peerParams.channel,
14985 TDLS_OFF_CHANNEL_BW_OFFSET,
14986 TDLS_CHANNEL_SWITCH_ENABLE);
14987 }
14988 else
14989 {
14990 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14991 "%s: TDLS channel switch request not sent"
14992 " numCurrTdlsPeers %d "
14993 "isOffChannelSupported %d "
14994 "isOffChannelConfigured %d",
14995 __func__, numCurrTdlsPeers,
14996 pTdlsPeer->isOffChannelSupported,
14997 pTdlsPeer->isOffChannelConfigured);
14998 }
14999
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015000 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015001 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015002
15003 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015004 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
15005 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015006 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015007 int ac;
15008 uint8 ucAc[4] = { WLANTL_AC_VO,
15009 WLANTL_AC_VI,
15010 WLANTL_AC_BK,
15011 WLANTL_AC_BE };
15012 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
15013 for(ac=0; ac < 4; ac++)
15014 {
15015 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15016 pTdlsPeer->staId, ucAc[ac],
15017 tlTid[ac], tlTid[ac], 0, 0,
15018 WLANTL_BI_DIR );
15019 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015020 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015021 }
15022
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015023 }
15024 break;
15025 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080015026 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015027 tANI_U16 numCurrTdlsPeers = 0;
15028 hddTdlsPeer_t *connPeer = NULL;
15029
Sunil Dutt41de4e22013-11-14 18:09:02 +053015030 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15031
15032 if ( NULL == pTdlsPeer ) {
15033 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15034 " (oper %d) not exsting. ignored",
15035 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15036 return -EINVAL;
15037 }
15038
15039 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15040 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15041 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15042 "NL80211_TDLS_DISABLE_LINK");
15043
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015044 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080015045 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015046 long status;
15047
Atul Mittal271a7652014-09-12 13:18:22 +053015048
15049 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15050 eTDLS_LINK_TEARING,
15051 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
15052 eTDLS_LINK_UNSPECIFIED:
15053 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015054 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
15055
Lee Hoonkic1262f22013-01-24 21:59:00 -080015056 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
15057 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015058
15059 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
15060 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053015061 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053015062 eTDLS_LINK_IDLE,
15063 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015064 if (status <= 0)
15065 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015066 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15067 "%s: Del station failed status %ld",
15068 __func__, status);
15069 return -EPERM;
15070 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015071
15072 /* TDLS Off Channel, Enable tdls channel switch,
15073 when their is only one tdls link and it supports */
15074 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15075 if (numCurrTdlsPeers == 1)
15076 {
15077 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
15078 if ((connPeer) &&
15079 (connPeer->isOffChannelSupported == TRUE) &&
15080 (connPeer->isOffChannelConfigured == TRUE))
15081 {
15082 sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
15083 pAdapter->sessionId,
15084 connPeer->peerMac,
15085 connPeer->peerParams.channel,
15086 TDLS_OFF_CHANNEL_BW_OFFSET,
15087 TDLS_CHANNEL_SWITCH_ENABLE);
15088 }
15089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15090 "%s: TDLS channel switch "
15091 "isOffChannelSupported %d "
15092 "isOffChannelConfigured %d",
15093 __func__,
15094 (connPeer ? connPeer->isOffChannelSupported : -1),
15095 (connPeer ? connPeer->isOffChannelConfigured : -1));
15096 }
15097 else
15098 {
15099 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15100 "%s: TDLS channel switch request not sent "
15101 "numCurrTdlsPeers %d ",
15102 __func__, numCurrTdlsPeers);
15103 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015104 }
15105 else
15106 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15108 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080015109 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015110 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015111 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015112 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015113 {
Atul Mittal115287b2014-07-08 13:26:33 +053015114 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015115
Atul Mittal115287b2014-07-08 13:26:33 +053015116 if (0 != status)
15117 {
15118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15119 "%s: Error in TDLS Teardown", __func__);
15120 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015121 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053015122 break;
15123 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015124 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015125 {
Atul Mittal115287b2014-07-08 13:26:33 +053015126 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
15127 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015128 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053015129 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015130
Atul Mittal115287b2014-07-08 13:26:33 +053015131 if (0 != status)
15132 {
15133 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15134 "%s: Error in TDLS Setup", __func__);
15135 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053015136 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053015137 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015138 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015139 case NL80211_TDLS_DISCOVERY_REQ:
15140 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15142 "%s: We don't support in-driver setup/teardown/discovery "
15143 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015144 return -ENOTSUPP;
15145 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15147 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015148 return -ENOTSUPP;
15149 }
15150 return 0;
15151}
Chilam NG571c65a2013-01-19 12:27:36 +053015152
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015153static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
15154 u8 *peer, enum nl80211_tdls_operation oper)
15155{
15156 int ret;
15157
15158 vos_ssr_protect(__func__);
15159 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
15160 vos_ssr_unprotect(__func__);
15161
15162 return ret;
15163}
15164
Chilam NG571c65a2013-01-19 12:27:36 +053015165int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
15166 struct net_device *dev, u8 *peer)
15167{
Arif Hussaina7c8e412013-11-20 11:06:42 -080015168 hddLog(VOS_TRACE_LEVEL_INFO,
15169 "tdls send discover req: "MAC_ADDRESS_STR,
15170 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053015171
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015172#if TDLS_MGMT_VERSION2
15173 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15174 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15175#else
Chilam NG571c65a2013-01-19 12:27:36 +053015176 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15177 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015178#endif
Chilam NG571c65a2013-01-19 12:27:36 +053015179}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015180#endif
15181
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015182#ifdef WLAN_FEATURE_GTK_OFFLOAD
15183/*
15184 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
15185 * Callback rountine called upon receiving response for
15186 * get offload info
15187 */
15188void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
15189 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
15190{
15191
15192 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015193 tANI_U8 tempReplayCounter[8];
15194 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015195
15196 ENTER();
15197
15198 if (NULL == pAdapter)
15199 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053015200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015201 "%s: HDD adapter is Null", __func__);
15202 return ;
15203 }
15204
15205 if (NULL == pGtkOffloadGetInfoRsp)
15206 {
15207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15208 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
15209 return ;
15210 }
15211
15212 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
15213 {
15214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15215 "%s: wlan Failed to get replay counter value",
15216 __func__);
15217 return ;
15218 }
15219
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015220 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15221 /* Update replay counter */
15222 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
15223 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15224
15225 {
15226 /* changing from little to big endian since supplicant
15227 * works on big endian format
15228 */
15229 int i;
15230 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15231
15232 for (i = 0; i < 8; i++)
15233 {
15234 tempReplayCounter[7-i] = (tANI_U8)p[i];
15235 }
15236 }
15237
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015238 /* Update replay counter to NL */
15239 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015240 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015241}
15242
15243/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015244 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015245 * This function is used to offload GTK rekeying job to the firmware.
15246 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015247int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015248 struct cfg80211_gtk_rekey_data *data)
15249{
15250 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15251 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15252 hdd_station_ctx_t *pHddStaCtx;
15253 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015254 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015255 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015256 eHalStatus status = eHAL_STATUS_FAILURE;
15257
15258 ENTER();
15259
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015260
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015261 if (NULL == pAdapter)
15262 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015263 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015264 "%s: HDD adapter is Null", __func__);
15265 return -ENODEV;
15266 }
15267
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015268 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15269 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
15270 pAdapter->sessionId, pAdapter->device_mode));
15271
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015272 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015273
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015274 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015275 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15277 "%s: HDD context is not valid", __func__);
15278 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015279 }
15280
15281 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15282 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15283 if (NULL == hHal)
15284 {
15285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15286 "%s: HAL context is Null!!!", __func__);
15287 return -EAGAIN;
15288 }
15289
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015290 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
15291 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
15292 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
15293 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015294 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015295 {
15296 /* changing from big to little endian since driver
15297 * works on little endian format
15298 */
15299 tANI_U8 *p =
15300 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
15301 int i;
15302
15303 for (i = 0; i < 8; i++)
15304 {
15305 p[7-i] = data->replay_ctr[i];
15306 }
15307 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015308
15309 if (TRUE == pHddCtx->hdd_wlan_suspended)
15310 {
15311 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015312 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
15313 sizeof (tSirGtkOffloadParams));
15314 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015315 pAdapter->sessionId);
15316
15317 if (eHAL_STATUS_SUCCESS != status)
15318 {
15319 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15320 "%s: sme_SetGTKOffload failed, returned %d",
15321 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053015322
15323 /* Need to clear any trace of key value in the memory.
15324 * Thus zero out the memory even though it is local
15325 * variable.
15326 */
15327 vos_mem_zero(&hddGtkOffloadReqParams,
15328 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015329 return status;
15330 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015331 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15332 "%s: sme_SetGTKOffload successfull", __func__);
15333 }
15334 else
15335 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015336 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15337 "%s: wlan not suspended GTKOffload request is stored",
15338 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015339 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015340
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053015341 /* Need to clear any trace of key value in the memory.
15342 * Thus zero out the memory even though it is local
15343 * variable.
15344 */
15345 vos_mem_zero(&hddGtkOffloadReqParams,
15346 sizeof(hddGtkOffloadReqParams));
15347
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015348 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015349}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015350
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015351int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
15352 struct cfg80211_gtk_rekey_data *data)
15353{
15354 int ret;
15355
15356 vos_ssr_protect(__func__);
15357 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
15358 vos_ssr_unprotect(__func__);
15359
15360 return ret;
15361}
15362#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015363/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015364 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015365 * This function is used to set access control policy
15366 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015367static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
15368 struct net_device *dev,
15369 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015370{
15371 int i;
15372 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15373 hdd_hostapd_state_t *pHostapdState;
15374 tsap_Config_t *pConfig;
15375 v_CONTEXT_t pVosContext = NULL;
15376 hdd_context_t *pHddCtx;
15377 int status;
15378
15379 ENTER();
15380
15381 if (NULL == pAdapter)
15382 {
15383 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15384 "%s: HDD adapter is Null", __func__);
15385 return -ENODEV;
15386 }
15387
15388 if (NULL == params)
15389 {
15390 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15391 "%s: params is Null", __func__);
15392 return -EINVAL;
15393 }
15394
15395 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15396 status = wlan_hdd_validate_context(pHddCtx);
15397
15398 if (0 != status)
15399 {
15400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15401 "%s: HDD context is not valid", __func__);
15402 return status;
15403 }
15404
15405 pVosContext = pHddCtx->pvosContext;
15406 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
15407
15408 if (NULL == pHostapdState)
15409 {
15410 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15411 "%s: pHostapdState is Null", __func__);
15412 return -EINVAL;
15413 }
15414
15415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
15416 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
15417
15418 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
15419 {
15420 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
15421
15422 /* default value */
15423 pConfig->num_accept_mac = 0;
15424 pConfig->num_deny_mac = 0;
15425
15426 /**
15427 * access control policy
15428 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
15429 * listed in hostapd.deny file.
15430 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
15431 * listed in hostapd.accept file.
15432 */
15433 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
15434 {
15435 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
15436 }
15437 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
15438 {
15439 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
15440 }
15441 else
15442 {
15443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15444 "%s:Acl Policy : %d is not supported",
15445 __func__, params->acl_policy);
15446 return -ENOTSUPP;
15447 }
15448
15449 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
15450 {
15451 pConfig->num_accept_mac = params->n_acl_entries;
15452 for (i = 0; i < params->n_acl_entries; i++)
15453 {
15454 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15455 "** Add ACL MAC entry %i in WhiletList :"
15456 MAC_ADDRESS_STR, i,
15457 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
15458
15459 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
15460 sizeof(qcmacaddr));
15461 }
15462 }
15463 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
15464 {
15465 pConfig->num_deny_mac = params->n_acl_entries;
15466 for (i = 0; i < params->n_acl_entries; i++)
15467 {
15468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15469 "** Add ACL MAC entry %i in BlackList :"
15470 MAC_ADDRESS_STR, i,
15471 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
15472
15473 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
15474 sizeof(qcmacaddr));
15475 }
15476 }
15477
15478 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
15479 {
15480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15481 "%s: SAP Set Mac Acl fail", __func__);
15482 return -EINVAL;
15483 }
15484 }
15485 else
15486 {
15487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015488 "%s: Invalid device_mode = %s (%d)",
15489 __func__, hdd_device_modetoString(pAdapter->device_mode),
15490 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015491 return -EINVAL;
15492 }
15493
15494 return 0;
15495}
15496
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015497static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
15498 struct net_device *dev,
15499 const struct cfg80211_acl_data *params)
15500{
15501 int ret;
15502 vos_ssr_protect(__func__);
15503 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
15504 vos_ssr_unprotect(__func__);
15505
15506 return ret;
15507}
15508
Leo Chang9056f462013-08-01 19:21:11 -070015509#ifdef WLAN_NL80211_TESTMODE
15510#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070015511void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070015512(
15513 void *pAdapter,
15514 void *indCont
15515)
15516{
Leo Changd9df8aa2013-09-26 13:32:26 -070015517 tSirLPHBInd *lphbInd;
15518 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053015519 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070015520
15521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070015522 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070015523
c_hpothu73f35e62014-04-18 13:40:08 +053015524 if (pAdapter == NULL)
15525 {
15526 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15527 "%s: pAdapter is NULL\n",__func__);
15528 return;
15529 }
15530
Leo Chang9056f462013-08-01 19:21:11 -070015531 if (NULL == indCont)
15532 {
15533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070015534 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070015535 return;
15536 }
15537
c_hpothu73f35e62014-04-18 13:40:08 +053015538 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070015539 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070015540 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053015541 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070015542 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070015543 GFP_ATOMIC);
15544 if (!skb)
15545 {
15546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15547 "LPHB timeout, NL buffer alloc fail");
15548 return;
15549 }
15550
Leo Changac3ba772013-10-07 09:47:04 -070015551 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070015552 {
15553 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15554 "WLAN_HDD_TM_ATTR_CMD put fail");
15555 goto nla_put_failure;
15556 }
Leo Changac3ba772013-10-07 09:47:04 -070015557 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070015558 {
15559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15560 "WLAN_HDD_TM_ATTR_TYPE put fail");
15561 goto nla_put_failure;
15562 }
Leo Changac3ba772013-10-07 09:47:04 -070015563 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070015564 sizeof(tSirLPHBInd), lphbInd))
15565 {
15566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15567 "WLAN_HDD_TM_ATTR_DATA put fail");
15568 goto nla_put_failure;
15569 }
Leo Chang9056f462013-08-01 19:21:11 -070015570 cfg80211_testmode_event(skb, GFP_ATOMIC);
15571 return;
15572
15573nla_put_failure:
15574 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15575 "NLA Put fail");
15576 kfree_skb(skb);
15577
15578 return;
15579}
15580#endif /* FEATURE_WLAN_LPHB */
15581
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015582static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070015583{
15584 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
15585 int err = 0;
15586#ifdef FEATURE_WLAN_LPHB
15587 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070015588 eHalStatus smeStatus;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015589 err = wlan_hdd_validate_context(pHddCtx);
15590 if (0 != err)
15591 {
15592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15593 "%s: HDD context is not valid", __func__);
15594 return err;
15595 }
Leo Chang9056f462013-08-01 19:21:11 -070015596#endif /* FEATURE_WLAN_LPHB */
15597
15598 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
15599 if (err)
15600 {
15601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15602 "%s Testmode INV ATTR", __func__);
15603 return err;
15604 }
15605
15606 if (!tb[WLAN_HDD_TM_ATTR_CMD])
15607 {
15608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15609 "%s Testmode INV CMD", __func__);
15610 return -EINVAL;
15611 }
15612
15613 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
15614 {
15615#ifdef FEATURE_WLAN_LPHB
15616 /* Low Power Heartbeat configuration request */
15617 case WLAN_HDD_TM_CMD_WLAN_HB:
15618 {
15619 int buf_len;
15620 void *buf;
15621 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080015622 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070015623
15624 if (!tb[WLAN_HDD_TM_ATTR_DATA])
15625 {
15626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15627 "%s Testmode INV DATA", __func__);
15628 return -EINVAL;
15629 }
15630
15631 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
15632 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080015633
15634 hb_params_temp =(tSirLPHBReq *)buf;
15635 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
15636 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
15637 return -EINVAL;
15638
Leo Chang9056f462013-08-01 19:21:11 -070015639 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
15640 if (NULL == hb_params)
15641 {
15642 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15643 "%s Request Buffer Alloc Fail", __func__);
15644 return -EINVAL;
15645 }
15646
15647 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070015648 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
15649 hb_params,
15650 wlan_hdd_cfg80211_lphb_ind_handler);
15651 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070015652 {
Leo Changd9df8aa2013-09-26 13:32:26 -070015653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15654 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070015655 vos_mem_free(hb_params);
15656 }
Leo Chang9056f462013-08-01 19:21:11 -070015657 return 0;
15658 }
15659#endif /* FEATURE_WLAN_LPHB */
15660 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15662 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070015663 return -EOPNOTSUPP;
15664 }
15665
15666 return err;
15667}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015668
15669static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
15670{
15671 int ret;
15672
15673 vos_ssr_protect(__func__);
15674 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
15675 vos_ssr_unprotect(__func__);
15676
15677 return ret;
15678}
Leo Chang9056f462013-08-01 19:21:11 -070015679#endif /* CONFIG_NL80211_TESTMODE */
15680
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015681static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015682 struct net_device *dev,
15683 int idx, struct survey_info *survey)
15684{
15685 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15686 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053015687 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015688 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053015689 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015690 v_S7_t snr,rssi;
15691 int status, i, j, filled = 0;
15692
15693 ENTER();
15694
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015695 if (NULL == pAdapter)
15696 {
15697 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15698 "%s: HDD adapter is Null", __func__);
15699 return -ENODEV;
15700 }
15701
15702 if (NULL == wiphy)
15703 {
15704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15705 "%s: wiphy is Null", __func__);
15706 return -ENODEV;
15707 }
15708
15709 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15710 status = wlan_hdd_validate_context(pHddCtx);
15711
15712 if (0 != status)
15713 {
15714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15715 "%s: HDD context is not valid", __func__);
15716 return status;
15717 }
15718
Mihir Sheted9072e02013-08-21 17:02:29 +053015719 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15720
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015721 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053015722 0 != pAdapter->survey_idx ||
15723 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015724 {
15725 /* The survey dump ops when implemented completely is expected to
15726 * return a survey of all channels and the ops is called by the
15727 * kernel with incremental values of the argument 'idx' till it
15728 * returns -ENONET. But we can only support the survey for the
15729 * operating channel for now. survey_idx is used to track
15730 * that the ops is called only once and then return -ENONET for
15731 * the next iteration
15732 */
15733 pAdapter->survey_idx = 0;
15734 return -ENONET;
15735 }
15736
15737 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15738
15739 wlan_hdd_get_snr(pAdapter, &snr);
15740 wlan_hdd_get_rssi(pAdapter, &rssi);
15741
15742 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
15743 hdd_wlan_get_freq(channel, &freq);
15744
15745
15746 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
15747 {
15748 if (NULL == wiphy->bands[i])
15749 {
15750 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
15751 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
15752 continue;
15753 }
15754
15755 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
15756 {
15757 struct ieee80211_supported_band *band = wiphy->bands[i];
15758
15759 if (band->channels[j].center_freq == (v_U16_t)freq)
15760 {
15761 survey->channel = &band->channels[j];
15762 /* The Rx BDs contain SNR values in dB for the received frames
15763 * while the supplicant expects noise. So we calculate and
15764 * return the value of noise (dBm)
15765 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
15766 */
15767 survey->noise = rssi - snr;
15768 survey->filled = SURVEY_INFO_NOISE_DBM;
15769 filled = 1;
15770 }
15771 }
15772 }
15773
15774 if (filled)
15775 pAdapter->survey_idx = 1;
15776 else
15777 {
15778 pAdapter->survey_idx = 0;
15779 return -ENONET;
15780 }
15781
15782 return 0;
15783}
15784
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015785static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
15786 struct net_device *dev,
15787 int idx, struct survey_info *survey)
15788{
15789 int ret;
15790
15791 vos_ssr_protect(__func__);
15792 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
15793 vos_ssr_unprotect(__func__);
15794
15795 return ret;
15796}
15797
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015798/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015799 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015800 * this is called when cfg80211 driver resume
15801 * driver updates latest sched_scan scan result(if any) to cfg80211 database
15802 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015803int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015804{
15805 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15806 hdd_adapter_t *pAdapter;
15807 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15808 VOS_STATUS status = VOS_STATUS_SUCCESS;
15809
15810 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015811 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015812 {
15813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015814 "%s: Hdd Context is invalid", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015815 return 0;
15816 }
15817
15818 spin_lock(&pHddCtx->schedScan_lock);
15819 pHddCtx->isWiphySuspended = FALSE;
15820 if (TRUE != pHddCtx->isSchedScanUpdatePending)
15821 {
15822 spin_unlock(&pHddCtx->schedScan_lock);
15823 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15824 "%s: Return resume is not due to PNO indication", __func__);
15825 return 0;
15826 }
15827 // Reset flag to avoid updatating cfg80211 data old results again
15828 pHddCtx->isSchedScanUpdatePending = FALSE;
15829 spin_unlock(&pHddCtx->schedScan_lock);
15830
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015831
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015832 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15833
15834 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15835 {
15836 pAdapter = pAdapterNode->pAdapter;
15837 if ( (NULL != pAdapter) &&
15838 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
15839 {
15840 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015841 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15843 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015844 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015845 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015846 {
15847 /* Acquire wakelock to handle the case where APP's tries to
15848 * suspend immediately after updating the scan results. Whis
15849 * results in app's is in suspended state and not able to
15850 * process the connect request to AP
15851 */
15852 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015853 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015854 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015855
15856 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15857 "%s : cfg80211 scan result database updated", __func__);
15858
15859 return 0;
15860
15861 }
15862 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15863 pAdapterNode = pNext;
15864 }
15865
15866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15867 "%s: Failed to find Adapter", __func__);
15868 return 0;
15869}
15870
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015871int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
15872{
15873 int ret;
15874
15875 vos_ssr_protect(__func__);
15876 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
15877 vos_ssr_unprotect(__func__);
15878
15879 return ret;
15880}
15881
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015882/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015883 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015884 * this is called when cfg80211 driver suspends
15885 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015886int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015887 struct cfg80211_wowlan *wow)
15888{
15889 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015890 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015891
15892 ENTER();
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015893 ret = wlan_hdd_validate_context(pHddCtx);
15894 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015895 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15897 "%s: HDD context is not valid", __func__);
15898 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015899 }
15900
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015901
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015902 pHddCtx->isWiphySuspended = TRUE;
15903
15904 EXIT();
15905
15906 return 0;
15907}
15908
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015909int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
15910 struct cfg80211_wowlan *wow)
15911{
15912 int ret;
15913
15914 vos_ssr_protect(__func__);
15915 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
15916 vos_ssr_unprotect(__func__);
15917
15918 return ret;
15919}
Jeff Johnson295189b2012-06-20 16:38:30 -070015920/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015921static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070015922{
15923 .add_virtual_intf = wlan_hdd_add_virtual_intf,
15924 .del_virtual_intf = wlan_hdd_del_virtual_intf,
15925 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
15926 .change_station = wlan_hdd_change_station,
15927#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
15928 .add_beacon = wlan_hdd_cfg80211_add_beacon,
15929 .del_beacon = wlan_hdd_cfg80211_del_beacon,
15930 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015931#else
15932 .start_ap = wlan_hdd_cfg80211_start_ap,
15933 .change_beacon = wlan_hdd_cfg80211_change_beacon,
15934 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070015935#endif
15936 .change_bss = wlan_hdd_cfg80211_change_bss,
15937 .add_key = wlan_hdd_cfg80211_add_key,
15938 .get_key = wlan_hdd_cfg80211_get_key,
15939 .del_key = wlan_hdd_cfg80211_del_key,
15940 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015941#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070015942 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015943#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015944 .scan = wlan_hdd_cfg80211_scan,
15945 .connect = wlan_hdd_cfg80211_connect,
15946 .disconnect = wlan_hdd_cfg80211_disconnect,
15947 .join_ibss = wlan_hdd_cfg80211_join_ibss,
15948 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
15949 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
15950 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
15951 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070015952 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
15953 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053015954 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070015955#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15956 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
15957 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
15958 .set_txq_params = wlan_hdd_set_txq_params,
15959#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015960 .get_station = wlan_hdd_cfg80211_get_station,
15961 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
15962 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015963 .add_station = wlan_hdd_cfg80211_add_station,
15964#ifdef FEATURE_WLAN_LFR
15965 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
15966 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
15967 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
15968#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015969#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
15970 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
15971#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015972#ifdef FEATURE_WLAN_TDLS
15973 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
15974 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
15975#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015976#ifdef WLAN_FEATURE_GTK_OFFLOAD
15977 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
15978#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015979#ifdef FEATURE_WLAN_SCAN_PNO
15980 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
15981 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
15982#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015983 .resume = wlan_hdd_cfg80211_resume_wlan,
15984 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015985 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070015986#ifdef WLAN_NL80211_TESTMODE
15987 .testmode_cmd = wlan_hdd_cfg80211_testmode,
15988#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015989 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070015990};
15991