blob: 74c05a3fcb9988f1e2caa31eb8afba3c04a83308 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
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.
Kiet Lamaa8e15a2014-02-11 23:30:06 -080026 */
Kiet Lam842dad02014-02-18 18:44:02 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/**========================================================================
32
33 \file wlan_hdd_cfg80211.c
34
35 \brief WLAN Host Device Driver implementation
36
Jeff Johnson295189b2012-06-20 16:38:30 -070037 ========================================================================*/
38
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070039/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070040
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070041 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070042
43
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070044 This section contains comments describing changes made to the module.
45 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070046
47
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070048 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070049
50
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070051 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070052 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070053 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070054
55 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070056 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070057 ==========================================================================*/
58
Jeff Johnson295189b2012-06-20 16:38:30 -070059
60#include <linux/version.h>
61#include <linux/module.h>
62#include <linux/kernel.h>
63#include <linux/init.h>
64#include <linux/wireless.h>
65#include <wlan_hdd_includes.h>
66#include <net/arp.h>
67#include <net/cfg80211.h>
68#include <linux/wireless.h>
69#include <wlan_hdd_wowl.h>
70#include <aniGlobal.h>
71#include "ccmApi.h"
72#include "sirParams.h"
73#include "dot11f.h"
74#include "wlan_hdd_assoc.h"
75#include "wlan_hdd_wext.h"
76#include "sme_Api.h"
77#include "wlan_hdd_p2p.h"
78#include "wlan_hdd_cfg80211.h"
79#include "wlan_hdd_hostapd.h"
80#include "sapInternal.h"
81#include "wlan_hdd_softap_tx_rx.h"
82#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053083#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053084#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053085#include "wlan_hdd_trace.h"
86#include "vos_types.h"
87#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070088#ifdef WLAN_BTAMP_FEATURE
89#include "bap_hdd_misc.h"
90#endif
91#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080092#ifdef FEATURE_WLAN_TDLS
93#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080096#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053097#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070098#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070099
100#define g_mode_rates_size (12)
101#define a_mode_rates_size (8)
102#define FREQ_BASE_80211G (2407)
103#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700104#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530105#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700106#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800107 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700108
109#define HDD2GHZCHAN(freq, chan, flag) { \
110 .band = IEEE80211_BAND_2GHZ, \
111 .center_freq = (freq), \
112 .hw_value = (chan),\
113 .flags = (flag), \
114 .max_antenna_gain = 0 ,\
115 .max_power = 30, \
116}
117
118#define HDD5GHZCHAN(freq, chan, flag) { \
119 .band = IEEE80211_BAND_5GHZ, \
120 .center_freq = (freq), \
121 .hw_value = (chan),\
122 .flags = (flag), \
123 .max_antenna_gain = 0 ,\
124 .max_power = 30, \
125}
126
127#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
128{\
129 .bitrate = rate, \
130 .hw_value = rate_id, \
131 .flags = flag, \
132}
133
Lee Hoonkic1262f22013-01-24 21:59:00 -0800134#ifndef WLAN_FEATURE_TDLS_DEBUG
135#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
136#else
137#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
138#endif
139
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530140#ifdef WLAN_FEATURE_VOWIFI_11R
141#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
142#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
143#endif
144
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530145#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530146#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530147
Sunil Duttc69bccb2014-05-26 21:30:20 +0530148#ifdef WLAN_FEATURE_LINK_LAYER_STATS
149/*
150 * Used to allocate the size of 4096 for the link layer stats.
151 * The size of 4096 is considered assuming that all data per
152 * respective event fit with in the limit.Please take a call
153 * on the limit based on the data requirements on link layer
154 * statistics.
155 */
156#define LL_STATS_EVENT_BUF_SIZE 4096
157#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530158#ifdef WLAN_FEATURE_EXTSCAN
159/*
160 * Used to allocate the size of 4096 for the EXTScan NL data.
161 * The size of 4096 is considered assuming that all data per
162 * respective event fit with in the limit.Please take a call
163 * on the limit based on the data requirements.
164 */
165
166#define EXTSCAN_EVENT_BUF_SIZE 4096
167#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
168#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530169
Atul Mittal115287b2014-07-08 13:26:33 +0530170/*EXT TDLS*/
171/*
172 * Used to allocate the size of 4096 for the TDLS.
173 * The size of 4096 is considered assuming that all data per
174 * respective event fit with in the limit.Please take a call
175 * on the limit based on the data requirements on link layer
176 * statistics.
177 */
178#define EXTTDLS_EVENT_BUF_SIZE 4096
179
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530180static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700181{
182 WLAN_CIPHER_SUITE_WEP40,
183 WLAN_CIPHER_SUITE_WEP104,
184 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800185#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700186#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
187 WLAN_CIPHER_SUITE_KRK,
188 WLAN_CIPHER_SUITE_CCMP,
189#else
190 WLAN_CIPHER_SUITE_CCMP,
191#endif
192#ifdef FEATURE_WLAN_WAPI
193 WLAN_CIPHER_SUITE_SMS4,
194#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700195#ifdef WLAN_FEATURE_11W
196 WLAN_CIPHER_SUITE_AES_CMAC,
197#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700198};
199
200static inline int is_broadcast_ether_addr(const u8 *addr)
201{
202 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
203 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
204}
205
206static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530207{
Jeff Johnson295189b2012-06-20 16:38:30 -0700208 HDD2GHZCHAN(2412, 1, 0) ,
209 HDD2GHZCHAN(2417, 2, 0) ,
210 HDD2GHZCHAN(2422, 3, 0) ,
211 HDD2GHZCHAN(2427, 4, 0) ,
212 HDD2GHZCHAN(2432, 5, 0) ,
213 HDD2GHZCHAN(2437, 6, 0) ,
214 HDD2GHZCHAN(2442, 7, 0) ,
215 HDD2GHZCHAN(2447, 8, 0) ,
216 HDD2GHZCHAN(2452, 9, 0) ,
217 HDD2GHZCHAN(2457, 10, 0) ,
218 HDD2GHZCHAN(2462, 11, 0) ,
219 HDD2GHZCHAN(2467, 12, 0) ,
220 HDD2GHZCHAN(2472, 13, 0) ,
221 HDD2GHZCHAN(2484, 14, 0) ,
222};
223
Jeff Johnson295189b2012-06-20 16:38:30 -0700224static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
225{
226 HDD2GHZCHAN(2412, 1, 0) ,
227 HDD2GHZCHAN(2437, 6, 0) ,
228 HDD2GHZCHAN(2462, 11, 0) ,
229};
Jeff Johnson295189b2012-06-20 16:38:30 -0700230
231static struct ieee80211_channel hdd_channels_5_GHZ[] =
232{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700233 HDD5GHZCHAN(4920, 240, 0) ,
234 HDD5GHZCHAN(4940, 244, 0) ,
235 HDD5GHZCHAN(4960, 248, 0) ,
236 HDD5GHZCHAN(4980, 252, 0) ,
237 HDD5GHZCHAN(5040, 208, 0) ,
238 HDD5GHZCHAN(5060, 212, 0) ,
239 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700240 HDD5GHZCHAN(5180, 36, 0) ,
241 HDD5GHZCHAN(5200, 40, 0) ,
242 HDD5GHZCHAN(5220, 44, 0) ,
243 HDD5GHZCHAN(5240, 48, 0) ,
244 HDD5GHZCHAN(5260, 52, 0) ,
245 HDD5GHZCHAN(5280, 56, 0) ,
246 HDD5GHZCHAN(5300, 60, 0) ,
247 HDD5GHZCHAN(5320, 64, 0) ,
248 HDD5GHZCHAN(5500,100, 0) ,
249 HDD5GHZCHAN(5520,104, 0) ,
250 HDD5GHZCHAN(5540,108, 0) ,
251 HDD5GHZCHAN(5560,112, 0) ,
252 HDD5GHZCHAN(5580,116, 0) ,
253 HDD5GHZCHAN(5600,120, 0) ,
254 HDD5GHZCHAN(5620,124, 0) ,
255 HDD5GHZCHAN(5640,128, 0) ,
256 HDD5GHZCHAN(5660,132, 0) ,
257 HDD5GHZCHAN(5680,136, 0) ,
258 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800259#ifdef FEATURE_WLAN_CH144
260 HDD5GHZCHAN(5720,144, 0) ,
261#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700262 HDD5GHZCHAN(5745,149, 0) ,
263 HDD5GHZCHAN(5765,153, 0) ,
264 HDD5GHZCHAN(5785,157, 0) ,
265 HDD5GHZCHAN(5805,161, 0) ,
266 HDD5GHZCHAN(5825,165, 0) ,
267};
268
269static struct ieee80211_rate g_mode_rates[] =
270{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530271 HDD_G_MODE_RATETAB(10, 0x1, 0),
272 HDD_G_MODE_RATETAB(20, 0x2, 0),
273 HDD_G_MODE_RATETAB(55, 0x4, 0),
274 HDD_G_MODE_RATETAB(110, 0x8, 0),
275 HDD_G_MODE_RATETAB(60, 0x10, 0),
276 HDD_G_MODE_RATETAB(90, 0x20, 0),
277 HDD_G_MODE_RATETAB(120, 0x40, 0),
278 HDD_G_MODE_RATETAB(180, 0x80, 0),
279 HDD_G_MODE_RATETAB(240, 0x100, 0),
280 HDD_G_MODE_RATETAB(360, 0x200, 0),
281 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700282 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530283};
Jeff Johnson295189b2012-06-20 16:38:30 -0700284
285static struct ieee80211_rate a_mode_rates[] =
286{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530287 HDD_G_MODE_RATETAB(60, 0x10, 0),
288 HDD_G_MODE_RATETAB(90, 0x20, 0),
289 HDD_G_MODE_RATETAB(120, 0x40, 0),
290 HDD_G_MODE_RATETAB(180, 0x80, 0),
291 HDD_G_MODE_RATETAB(240, 0x100, 0),
292 HDD_G_MODE_RATETAB(360, 0x200, 0),
293 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700294 HDD_G_MODE_RATETAB(540, 0x800, 0),
295};
296
297static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
298{
299 .channels = hdd_channels_2_4_GHZ,
300 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
301 .band = IEEE80211_BAND_2GHZ,
302 .bitrates = g_mode_rates,
303 .n_bitrates = g_mode_rates_size,
304 .ht_cap.ht_supported = 1,
305 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
306 | IEEE80211_HT_CAP_GRN_FLD
307 | IEEE80211_HT_CAP_DSSSCCK40
308 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
309 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
310 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
311 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
312 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
313 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
314};
315
Jeff Johnson295189b2012-06-20 16:38:30 -0700316static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
317{
318 .channels = hdd_social_channels_2_4_GHZ,
319 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
320 .band = IEEE80211_BAND_2GHZ,
321 .bitrates = g_mode_rates,
322 .n_bitrates = g_mode_rates_size,
323 .ht_cap.ht_supported = 1,
324 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
325 | IEEE80211_HT_CAP_GRN_FLD
326 | IEEE80211_HT_CAP_DSSSCCK40
327 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
328 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
329 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
330 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
331 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
332 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
333};
Jeff Johnson295189b2012-06-20 16:38:30 -0700334
335static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
336{
337 .channels = hdd_channels_5_GHZ,
338 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
339 .band = IEEE80211_BAND_5GHZ,
340 .bitrates = a_mode_rates,
341 .n_bitrates = a_mode_rates_size,
342 .ht_cap.ht_supported = 1,
343 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
344 | IEEE80211_HT_CAP_GRN_FLD
345 | IEEE80211_HT_CAP_DSSSCCK40
346 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
347 | IEEE80211_HT_CAP_SGI_40
348 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
349 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
350 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
351 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
352 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
353 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
354};
355
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530356/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700357 TX/RX direction for each kind of interface */
358static const struct ieee80211_txrx_stypes
359wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
360 [NL80211_IFTYPE_STATION] = {
361 .tx = 0xffff,
362 .rx = BIT(SIR_MAC_MGMT_ACTION) |
363 BIT(SIR_MAC_MGMT_PROBE_REQ),
364 },
365 [NL80211_IFTYPE_AP] = {
366 .tx = 0xffff,
367 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
368 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
369 BIT(SIR_MAC_MGMT_PROBE_REQ) |
370 BIT(SIR_MAC_MGMT_DISASSOC) |
371 BIT(SIR_MAC_MGMT_AUTH) |
372 BIT(SIR_MAC_MGMT_DEAUTH) |
373 BIT(SIR_MAC_MGMT_ACTION),
374 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700375 [NL80211_IFTYPE_ADHOC] = {
376 .tx = 0xffff,
377 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
378 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
379 BIT(SIR_MAC_MGMT_PROBE_REQ) |
380 BIT(SIR_MAC_MGMT_DISASSOC) |
381 BIT(SIR_MAC_MGMT_AUTH) |
382 BIT(SIR_MAC_MGMT_DEAUTH) |
383 BIT(SIR_MAC_MGMT_ACTION),
384 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700385 [NL80211_IFTYPE_P2P_CLIENT] = {
386 .tx = 0xffff,
387 .rx = BIT(SIR_MAC_MGMT_ACTION) |
388 BIT(SIR_MAC_MGMT_PROBE_REQ),
389 },
390 [NL80211_IFTYPE_P2P_GO] = {
391 /* This is also same as for SoftAP */
392 .tx = 0xffff,
393 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
394 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
395 BIT(SIR_MAC_MGMT_PROBE_REQ) |
396 BIT(SIR_MAC_MGMT_DISASSOC) |
397 BIT(SIR_MAC_MGMT_AUTH) |
398 BIT(SIR_MAC_MGMT_DEAUTH) |
399 BIT(SIR_MAC_MGMT_ACTION),
400 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700401};
402
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800403#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800404static const struct ieee80211_iface_limit
405wlan_hdd_iface_limit[] = {
406 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800407 /* max = 3 ; Our driver create two interfaces during driver init
408 * wlan0 and p2p0 interfaces. p2p0 is considered as station
409 * interface until a group is formed. In JB architecture, once the
410 * group is formed, interface type of p2p0 is changed to P2P GO or
411 * Client.
412 * When supplicant remove the group, it first issue a set interface
413 * cmd to change the mode back to Station. In JB this works fine as
414 * we advertize two station type interface during driver init.
415 * Some vendors create separate interface for P2P GO/Client,
416 * after group formation(Third one). But while group remove
417 * supplicant first tries to change the mode(3rd interface) to STATION
418 * But as we advertized only two sta type interfaces nl80211 was
419 * returning error for the third one which was leading to failure in
420 * delete interface. Ideally while removing the group, supplicant
421 * should not try to change the 3rd interface mode to Station type.
422 * Till we get a fix in wpa_supplicant, we advertize max STA
423 * interface type to 3
424 */
425 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800426 .types = BIT(NL80211_IFTYPE_STATION),
427 },
428 {
429 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700430 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800431 },
432 {
433 .max = 1,
434 .types = BIT(NL80211_IFTYPE_P2P_GO) |
435 BIT(NL80211_IFTYPE_P2P_CLIENT),
436 },
437};
438
439/* By default, only single channel concurrency is allowed */
440static struct ieee80211_iface_combination
441wlan_hdd_iface_combination = {
442 .limits = wlan_hdd_iface_limit,
443 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800444 /*
445 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
446 * and p2p0 interfaces during driver init
447 * Some vendors create separate interface for P2P operations.
448 * wlan0: STA interface
449 * p2p0: P2P Device interface, action frames goes
450 * through this interface.
451 * p2p-xx: P2P interface, After GO negotiation this interface is
452 * created for p2p operations(GO/CLIENT interface).
453 */
454 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800455 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
456 .beacon_int_infra_match = false,
457};
458#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800459
Jeff Johnson295189b2012-06-20 16:38:30 -0700460static struct cfg80211_ops wlan_hdd_cfg80211_ops;
461
462/* Data rate 100KBPS based on IE Index */
463struct index_data_rate_type
464{
465 v_U8_t beacon_rate_index;
466 v_U16_t supported_rate[4];
467};
468
469/* 11B, 11G Rate table include Basic rate and Extended rate
470 The IDX field is the rate index
471 The HI field is the rate when RSSI is strong or being ignored
472 (in this case we report actual rate)
473 The MID field is the rate when RSSI is moderate
474 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
475 The LO field is the rate when RSSI is low
476 (in this case we don't report rates, actual current rate used)
477 */
478static const struct
479{
480 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700481 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700482} supported_data_rate[] =
483{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700484/* IDX HI HM LM LO (RSSI-based index */
485 {2, { 10, 10, 10, 0}},
486 {4, { 20, 20, 10, 0}},
487 {11, { 55, 20, 10, 0}},
488 {12, { 60, 55, 20, 0}},
489 {18, { 90, 55, 20, 0}},
490 {22, {110, 55, 20, 0}},
491 {24, {120, 90, 60, 0}},
492 {36, {180, 120, 60, 0}},
493 {44, {220, 180, 60, 0}},
494 {48, {240, 180, 90, 0}},
495 {66, {330, 180, 90, 0}},
496 {72, {360, 240, 90, 0}},
497 {96, {480, 240, 120, 0}},
498 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700499};
500
501/* MCS Based rate table */
502static struct index_data_rate_type supported_mcs_rate[] =
503{
504/* MCS L20 L40 S20 S40 */
505 {0, {65, 135, 72, 150}},
506 {1, {130, 270, 144, 300}},
507 {2, {195, 405, 217, 450}},
508 {3, {260, 540, 289, 600}},
509 {4, {390, 810, 433, 900}},
510 {5, {520, 1080, 578, 1200}},
511 {6, {585, 1215, 650, 1350}},
512 {7, {650, 1350, 722, 1500}}
513};
514
Leo Chang6f8870f2013-03-26 18:11:36 -0700515#ifdef WLAN_FEATURE_11AC
516
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530517#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700518
519struct index_vht_data_rate_type
520{
521 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530522 v_U16_t supported_VHT80_rate[2];
523 v_U16_t supported_VHT40_rate[2];
524 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700525};
526
527typedef enum
528{
529 DATA_RATE_11AC_MAX_MCS_7,
530 DATA_RATE_11AC_MAX_MCS_8,
531 DATA_RATE_11AC_MAX_MCS_9,
532 DATA_RATE_11AC_MAX_MCS_NA
533} eDataRate11ACMaxMcs;
534
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530535/* SSID broadcast type */
536typedef enum eSSIDBcastType
537{
538 eBCAST_UNKNOWN = 0,
539 eBCAST_NORMAL = 1,
540 eBCAST_HIDDEN = 2,
541} tSSIDBcastType;
542
Leo Chang6f8870f2013-03-26 18:11:36 -0700543/* MCS Based VHT rate table */
544static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
545{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530546/* MCS L80 S80 L40 S40 L20 S40*/
547 {0, {293, 325}, {135, 150}, {65, 72}},
548 {1, {585, 650}, {270, 300}, {130, 144}},
549 {2, {878, 975}, {405, 450}, {195, 217}},
550 {3, {1170, 1300}, {540, 600}, {260, 289}},
551 {4, {1755, 1950}, {810, 900}, {390, 433}},
552 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
553 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
554 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
555 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
556 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700557};
558#endif /* WLAN_FEATURE_11AC */
559
c_hpothu79aab322014-07-14 21:11:01 +0530560/*array index points to MCS and array value points respective rssi*/
561static int rssiMcsTbl[][10] =
562{
563/*MCS 0 1 2 3 4 5 6 7 8 9*/
564 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
565 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
566 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
567};
568
Jeff Johnson295189b2012-06-20 16:38:30 -0700569extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530570#ifdef FEATURE_WLAN_SCAN_PNO
571static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
572#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700573
Leo Chang9056f462013-08-01 19:21:11 -0700574#ifdef WLAN_NL80211_TESTMODE
575enum wlan_hdd_tm_attr
576{
577 WLAN_HDD_TM_ATTR_INVALID = 0,
578 WLAN_HDD_TM_ATTR_CMD = 1,
579 WLAN_HDD_TM_ATTR_DATA = 2,
580 WLAN_HDD_TM_ATTR_TYPE = 3,
581 /* keep last */
582 WLAN_HDD_TM_ATTR_AFTER_LAST,
583 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
584};
585
586enum wlan_hdd_tm_cmd
587{
588 WLAN_HDD_TM_CMD_WLAN_HB = 1,
589};
590
591#define WLAN_HDD_TM_DATA_MAX_LEN 5000
592
593static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
594{
595 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
596 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
597 .len = WLAN_HDD_TM_DATA_MAX_LEN },
598};
599#endif /* WLAN_NL80211_TESTMODE */
600
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800601#ifdef FEATURE_WLAN_CH_AVOID
602/*
603 * FUNCTION: wlan_hdd_send_avoid_freq_event
604 * This is called when wlan driver needs to send vendor specific
605 * avoid frequency range event to userspace
606 */
607int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
608 tHddAvoidFreqList *pAvoidFreqList)
609{
610 struct sk_buff *vendor_event;
611
612 ENTER();
613
614 if (!pHddCtx)
615 {
616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
617 "%s: HDD context is null", __func__);
618 return -1;
619 }
620
621 if (!pAvoidFreqList)
622 {
623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
624 "%s: pAvoidFreqList is null", __func__);
625 return -1;
626 }
627
628 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
629 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530630 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800631 GFP_KERNEL);
632 if (!vendor_event)
633 {
634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
635 "%s: cfg80211_vendor_event_alloc failed", __func__);
636 return -1;
637 }
638
639 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
640 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
641
642 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
643
644 EXIT();
645 return 0;
646}
647#endif /* FEATURE_WLAN_CH_AVOID */
648
Sunil Duttc69bccb2014-05-26 21:30:20 +0530649#ifdef WLAN_FEATURE_LINK_LAYER_STATS
650
651static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
652 struct sk_buff *vendor_event)
653{
654 if (nla_put_u8(vendor_event,
655 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
656 stats->rate.preamble) ||
657 nla_put_u8(vendor_event,
658 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
659 stats->rate.nss) ||
660 nla_put_u8(vendor_event,
661 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
662 stats->rate.bw) ||
663 nla_put_u8(vendor_event,
664 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
665 stats->rate.rateMcsIdx) ||
666 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
667 stats->rate.bitrate ) ||
668 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
669 stats->txMpdu ) ||
670 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
671 stats->rxMpdu ) ||
672 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
673 stats->mpduLost ) ||
674 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
675 stats->retries) ||
676 nla_put_u32(vendor_event,
677 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
678 stats->retriesShort ) ||
679 nla_put_u32(vendor_event,
680 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
681 stats->retriesLong))
682 {
683 hddLog(VOS_TRACE_LEVEL_ERROR,
684 FL("QCA_WLAN_VENDOR_ATTR put fail"));
685 return FALSE;
686 }
687 return TRUE;
688}
689
690static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
691 struct sk_buff *vendor_event)
692{
693 u32 i = 0;
694 struct nlattr *rateInfo;
695 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
696 stats->type) ||
697 nla_put(vendor_event,
698 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
699 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
700 nla_put_u32(vendor_event,
701 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
702 stats->capabilities) ||
703 nla_put_u32(vendor_event,
704 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
705 stats->numRate))
706 {
707 hddLog(VOS_TRACE_LEVEL_ERROR,
708 FL("QCA_WLAN_VENDOR_ATTR put fail"));
709 goto error;
710 }
711
712 rateInfo = nla_nest_start(vendor_event,
713 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
714 for (i = 0; i < stats->numRate; i++)
715 {
716 struct nlattr *rates;
717 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
718 stats->rateStats +
719 (i * sizeof(tSirWifiRateStat)));
720 rates = nla_nest_start(vendor_event, i);
721
722 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
723 {
724 hddLog(VOS_TRACE_LEVEL_ERROR,
725 FL("QCA_WLAN_VENDOR_ATTR put fail"));
726 return FALSE;
727 }
728 nla_nest_end(vendor_event, rates);
729 }
730 nla_nest_end(vendor_event, rateInfo);
731
732 return TRUE;
733error:
734 return FALSE;
735}
736
737static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
738 struct sk_buff *vendor_event)
739{
740 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
741 stats->ac ) ||
742 nla_put_u32(vendor_event,
743 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
744 stats->txMpdu ) ||
745 nla_put_u32(vendor_event,
746 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
747 stats->rxMpdu ) ||
748 nla_put_u32(vendor_event,
749 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
750 stats->txMcast ) ||
751 nla_put_u32(vendor_event,
752 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
753 stats->rxMcast ) ||
754 nla_put_u32(vendor_event,
755 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
756 stats->rxAmpdu ) ||
757 nla_put_u32(vendor_event,
758 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
759 stats->txAmpdu ) ||
760 nla_put_u32(vendor_event,
761 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
762 stats->mpduLost )||
763 nla_put_u32(vendor_event,
764 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
765 stats->retries ) ||
766 nla_put_u32(vendor_event,
767 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
768 stats->retriesShort ) ||
769 nla_put_u32(vendor_event,
770 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
771 stats->retriesLong ) ||
772 nla_put_u32(vendor_event,
773 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
774 stats->contentionTimeMin ) ||
775 nla_put_u32(vendor_event,
776 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
777 stats->contentionTimeMax ) ||
778 nla_put_u32(vendor_event,
779 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
780 stats->contentionTimeAvg ) ||
781 nla_put_u32(vendor_event,
782 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
783 stats->contentionNumSamples ))
784 {
785 hddLog(VOS_TRACE_LEVEL_ERROR,
786 FL("QCA_WLAN_VENDOR_ATTR put fail") );
787 return FALSE;
788 }
789 return TRUE;
790}
791
792static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
793 struct sk_buff *vendor_event)
794{
Dino Myclec8f3f332014-07-21 16:48:27 +0530795 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530796 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
797 nla_put(vendor_event,
798 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
799 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
800 nla_put_u32(vendor_event,
801 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
802 stats->state ) ||
803 nla_put_u32(vendor_event,
804 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
805 stats->roaming ) ||
806 nla_put_u32(vendor_event,
807 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
808 stats->capabilities ) ||
809 nla_put(vendor_event,
810 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
811 strlen(stats->ssid), stats->ssid) ||
812 nla_put(vendor_event,
813 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
814 WNI_CFG_BSSID_LEN, stats->bssid) ||
815 nla_put(vendor_event,
816 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
817 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
818 nla_put(vendor_event,
819 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
820 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
821 )
822 {
823 hddLog(VOS_TRACE_LEVEL_ERROR,
824 FL("QCA_WLAN_VENDOR_ATTR put fail") );
825 return FALSE;
826 }
827 return TRUE;
828}
829
Dino Mycle3b9536d2014-07-09 22:05:24 +0530830static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
831 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530832 struct sk_buff *vendor_event)
833{
834 int i = 0;
835 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530836 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
837 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530838 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530839
Sunil Duttc69bccb2014-05-26 21:30:20 +0530840 if (FALSE == put_wifi_interface_info(
841 &pWifiIfaceStat->info,
842 vendor_event))
843 {
844 hddLog(VOS_TRACE_LEVEL_ERROR,
845 FL("QCA_WLAN_VENDOR_ATTR put fail") );
846 return FALSE;
847
848 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530849 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
850 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
851 if (NULL == pWifiIfaceStatTL)
852 {
853 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
854 return FALSE;
855 }
856
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530857 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
858 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
859 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
860 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
861
862 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
863 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
864 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
865 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530866
867 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
868 {
869 if (VOS_STATUS_SUCCESS ==
870 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
871 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
872 {
873 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
874 * obtained from TL structure
875 */
876
877 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
878 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530879 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
880
Srinivas Dasari98947432014-11-07 19:41:24 +0530881 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
882 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
883 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
884 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
885 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
886 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
887 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
888 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530889
Srinivas Dasari98947432014-11-07 19:41:24 +0530890 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
891 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
892 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
893 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
894 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
895 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
896 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
897 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530898
Srinivas Dasari98947432014-11-07 19:41:24 +0530899 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
900 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
901 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
902 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
903 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
904 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
905 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
906 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530907 }
908 else
909 {
910 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
911 }
912
Dino Mycle3b9536d2014-07-09 22:05:24 +0530913 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
914 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
915 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
916 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
917 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
918 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
919 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
920 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
921 }
922 else
923 {
924 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
925 }
926
927
Sunil Duttc69bccb2014-05-26 21:30:20 +0530928
929 if (nla_put_u32(vendor_event,
930 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
931 pWifiIfaceStat->beaconRx) ||
932 nla_put_u32(vendor_event,
933 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
934 pWifiIfaceStat->mgmtRx) ||
935 nla_put_u32(vendor_event,
936 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
937 pWifiIfaceStat->mgmtActionRx) ||
938 nla_put_u32(vendor_event,
939 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
940 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530941 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530942 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
943 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530944 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530945 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
946 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530947 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530948 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
949 pWifiIfaceStat->rssiAck))
950 {
951 hddLog(VOS_TRACE_LEVEL_ERROR,
952 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530953 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530954 return FALSE;
955 }
956
957 wmmInfo = nla_nest_start(vendor_event,
958 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
959 for (i = 0; i < WIFI_AC_MAX; i++)
960 {
961 struct nlattr *wmmStats;
962 wmmStats = nla_nest_start(vendor_event, i);
963 if (FALSE == put_wifi_wmm_ac_stat(
964 &pWifiIfaceStat->AccessclassStats[i],
965 vendor_event))
966 {
967 hddLog(VOS_TRACE_LEVEL_ERROR,
968 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530969 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530970 return FALSE;
971 }
972
973 nla_nest_end(vendor_event, wmmStats);
974 }
975 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +0530976 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530977 return TRUE;
978}
979
980static tSirWifiInterfaceMode
981 hdd_map_device_to_ll_iface_mode ( int deviceMode )
982{
983 switch (deviceMode)
984 {
985 case WLAN_HDD_INFRA_STATION:
986 return WIFI_INTERFACE_STA;
987 case WLAN_HDD_SOFTAP:
988 return WIFI_INTERFACE_SOFTAP;
989 case WLAN_HDD_P2P_CLIENT:
990 return WIFI_INTERFACE_P2P_CLIENT;
991 case WLAN_HDD_P2P_GO:
992 return WIFI_INTERFACE_P2P_GO;
993 case WLAN_HDD_IBSS:
994 return WIFI_INTERFACE_IBSS;
995 default:
Dino Myclec8f3f332014-07-21 16:48:27 +0530996 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530997 }
998}
999
1000static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1001 tpSirWifiInterfaceInfo pInfo)
1002{
1003 v_U8_t *staMac = NULL;
1004 hdd_station_ctx_t *pHddStaCtx;
1005 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1006 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1007
1008 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1009
1010 vos_mem_copy(pInfo->macAddr,
1011 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1012
1013 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1014 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1015 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1016 {
1017 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1018 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1019 {
1020 pInfo->state = WIFI_DISCONNECTED;
1021 }
1022 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1023 {
1024 hddLog(VOS_TRACE_LEVEL_ERROR,
1025 "%s: Session ID %d, Connection is in progress", __func__,
1026 pAdapter->sessionId);
1027 pInfo->state = WIFI_ASSOCIATING;
1028 }
1029 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1030 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1031 {
1032 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1033 hddLog(VOS_TRACE_LEVEL_ERROR,
1034 "%s: client " MAC_ADDRESS_STR
1035 " is in the middle of WPS/EAPOL exchange.", __func__,
1036 MAC_ADDR_ARRAY(staMac));
1037 pInfo->state = WIFI_AUTHENTICATING;
1038 }
1039 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1040 {
1041 pInfo->state = WIFI_ASSOCIATED;
1042 vos_mem_copy(pInfo->bssid,
1043 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1044 vos_mem_copy(pInfo->ssid,
1045 pHddStaCtx->conn_info.SSID.SSID.ssId,
1046 pHddStaCtx->conn_info.SSID.SSID.length);
1047 //NULL Terminate the string.
1048 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1049 }
1050 }
1051 vos_mem_copy(pInfo->countryStr,
1052 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1053
1054 vos_mem_copy(pInfo->apCountryStr,
1055 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1056
1057 return TRUE;
1058}
1059
1060/*
1061 * hdd_link_layer_process_peer_stats () - This function is called after
1062 * receiving Link Layer Peer statistics from FW.This function converts
1063 * the firmware data to the NL data and sends the same to the kernel/upper
1064 * layers.
1065 */
1066static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1067 v_VOID_t *pData)
1068{
1069 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1070 tpSirWifiRateStat pWifiRateStat;
1071 tpSirWifiPeerStat pWifiPeerStat;
1072 tpSirWifiPeerInfo pWifiPeerInfo;
1073 struct nlattr *peerInfo;
1074 struct sk_buff *vendor_event;
1075 int status, i;
1076
1077 status = wlan_hdd_validate_context(pHddCtx);
1078 if (0 != status)
1079 {
1080 hddLog(VOS_TRACE_LEVEL_ERROR,
1081 FL("HDD context is not valid") );
1082 return;
1083 }
1084
1085 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1086
1087 hddLog(VOS_TRACE_LEVEL_INFO,
1088 "LL_STATS_PEER_ALL : numPeers %u",
1089 pWifiPeerStat->numPeers);
1090 {
1091 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1092 {
1093 pWifiPeerInfo = (tpSirWifiPeerInfo)
1094 ((uint8 *)pWifiPeerStat->peerInfo +
1095 ( i * sizeof(tSirWifiPeerInfo)));
1096
Dasari Srinivas1be0c4e2014-10-19 13:03:41 +05301097 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) {
1098 pWifiPeerInfo->type = WIFI_PEER_AP;
1099 }
1100 if (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) {
1101 pWifiPeerInfo->type = WIFI_PEER_P2P_GO;
1102 }
1103
Sunil Duttc69bccb2014-05-26 21:30:20 +05301104 hddLog(VOS_TRACE_LEVEL_INFO,
1105 " %d) LL_STATS Channel Stats "
1106 " Peer Type %u "
1107 " peerMacAddress %pM "
1108 " capabilities 0x%x "
1109 " numRate %u ",
1110 i,
1111 pWifiPeerInfo->type,
1112 pWifiPeerInfo->peerMacAddress,
1113 pWifiPeerInfo->capabilities,
1114 pWifiPeerInfo->numRate);
1115 {
1116 int j;
1117 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1118 {
1119 pWifiRateStat = (tpSirWifiRateStat)
1120 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1121 ( j * sizeof(tSirWifiRateStat)));
1122
1123 hddLog(VOS_TRACE_LEVEL_INFO,
1124 " peer Rate Stats "
1125 " preamble %u "
1126 " nss %u "
1127 " bw %u "
1128 " rateMcsIdx %u "
1129 " reserved %u "
1130 " bitrate %u "
1131 " txMpdu %u "
1132 " rxMpdu %u "
1133 " mpduLost %u "
1134 " retries %u "
1135 " retriesShort %u "
1136 " retriesLong %u",
1137 pWifiRateStat->rate.preamble,
1138 pWifiRateStat->rate.nss,
1139 pWifiRateStat->rate.bw,
1140 pWifiRateStat->rate.rateMcsIdx,
1141 pWifiRateStat->rate.reserved,
1142 pWifiRateStat->rate.bitrate,
1143 pWifiRateStat->txMpdu,
1144 pWifiRateStat->rxMpdu,
1145 pWifiRateStat->mpduLost,
1146 pWifiRateStat->retries,
1147 pWifiRateStat->retriesShort,
1148 pWifiRateStat->retriesLong);
1149 }
1150 }
1151 }
1152 }
1153
1154 /*
1155 * Allocate a size of 4096 for the peer stats comprising
1156 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1157 * sizeof (tSirWifiRateStat).Each field is put with an
1158 * NL attribute.The size of 4096 is considered assuming
1159 * that number of rates shall not exceed beyond 50 with
1160 * the sizeof (tSirWifiRateStat) being 32.
1161 */
1162 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1163 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1164 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1165 GFP_KERNEL);
1166 if (!vendor_event)
1167 {
1168 hddLog(VOS_TRACE_LEVEL_ERROR,
1169 "%s: cfg80211_vendor_event_alloc failed",
1170 __func__);
1171 return;
1172 }
1173 if (nla_put_u32(vendor_event,
1174 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1175 pWifiPeerStat->numPeers))
1176 {
1177 hddLog(VOS_TRACE_LEVEL_ERROR,
1178 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1179 kfree_skb(vendor_event);
1180 return;
1181 }
1182
1183 peerInfo = nla_nest_start(vendor_event,
1184 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
1185
1186 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1187 pWifiPeerStat->peerInfo);
1188
1189 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1190 {
1191 struct nlattr *peers = nla_nest_start(vendor_event, i);
1192 int numRate = pWifiPeerInfo->numRate;
1193
1194 if (FALSE == put_wifi_peer_info(
1195 pWifiPeerInfo, vendor_event))
1196 {
1197 hddLog(VOS_TRACE_LEVEL_ERROR,
1198 "%s: put_wifi_peer_info put fail", __func__);
1199 kfree_skb(vendor_event);
1200 return;
1201 }
1202
1203 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1204 pWifiPeerStat->peerInfo +
1205 (i * sizeof(tSirWifiPeerInfo)) +
1206 (numRate * sizeof (tSirWifiRateStat)));
1207 nla_nest_end(vendor_event, peers);
1208 }
1209 nla_nest_end(vendor_event, peerInfo);
1210 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1211}
1212
1213/*
1214 * hdd_link_layer_process_iface_stats () - This function is called after
1215 * receiving Link Layer Interface statistics from FW.This function converts
1216 * the firmware data to the NL data and sends the same to the kernel/upper
1217 * layers.
1218 */
1219static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1220 v_VOID_t *pData)
1221{
1222 tpSirWifiIfaceStat pWifiIfaceStat;
1223 struct sk_buff *vendor_event;
1224 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1225 int status;
1226
1227 status = wlan_hdd_validate_context(pHddCtx);
1228 if (0 != status)
1229 {
1230 hddLog(VOS_TRACE_LEVEL_ERROR,
1231 FL("HDD context is not valid") );
1232 return;
1233 }
1234 /*
1235 * Allocate a size of 4096 for the interface stats comprising
1236 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1237 * assuming that all these fit with in the limit.Please take
1238 * a call on the limit based on the data requirements on
1239 * interface statistics.
1240 */
1241 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1242 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1243 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1244 GFP_KERNEL);
1245 if (!vendor_event)
1246 {
1247 hddLog(VOS_TRACE_LEVEL_ERROR,
1248 FL("cfg80211_vendor_event_alloc failed") );
1249 return;
1250 }
1251
1252 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1253
Dino Mycle3b9536d2014-07-09 22:05:24 +05301254
1255 if (FALSE == hdd_get_interface_info( pAdapter,
1256 &pWifiIfaceStat->info))
1257 {
1258 hddLog(VOS_TRACE_LEVEL_ERROR,
1259 FL("hdd_get_interface_info get fail") );
1260 kfree_skb(vendor_event);
1261 return;
1262 }
1263
1264 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1265 vendor_event))
1266 {
1267 hddLog(VOS_TRACE_LEVEL_ERROR,
1268 FL("put_wifi_iface_stats fail") );
1269 kfree_skb(vendor_event);
1270 return;
1271 }
1272
Sunil Duttc69bccb2014-05-26 21:30:20 +05301273 hddLog(VOS_TRACE_LEVEL_INFO,
1274 "WMI_LINK_STATS_IFACE Data");
1275
1276 hddLog(VOS_TRACE_LEVEL_INFO,
1277 "LL_STATS_IFACE: "
1278 " Mode %u "
1279 " MAC %pM "
1280 " State %u "
1281 " Roaming %u "
1282 " capabilities 0x%x "
1283 " SSID %s "
1284 " BSSID %pM",
1285 pWifiIfaceStat->info.mode,
1286 pWifiIfaceStat->info.macAddr,
1287 pWifiIfaceStat->info.state,
1288 pWifiIfaceStat->info.roaming,
1289 pWifiIfaceStat->info.capabilities,
1290 pWifiIfaceStat->info.ssid,
1291 pWifiIfaceStat->info.bssid);
1292
1293 hddLog(VOS_TRACE_LEVEL_INFO,
1294 " AP country str: %c%c%c",
1295 pWifiIfaceStat->info.apCountryStr[0],
1296 pWifiIfaceStat->info.apCountryStr[1],
1297 pWifiIfaceStat->info.apCountryStr[2]);
1298
1299
1300 hddLog(VOS_TRACE_LEVEL_INFO,
1301 " Country Str Association: %c%c%c",
1302 pWifiIfaceStat->info.countryStr[0],
1303 pWifiIfaceStat->info.countryStr[1],
1304 pWifiIfaceStat->info.countryStr[2]);
1305
1306 hddLog(VOS_TRACE_LEVEL_INFO,
1307 " beaconRx %u "
1308 " mgmtRx %u "
1309 " mgmtActionRx %u "
1310 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301311 " rssiMgmt %d "
1312 " rssiData %d "
1313 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301314 pWifiIfaceStat->beaconRx,
1315 pWifiIfaceStat->mgmtRx,
1316 pWifiIfaceStat->mgmtActionRx,
1317 pWifiIfaceStat->mgmtActionTx,
1318 pWifiIfaceStat->rssiMgmt,
1319 pWifiIfaceStat->rssiData,
1320 pWifiIfaceStat->rssiAck );
1321
1322
1323 {
1324 int i;
1325 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1326 {
1327 hddLog(VOS_TRACE_LEVEL_INFO,
1328
1329 " %d) LL_STATS IFACE: "
1330 " ac: %u txMpdu: %u "
1331 " rxMpdu: %u txMcast: %u "
1332 " rxMcast: %u rxAmpdu: %u "
1333 " txAmpdu: %u mpduLost: %u "
1334 " retries: %u retriesShort: %u "
1335 " retriesLong: %u contentionTimeMin: %u "
1336 " contentionTimeMax: %u contentionTimeAvg: %u "
1337 " contentionNumSamples: %u",
1338 i,
1339 pWifiIfaceStat->AccessclassStats[i].ac,
1340 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1341 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1342 pWifiIfaceStat->AccessclassStats[i].txMcast,
1343 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1344 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1345 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1346 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1347 pWifiIfaceStat->AccessclassStats[i].retries,
1348 pWifiIfaceStat->
1349 AccessclassStats[i].retriesShort,
1350 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1351 pWifiIfaceStat->
1352 AccessclassStats[i].contentionTimeMin,
1353 pWifiIfaceStat->
1354 AccessclassStats[i].contentionTimeMax,
1355 pWifiIfaceStat->
1356 AccessclassStats[i].contentionTimeAvg,
1357 pWifiIfaceStat->
1358 AccessclassStats[i].contentionNumSamples);
1359
1360 }
1361 }
1362
Sunil Duttc69bccb2014-05-26 21:30:20 +05301363 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1364}
1365
1366/*
1367 * hdd_link_layer_process_radio_stats () - This function is called after
1368 * receiving Link Layer Radio statistics from FW.This function converts
1369 * the firmware data to the NL data and sends the same to the kernel/upper
1370 * layers.
1371 */
1372static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1373 v_VOID_t *pData)
1374{
1375 int status, i;
1376 tpSirWifiRadioStat pWifiRadioStat;
1377 tpSirWifiChannelStats pWifiChannelStats;
1378 struct sk_buff *vendor_event;
1379 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1380 struct nlattr *chList;
1381
1382 status = wlan_hdd_validate_context(pHddCtx);
1383 if (0 != status)
1384 {
1385 hddLog(VOS_TRACE_LEVEL_ERROR,
1386 FL("HDD context is not valid") );
1387 return;
1388 }
1389 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1390
1391 hddLog(VOS_TRACE_LEVEL_INFO,
1392 "LL_STATS_RADIO"
1393 " radio is %d onTime is %u "
1394 " txTime is %u rxTime is %u "
1395 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301396 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301397 " onTimePnoScan is %u onTimeHs20 is %u "
1398 " numChannels is %u",
1399 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1400 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1401 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301402 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301403 pWifiRadioStat->onTimeRoamScan,
1404 pWifiRadioStat->onTimePnoScan,
1405 pWifiRadioStat->onTimeHs20,
1406 pWifiRadioStat->numChannels);
1407 /*
1408 * Allocate a size of 4096 for the Radio stats comprising
1409 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1410 * (tSirWifiChannelStats).Each channel data is put with an
1411 * NL attribute.The size of 4096 is considered assuming that
1412 * number of channels shall not exceed beyond 60 with the
1413 * sizeof (tSirWifiChannelStats) being 24 bytes.
1414 */
1415
1416 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1417 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1418 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1419 GFP_KERNEL);
1420
1421 if (!vendor_event)
1422 {
1423 hddLog(VOS_TRACE_LEVEL_ERROR,
1424 FL("cfg80211_vendor_event_alloc failed") );
1425 return;
1426 }
1427
1428 if (nla_put_u32(vendor_event,
1429 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1430 pWifiRadioStat->radio) ||
1431 nla_put_u32(vendor_event,
1432 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1433 pWifiRadioStat->onTime) ||
1434 nla_put_u32(vendor_event,
1435 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1436 pWifiRadioStat->txTime) ||
1437 nla_put_u32(vendor_event,
1438 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1439 pWifiRadioStat->rxTime) ||
1440 nla_put_u32(vendor_event,
1441 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1442 pWifiRadioStat->onTimeScan) ||
1443 nla_put_u32(vendor_event,
1444 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1445 pWifiRadioStat->onTimeNbd) ||
1446 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301447 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1448 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301449 nla_put_u32(vendor_event,
1450 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1451 pWifiRadioStat->onTimeRoamScan) ||
1452 nla_put_u32(vendor_event,
1453 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1454 pWifiRadioStat->onTimePnoScan) ||
1455 nla_put_u32(vendor_event,
1456 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1457 pWifiRadioStat->onTimeHs20) ||
1458 nla_put_u32(vendor_event,
1459 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1460 pWifiRadioStat->numChannels))
1461 {
1462 hddLog(VOS_TRACE_LEVEL_ERROR,
1463 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1464 kfree_skb(vendor_event);
1465 return ;
1466 }
1467
1468 chList = nla_nest_start(vendor_event,
1469 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
1470 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1471 {
1472 struct nlattr *chInfo;
1473
1474 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1475 pWifiRadioStat->channels +
1476 (i * sizeof(tSirWifiChannelStats)));
1477
1478 hddLog(VOS_TRACE_LEVEL_INFO,
1479 " %d) Channel Info"
1480 " width is %u "
1481 " CenterFreq %u "
1482 " CenterFreq0 %u "
1483 " CenterFreq1 %u "
1484 " onTime %u "
1485 " ccaBusyTime %u",
1486 i,
1487 pWifiChannelStats->channel.width,
1488 pWifiChannelStats->channel.centerFreq,
1489 pWifiChannelStats->channel.centerFreq0,
1490 pWifiChannelStats->channel.centerFreq1,
1491 pWifiChannelStats->onTime,
1492 pWifiChannelStats->ccaBusyTime);
1493
1494
1495 chInfo = nla_nest_start(vendor_event, i);
1496
1497 if (nla_put_u32(vendor_event,
1498 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1499 pWifiChannelStats->channel.width) ||
1500 nla_put_u32(vendor_event,
1501 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1502 pWifiChannelStats->channel.centerFreq) ||
1503 nla_put_u32(vendor_event,
1504 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1505 pWifiChannelStats->channel.centerFreq0) ||
1506 nla_put_u32(vendor_event,
1507 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1508 pWifiChannelStats->channel.centerFreq1) ||
1509 nla_put_u32(vendor_event,
1510 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1511 pWifiChannelStats->onTime) ||
1512 nla_put_u32(vendor_event,
1513 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1514 pWifiChannelStats->ccaBusyTime))
1515 {
1516 hddLog(VOS_TRACE_LEVEL_ERROR,
1517 FL("cfg80211_vendor_event_alloc failed") );
1518 kfree_skb(vendor_event);
1519 return ;
1520 }
1521 nla_nest_end(vendor_event, chInfo);
1522 }
1523 nla_nest_end(vendor_event, chList);
1524
1525 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1526 return;
1527}
1528
1529/*
1530 * hdd_link_layer_stats_ind_callback () - This function is called after
1531 * receiving Link Layer indications from FW.This callback converts the firmware
1532 * data to the NL data and send the same to the kernel/upper layers.
1533 */
1534static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1535 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301536 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301537{
Dino Mycled3d50022014-07-07 12:58:25 +05301538 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1539 hdd_adapter_t *pAdapter = NULL;
1540 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301541 int status;
1542
1543 status = wlan_hdd_validate_context(pHddCtx);
1544
1545 if (0 != status)
1546 {
1547 hddLog(VOS_TRACE_LEVEL_ERROR,
1548 FL("HDD context is not valid"));
1549 return;
1550 }
1551
Dino Mycled3d50022014-07-07 12:58:25 +05301552
1553
1554 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1555 if (NULL == pAdapter)
1556 {
1557 hddLog(VOS_TRACE_LEVEL_ERROR,
1558 FL(" MAC address %pM does not exist with host"),
1559 macAddr);
1560 return;
1561 }
1562
Sunil Duttc69bccb2014-05-26 21:30:20 +05301563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301564 "%s: Interface: %s LLStats indType: %d", __func__,
1565 pAdapter->dev->name, indType);
1566
Sunil Duttc69bccb2014-05-26 21:30:20 +05301567 switch (indType)
1568 {
1569 case SIR_HAL_LL_STATS_RESULTS_RSP:
1570 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301571 hddLog(VOS_TRACE_LEVEL_INFO,
1572 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1573 hddLog(VOS_TRACE_LEVEL_INFO,
1574 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1575 linkLayerStatsResults->paramId);
1576 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301577 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1578 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301579 hddLog(VOS_TRACE_LEVEL_INFO,
1580 "LL_STATS RESULTS RESPONSE respId = %u",
1581 linkLayerStatsResults->respId);
1582 hddLog(VOS_TRACE_LEVEL_INFO,
1583 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1584 linkLayerStatsResults->moreResultToFollow);
1585 hddLog(VOS_TRACE_LEVEL_INFO,
1586 "LL_STATS RESULTS RESPONSE result = %p",
1587 linkLayerStatsResults->result);
1588 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1589 {
1590 hdd_link_layer_process_radio_stats(pAdapter,
1591 (v_VOID_t *)linkLayerStatsResults->result);
1592 }
1593 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1594 {
1595 hdd_link_layer_process_iface_stats(pAdapter,
1596 (v_VOID_t *)linkLayerStatsResults->result);
1597 }
1598 else if ( linkLayerStatsResults->paramId &
1599 WMI_LINK_STATS_ALL_PEER )
1600 {
1601 hdd_link_layer_process_peer_stats(pAdapter,
1602 (v_VOID_t *)linkLayerStatsResults->result);
1603 } /* WMI_LINK_STATS_ALL_PEER */
1604 else
1605 {
1606 hddLog(VOS_TRACE_LEVEL_ERROR,
1607 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1608 }
1609
1610 break;
1611 }
1612 default:
1613 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1614 break;
1615 }
1616 return;
1617}
1618
1619const struct
1620nla_policy
1621qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1622{
1623 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1624 { .type = NLA_U32 },
1625 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1626 { .type = NLA_U32 },
1627};
1628
1629static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1630 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05301631 const void *data,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301632 int data_len)
1633{
1634 int status;
1635 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301636 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301637 struct net_device *dev = wdev->netdev;
1638 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1639 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Srinivas Dasari98947432014-11-07 19:41:24 +05301640 hdd_station_ctx_t *pHddStaCtx;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301641
1642 status = wlan_hdd_validate_context(pHddCtx);
1643 if (0 != status)
1644 {
1645 hddLog(VOS_TRACE_LEVEL_ERROR,
1646 FL("HDD context is not valid"));
1647 return -EINVAL;
1648 }
1649
1650 if (NULL == pAdapter)
1651 {
1652 hddLog(VOS_TRACE_LEVEL_ERROR,
1653 FL("HDD adapter is Null"));
1654 return -ENODEV;
1655 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301656 /* check the LLStats Capability */
1657 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1658 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1659 {
1660 hddLog(VOS_TRACE_LEVEL_ERROR,
1661 FL("Link Layer Statistics not supported by Firmware"));
1662 return -EINVAL;
1663 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301664
1665 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1666 (struct nlattr *)data,
1667 data_len, qca_wlan_vendor_ll_set_policy))
1668 {
1669 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1670 return -EINVAL;
1671 }
1672 if (!tb_vendor
1673 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1674 {
1675 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1676 return -EINVAL;
1677 }
1678 if (!tb_vendor[
1679 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1680 {
1681 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1682 return -EINVAL;
1683 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301684 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301685 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301686
Dino Mycledf0a5d92014-07-04 09:41:55 +05301687 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301688 nla_get_u32(
1689 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1690
Dino Mycledf0a5d92014-07-04 09:41:55 +05301691 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301692 nla_get_u32(
1693 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1694
Dino Mycled3d50022014-07-07 12:58:25 +05301695 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1696 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301697
1698
1699 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301700 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301701 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301702 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301703 hddLog(VOS_TRACE_LEVEL_INFO,
1704 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301705 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301706 hddLog(VOS_TRACE_LEVEL_INFO,
1707 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301708 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301709
1710 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1711 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301712 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301713 {
1714 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1715 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301716 return -EINVAL;
1717
1718 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301719
1720 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1721 if (VOS_STATUS_SUCCESS !=
1722 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1723 pHddStaCtx->conn_info.staId[0], WIFI_STATS_IFACE))
1724 {
1725 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1726 "WLANTL_ClearInterfaceStats Failed", __func__);
1727 return -EINVAL;
1728 }
1729
1730 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
1731 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
1732 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
1733 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
1734
Sunil Duttc69bccb2014-05-26 21:30:20 +05301735 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301736 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301737 {
1738 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1739 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301740 return -EINVAL;
1741 }
1742
1743 pAdapter->isLinkLayerStatsSet = 1;
1744
1745 return 0;
1746}
1747
1748const struct
1749nla_policy
1750qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1751{
1752 /* Unsigned 32bit value provided by the caller issuing the GET stats
1753 * command. When reporting
1754 * the stats results, the driver uses the same value to indicate
1755 * which GET request the results
1756 * correspond to.
1757 */
1758 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1759
1760 /* Unsigned 32bit value . bit mask to identify what statistics are
1761 requested for retrieval */
1762 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1763};
1764
1765static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1766 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05301767 const void *data,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301768 int data_len)
1769{
1770 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1771 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301772 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301773 struct net_device *dev = wdev->netdev;
1774 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1775 int status;
1776
1777 status = wlan_hdd_validate_context(pHddCtx);
1778 if (0 != status)
1779 {
1780 hddLog(VOS_TRACE_LEVEL_ERROR,
1781 FL("HDD context is not valid"));
1782 return -EINVAL ;
1783 }
1784
1785 if (NULL == pAdapter)
1786 {
1787 hddLog(VOS_TRACE_LEVEL_FATAL,
1788 "%s: HDD adapter is Null", __func__);
1789 return -ENODEV;
1790 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301791 /* check the LLStats Capability */
1792 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1793 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1794 {
1795 hddLog(VOS_TRACE_LEVEL_ERROR,
1796 FL("Link Layer Statistics not supported by Firmware"));
1797 return -EINVAL;
1798 }
1799
Sunil Duttc69bccb2014-05-26 21:30:20 +05301800
1801 if (!pAdapter->isLinkLayerStatsSet)
1802 {
1803 hddLog(VOS_TRACE_LEVEL_FATAL,
1804 "%s: isLinkLayerStatsSet : %d",
1805 __func__, pAdapter->isLinkLayerStatsSet);
1806 return -EINVAL;
1807 }
1808
1809 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1810 (struct nlattr *)data,
1811 data_len, qca_wlan_vendor_ll_get_policy))
1812 {
1813 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1814 return -EINVAL;
1815 }
1816
1817 if (!tb_vendor
1818 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1819 {
1820 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1821 return -EINVAL;
1822 }
1823
1824 if (!tb_vendor
1825 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1826 {
1827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1828 return -EINVAL;
1829 }
1830
Sunil Duttc69bccb2014-05-26 21:30:20 +05301831
Dino Mycledf0a5d92014-07-04 09:41:55 +05301832 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301833 nla_get_u32( tb_vendor[
1834 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301835 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301836 nla_get_u32( tb_vendor[
1837 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1838
Dino Mycled3d50022014-07-07 12:58:25 +05301839 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1840 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301841
1842 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301843 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301844 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301845 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301846 hddLog(VOS_TRACE_LEVEL_INFO,
1847 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301848 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301849
1850 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301851 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301852 {
1853 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1854 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301855 return -EINVAL;
1856 }
1857 return 0;
1858}
1859
1860const struct
1861nla_policy
1862qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1863{
1864 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1865 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1866 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1867 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1868};
1869
1870static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1871 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05301872 const void *data,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301873 int data_len)
1874{
1875 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1876 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301877 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301878 struct net_device *dev = wdev->netdev;
1879 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1880 u32 statsClearReqMask;
1881 u8 stopReq;
1882 int status;
1883
1884 status = wlan_hdd_validate_context(pHddCtx);
1885 if (0 != status)
1886 {
1887 hddLog(VOS_TRACE_LEVEL_ERROR,
1888 FL("HDD context is not valid"));
1889 return -EINVAL;
1890 }
1891
1892 if (NULL == pAdapter)
1893 {
1894 hddLog(VOS_TRACE_LEVEL_FATAL,
1895 "%s: HDD adapter is Null", __func__);
1896 return -ENODEV;
1897 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301898 /* check the LLStats Capability */
1899 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1900 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1901 {
1902 hddLog(VOS_TRACE_LEVEL_ERROR,
1903 FL("Enable LLStats Capability"));
1904 return -EINVAL;
1905 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301906
1907 if (!pAdapter->isLinkLayerStatsSet)
1908 {
1909 hddLog(VOS_TRACE_LEVEL_FATAL,
1910 "%s: isLinkLayerStatsSet : %d",
1911 __func__, pAdapter->isLinkLayerStatsSet);
1912 return -EINVAL;
1913 }
1914
1915 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1916 (struct nlattr *)data,
1917 data_len, qca_wlan_vendor_ll_clr_policy))
1918 {
1919 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1920 return -EINVAL;
1921 }
1922
1923 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
1924
1925 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
1926 {
1927 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
1928 return -EINVAL;
1929
1930 }
1931
Sunil Duttc69bccb2014-05-26 21:30:20 +05301932
Dino Mycledf0a5d92014-07-04 09:41:55 +05301933 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301934 nla_get_u32(
1935 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
1936
Dino Mycledf0a5d92014-07-04 09:41:55 +05301937 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301938 nla_get_u8(
1939 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
1940
1941 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301942 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301943
Dino Mycled3d50022014-07-07 12:58:25 +05301944 vos_mem_copy(linkLayerStatsClearReq.macAddr,
1945 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301946
1947 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301948 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301949 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301950 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301951 hddLog(VOS_TRACE_LEVEL_INFO,
1952 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301953 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301954 hddLog(VOS_TRACE_LEVEL_INFO,
1955 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301956 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301957
1958 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301959 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301960 {
1961 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05301962 hdd_station_ctx_t *pHddStaCtx;
1963
1964 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1965 if (VOS_STATUS_SUCCESS !=
1966 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1967 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
1968 {
1969 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1970 "WLANTL_ClearInterfaceStats Failed", __func__);
1971 return -EINVAL;
1972 }
1973 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
1974 (statsClearReqMask & WIFI_STATS_IFACE)) {
1975 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
1976 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
1977 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
1978 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
1979 }
1980
Sunil Duttc69bccb2014-05-26 21:30:20 +05301981 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
1982 2 * sizeof(u32) +
1983 NLMSG_HDRLEN);
1984
1985 if (temp_skbuff != NULL)
1986 {
1987
1988 if (nla_put_u32(temp_skbuff,
1989 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
1990 statsClearReqMask) ||
1991 nla_put_u32(temp_skbuff,
1992 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
1993 stopReq))
1994 {
1995 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
1996 kfree_skb(temp_skbuff);
1997 return -EINVAL;
1998 }
1999 /* If the ask is to stop the stats collection as part of clear
2000 * (stopReq = 1) , ensure that no further requests of get
2001 * go to the firmware by having isLinkLayerStatsSet set to 0.
2002 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302003 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302004 * case the firmware is just asked to clear the statistics.
2005 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302006 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302007 pAdapter->isLinkLayerStatsSet = 0;
2008 return cfg80211_vendor_cmd_reply(temp_skbuff);
2009 }
2010 return -ENOMEM;
2011 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302012 return -EINVAL;
2013}
2014#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2015
Dino Mycle6fb96c12014-06-10 11:52:40 +05302016#ifdef WLAN_FEATURE_EXTSCAN
2017static const struct nla_policy
2018wlan_hdd_extscan_config_policy
2019 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2020{
2021 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2022 { .type = NLA_U32 },
2023 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2024 { .type = NLA_U32 },
2025 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2026 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2027 { .type = NLA_U32 },
2028 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2029 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2030
2031 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2032 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2033 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2034 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2035 { .type = NLA_U8 },
2036 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2037 { .type = NLA_U32 },
2038 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2039 { .type = NLA_U32 },
2040 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2041 { .type = NLA_U32 },
2042 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
2043 { .type = NLA_U8 },
2044 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2045 { .type = NLA_U8 },
2046 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2047 { .type = NLA_U8 },
2048
2049 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2050 { .type = NLA_U32 },
2051 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2052 { .type = NLA_UNSPEC },
2053 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2054 { .type = NLA_S32 },
2055 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2056 { .type = NLA_S32 },
2057 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2058 { .type = NLA_U32 },
2059 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2060 { .type = NLA_U32 },
2061 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2062 { .type = NLA_U32 },
2063 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2064 = { .type = NLA_U32 },
2065 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2066 { .type = NLA_U32 },
2067 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2068 NLA_U32 },
2069};
2070
2071static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
2072{
2073 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2074 struct sk_buff *skb = NULL;
2075 tpSirEXTScanCapabilitiesEvent pData =
2076 (tpSirEXTScanCapabilitiesEvent) pMsg;
2077
2078 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2079 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2080 "or pData(%p) is null"), pData);
2081 return;
2082 }
2083
2084 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2085 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2086 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
2087 GFP_KERNEL);
2088
2089 if (!skb) {
2090 hddLog(VOS_TRACE_LEVEL_ERROR,
2091 FL("cfg80211_vendor_event_alloc failed"));
2092 return;
2093 }
2094
2095 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2096 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
2097 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
2098 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
2099 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
2100 pData->maxRssiSampleSize);
2101 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
2102 pData->maxScanReportingThreshold);
2103 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
2104 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
2105 pData->maxSignificantWifiChangeAPs);
2106 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
2107 pData->maxBsidHistoryEntries);
2108
2109 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2110 pData->requestId) ||
2111 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
2112 nla_put_u32(skb,
2113 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
2114 pData->scanCacheSize) ||
2115 nla_put_u32(skb,
2116 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
2117 pData->scanBuckets) ||
2118 nla_put_u32(skb,
2119 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
2120 pData->maxApPerScan) ||
2121 nla_put_u32(skb,
2122 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
2123 pData->maxRssiSampleSize) ||
2124 nla_put_u32(skb,
2125 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
2126 pData->maxScanReportingThreshold) ||
2127 nla_put_u32(skb,
2128 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
2129 pData->maxHotlistAPs) ||
2130 nla_put_u32(skb,
2131 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
2132 pData->maxSignificantWifiChangeAPs) ||
2133 nla_put_u32(skb,
2134 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2135 pData->maxBsidHistoryEntries)) {
2136 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2137 goto nla_put_failure;
2138 }
2139
2140 cfg80211_vendor_event(skb, GFP_KERNEL);
2141 return;
2142
2143nla_put_failure:
2144 kfree_skb(skb);
2145 return;
2146}
2147
2148
2149static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2150{
2151 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2152 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2153 struct sk_buff *skb = NULL;
2154 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2155
2156
2157 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2158 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2159 "or pData(%p) is null"), pData);
2160 return;
2161 }
2162
2163 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2164 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2165 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2166 GFP_KERNEL);
2167
2168 if (!skb) {
2169 hddLog(VOS_TRACE_LEVEL_ERROR,
2170 FL("cfg80211_vendor_event_alloc failed"));
2171 return;
2172 }
2173 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2174 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2175 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2176
2177 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2178 pData->requestId) ||
2179 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2180 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2181 goto nla_put_failure;
2182 }
2183
2184 /*
2185 * Store the Request ID for comparing with the requestID obtained
2186 * in other requests.HDD shall return a failure is the extscan_stop
2187 * request is issued with a different requestId as that of the
2188 * extscan_start request. Also, This requestId shall be used while
2189 * indicating the full scan results to the upper layers.
2190 * The requestId is stored with the assumption that the firmware
2191 * shall return the ext scan start request's requestId in ext scan
2192 * start response.
2193 */
2194 if (pData->status == 0)
2195 pMac->sme.extScanStartReqId = pData->requestId;
2196
2197
2198 cfg80211_vendor_event(skb, GFP_KERNEL);
2199 return;
2200
2201nla_put_failure:
2202 kfree_skb(skb);
2203 return;
2204}
2205
2206
2207static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2208{
2209 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2210 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2211 struct sk_buff *skb = NULL;
2212
2213 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2214 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2215 "or pData(%p) is null"), pData);
2216 return;
2217 }
2218
2219 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2220 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2221 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2222 GFP_KERNEL);
2223
2224 if (!skb) {
2225 hddLog(VOS_TRACE_LEVEL_ERROR,
2226 FL("cfg80211_vendor_event_alloc failed"));
2227 return;
2228 }
2229 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2230 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2231
2232 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2233 pData->requestId) ||
2234 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2235 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2236 goto nla_put_failure;
2237 }
2238
2239 cfg80211_vendor_event(skb, GFP_KERNEL);
2240 return;
2241
2242nla_put_failure:
2243 kfree_skb(skb);
2244 return;
2245}
2246
2247
2248static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2249 void *pMsg)
2250{
2251 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2252 struct sk_buff *skb = NULL;
2253 tpSirEXTScanSetBssidHotListRspParams pData =
2254 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2255
2256 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2257 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2258 "or pData(%p) is null"), pData);
2259 return;
2260 }
2261 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2262 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2263 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2264 GFP_KERNEL);
2265
2266 if (!skb) {
2267 hddLog(VOS_TRACE_LEVEL_ERROR,
2268 FL("cfg80211_vendor_event_alloc failed"));
2269 return;
2270 }
2271 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2272 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2273 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2274
2275 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2276 pData->requestId) ||
2277 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2278 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2279 goto nla_put_failure;
2280 }
2281
2282 cfg80211_vendor_event(skb, GFP_KERNEL);
2283 return;
2284
2285nla_put_failure:
2286 kfree_skb(skb);
2287 return;
2288}
2289
2290static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2291 void *pMsg)
2292{
2293 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2294 struct sk_buff *skb = NULL;
2295 tpSirEXTScanResetBssidHotlistRspParams pData =
2296 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2297
2298 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2299 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2300 "or pData(%p) is null"), pData);
2301 return;
2302 }
2303
2304 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2305 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2306 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2307 GFP_KERNEL);
2308
2309 if (!skb) {
2310 hddLog(VOS_TRACE_LEVEL_ERROR,
2311 FL("cfg80211_vendor_event_alloc failed"));
2312 return;
2313 }
2314 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2315 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2316
2317 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2318 pData->requestId) ||
2319 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2320 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2321 goto nla_put_failure;
2322 }
2323
2324 cfg80211_vendor_event(skb, GFP_KERNEL);
2325 return;
2326
2327nla_put_failure:
2328 kfree_skb(skb);
2329 return;
2330}
2331
2332
2333static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2334 void *pMsg)
2335{
2336 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2337 struct sk_buff *skb = NULL;
2338 tpSirEXTScanSetSignificantChangeRspParams pData =
2339 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2340
2341 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2342 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2343 "or pData(%p) is null"), pData);
2344 return;
2345 }
2346
2347 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2348 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2349 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2350 GFP_KERNEL);
2351
2352 if (!skb) {
2353 hddLog(VOS_TRACE_LEVEL_ERROR,
2354 FL("cfg80211_vendor_event_alloc failed"));
2355 return;
2356 }
2357 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2358 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2359 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2360
2361 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2362 pData->requestId) ||
2363 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2364 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2365 goto nla_put_failure;
2366 }
2367
2368 cfg80211_vendor_event(skb, GFP_KERNEL);
2369 return;
2370
2371nla_put_failure:
2372 kfree_skb(skb);
2373 return;
2374}
2375
2376
2377static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2378 void *pMsg)
2379{
2380 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2381 struct sk_buff *skb = NULL;
2382 tpSirEXTScanResetSignificantChangeRspParams pData =
2383 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2384
2385 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2386 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2387 "or pData(%p) is null"), pData);
2388 return;
2389 }
2390
2391 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2392 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2393 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2394 GFP_KERNEL);
2395
2396 if (!skb) {
2397 hddLog(VOS_TRACE_LEVEL_ERROR,
2398 FL("cfg80211_vendor_event_alloc failed"));
2399 return;
2400 }
2401 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2402 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2403 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2404
2405 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2406 pData->requestId) ||
2407 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2408 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2409 goto nla_put_failure;
2410 }
2411
2412 cfg80211_vendor_event(skb, GFP_KERNEL);
2413 return;
2414
2415nla_put_failure:
2416 kfree_skb(skb);
2417 return;
2418}
2419
2420static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2421 void *pMsg)
2422{
2423 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2424 struct sk_buff *skb = NULL;
2425 tANI_U32 i = 0, j, resultsPerEvent;
2426 tANI_S32 totalResults;
2427 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2428 tpSirWifiScanResult pSirWifiScanResult;
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 totalResults = pData->numOfAps;
2436 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2437 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2438 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2439
2440 do{
2441 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2442 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2443 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2444
2445 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2446 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2447 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2448 GFP_KERNEL);
2449
2450 if (!skb) {
2451 hddLog(VOS_TRACE_LEVEL_ERROR,
2452 FL("cfg80211_vendor_event_alloc failed"));
2453 return;
2454 }
2455
2456 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2457
2458 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2459 pData->requestId) ||
2460 nla_put_u32(skb,
2461 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2462 resultsPerEvent)) {
2463 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2464 goto fail;
2465 }
2466 if (nla_put_u8(skb,
2467 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2468 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2469 {
2470 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2471 goto fail;
2472 }
2473
2474 if (resultsPerEvent) {
2475 struct nlattr *aps;
2476
2477 aps = nla_nest_start(skb,
2478 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2479 if (!aps)
2480 {
2481 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2482 goto fail;
2483 }
2484
2485 for (j = 0; j < resultsPerEvent; j++, i++) {
2486 struct nlattr *ap;
2487 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2488 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2489
2490 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2491 "Ssid (%s)"
2492 "Bssid: %pM "
2493 "Channel (%u)"
2494 "Rssi (%d)"
2495 "RTT (%u)"
2496 "RTT_SD (%u)",
2497 i,
2498 pSirWifiScanResult->ts,
2499 pSirWifiScanResult->ssid,
2500 pSirWifiScanResult->bssid,
2501 pSirWifiScanResult->channel,
2502 pSirWifiScanResult->rssi,
2503 pSirWifiScanResult->rtt,
2504 pSirWifiScanResult->rtt_sd);
2505
2506 ap = nla_nest_start(skb, j + 1);
2507 if (!ap)
2508 {
2509 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2510 goto fail;
2511 }
2512
2513 if (nla_put_u64(skb,
2514 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2515 pSirWifiScanResult->ts) )
2516 {
2517 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2518 goto fail;
2519 }
2520 if (nla_put(skb,
2521 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2522 sizeof(pSirWifiScanResult->ssid),
2523 pSirWifiScanResult->ssid) )
2524 {
2525 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2526 goto fail;
2527 }
2528 if (nla_put(skb,
2529 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2530 sizeof(pSirWifiScanResult->bssid),
2531 pSirWifiScanResult->bssid) )
2532 {
2533 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2534 goto fail;
2535 }
2536 if (nla_put_u32(skb,
2537 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2538 pSirWifiScanResult->channel) )
2539 {
2540 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2541 goto fail;
2542 }
Dasari Srinivas90747d72014-10-08 12:16:15 +05302543 if (nla_put_s32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302544 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2545 pSirWifiScanResult->rssi) )
2546 {
2547 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2548 goto fail;
2549 }
2550 if (nla_put_u32(skb,
2551 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2552 pSirWifiScanResult->rtt) )
2553 {
2554 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2555 goto fail;
2556 }
2557 if (nla_put_u32(skb,
2558 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2559 pSirWifiScanResult->rtt_sd))
2560 {
2561 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2562 goto fail;
2563 }
2564
2565 nla_nest_end(skb, ap);
2566 }
2567 nla_nest_end(skb, aps);
2568
2569 }
2570 cfg80211_vendor_event(skb, GFP_KERNEL);
2571 } while (totalResults > 0);
2572
2573 return;
2574fail:
2575 kfree_skb(skb);
2576 return;
2577}
2578
2579static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2580 void *pMsg)
2581{
2582 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2583 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2584 struct sk_buff *skb = NULL;
2585 tANI_U32 i;
2586
2587 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2588 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2589 "or pData(%p) is null"), pData);
2590 return;
2591 }
2592
2593 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2594 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2595 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2596 GFP_KERNEL);
2597
2598 if (!skb) {
2599 hddLog(VOS_TRACE_LEVEL_ERROR,
2600 FL("cfg80211_vendor_event_alloc failed"));
2601 return;
2602 }
2603 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2604 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2605 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2606 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2607
2608 for (i = 0; i < pData->numOfAps; i++) {
2609 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2610 "Ssid (%s) "
2611 "Bssid (" MAC_ADDRESS_STR ") "
2612 "Channel (%u) "
2613 "Rssi (%d) "
2614 "RTT (%u) "
2615 "RTT_SD (%u) ",
2616 i,
2617 pData->ap[i].ts,
2618 pData->ap[i].ssid,
2619 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2620 pData->ap[i].channel,
2621 pData->ap[i].rssi,
2622 pData->ap[i].rtt,
2623 pData->ap[i].rtt_sd);
2624 }
2625
2626 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2627 pData->requestId) ||
2628 nla_put_u32(skb,
2629 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2630 pData->numOfAps)) {
2631 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2632 goto fail;
2633 }
2634 if (pData->numOfAps) {
2635 struct nlattr *aps;
2636
2637 aps = nla_nest_start(skb,
2638 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2639 if (!aps)
2640 goto fail;
2641
2642 for (i = 0; i < pData->numOfAps; i++) {
2643 struct nlattr *ap;
2644
2645 ap = nla_nest_start(skb, i + 1);
2646 if (!ap)
2647 goto fail;
2648
2649 if (nla_put_u64(skb,
2650 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2651 pData->ap[i].ts) ||
2652 nla_put(skb,
2653 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2654 sizeof(pData->ap[i].ssid),
2655 pData->ap[i].ssid) ||
2656 nla_put(skb,
2657 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2658 sizeof(pData->ap[i].bssid),
2659 pData->ap[i].bssid) ||
2660 nla_put_u32(skb,
2661 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2662 pData->ap[i].channel) ||
2663 nla_put_s32(skb,
2664 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2665 pData->ap[i].rssi) ||
2666 nla_put_u32(skb,
2667 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2668 pData->ap[i].rtt) ||
2669 nla_put_u32(skb,
2670 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2671 pData->ap[i].rtt_sd))
2672 goto fail;
2673
2674 nla_nest_end(skb, ap);
2675 }
2676 nla_nest_end(skb, aps);
2677
2678 if (nla_put_u8(skb,
2679 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2680 pData->moreData))
2681 goto fail;
2682 }
2683
2684 cfg80211_vendor_event(skb, GFP_KERNEL);
2685 return;
2686
2687fail:
2688 kfree_skb(skb);
2689 return;
2690
2691}
2692static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2693 void *pMsg)
2694{
2695 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2696 struct sk_buff *skb = NULL;
2697 tANI_U32 i, j;
2698 tpSirWifiSignificantChangeEvent pData =
2699 (tpSirWifiSignificantChangeEvent) pMsg;
2700
2701 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2702 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2703 "or pData(%p) is null"), pData);
2704 return;
2705 }
2706 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2707 EXTSCAN_EVENT_BUF_SIZE,
2708 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2709 GFP_KERNEL);
2710
2711 if (!skb) {
2712 hddLog(VOS_TRACE_LEVEL_ERROR,
2713 FL("cfg80211_vendor_event_alloc failed"));
2714 return;
2715 }
2716 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2717 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2718 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2719 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2720 pData->numSigRssiBss);
2721 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2722
2723 for (i = 0; i < pData->numSigRssiBss; i++) {
2724 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2725 " num RSSI %u ",
2726 i, pData->sigRssiResult[i].bssid,
2727 pData->sigRssiResult[i].channel,
2728 pData->sigRssiResult[i].numRssi);
2729
2730 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2731
2732 hddLog(VOS_TRACE_LEVEL_INFO,
2733 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05302734 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302735
2736 }
2737 }
2738
2739
2740 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2741 pData->requestId) ||
2742 nla_put_u32(skb,
2743 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2744 pData->numSigRssiBss)) {
2745 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2746 goto fail;
2747 }
2748
2749 if (pData->numSigRssiBss) {
2750 struct nlattr *aps;
2751 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2752 if (!aps)
2753 goto fail;
2754 for (i = 0; i < pData->numSigRssiBss; i++) {
2755 struct nlattr *ap;
2756
2757 ap = nla_nest_start(skb, i);
2758 if (!ap)
2759 goto fail;
2760 if (nla_put(skb,
2761 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2762 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2763 nla_put_u32(skb,
2764 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2765 pData->sigRssiResult[i].channel) ||
2766 nla_put_u32(skb,
2767 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2768 pData->sigRssiResult[i].numRssi) ||
2769 nla_put(skb,
2770 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2771 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2772 pData->sigRssiResult[i].rssi))
2773 goto fail;
2774 nla_nest_end(skb, ap);
2775 }
2776 nla_nest_end(skb, aps);
2777 if (nla_put_u8(skb,
2778 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2779 pData->moreData))
2780 goto fail;
2781 }
2782 cfg80211_vendor_event(skb, GFP_KERNEL);
2783 return;
2784fail:
2785 kfree_skb(skb);
2786 return;
2787}
2788
2789static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2790 void *pMsg)
2791{
2792 struct sk_buff *skb;
2793 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2794 tpSirWifiFullScanResultEvent pData =
2795 (tpSirWifiFullScanResultEvent) (pMsg);
2796
2797 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2798 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2799 "or pData(%p) is null"), pData);
2800 return;
2801 }
2802
2803 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2804 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2805 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2806 GFP_KERNEL);
2807
2808 if (!skb) {
2809 hddLog(VOS_TRACE_LEVEL_ERROR,
2810 FL("cfg80211_vendor_event_alloc failed"));
2811 return;
2812 }
2813
2814 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2815 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2816 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2817 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2818 "Ssid (%s)"
2819 "Bssid (" MAC_ADDRESS_STR ")"
2820 "Channel (%u)"
2821 "Rssi (%d)"
2822 "RTT (%u)"
2823 "RTT_SD (%u)"),
2824 pData->ap.ts,
2825 pData->ap.ssid,
2826 MAC_ADDR_ARRAY(pData->ap.bssid),
2827 pData->ap.channel,
2828 pData->ap.rssi,
2829 pData->ap.rtt,
2830 pData->ap.rtt_sd);
2831 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2832 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2833 pData->requestId) ||
2834 nla_put_u64(skb,
2835 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2836 pData->ap.ts) ||
2837 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2838 sizeof(pData->ap.ssid),
2839 pData->ap.ssid) ||
2840 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2841 WNI_CFG_BSSID_LEN,
2842 pData->ap.bssid) ||
2843 nla_put_u32(skb,
2844 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2845 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05302846 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302847 pData->ap.rssi) ||
2848 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2849 pData->ap.rtt) ||
2850 nla_put_u32(skb,
2851 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2852 pData->ap.rtt_sd) ||
2853 nla_put_u16(skb,
2854 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2855 pData->ap.beaconPeriod) ||
2856 nla_put_u16(skb,
2857 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2858 pData->ap.capability) ||
2859 nla_put_u32(skb,
2860 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2861 pData->ieLength))
2862 {
2863 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2864 goto nla_put_failure;
2865 }
2866 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2867 pData->ieLength,
2868 pData->ie))
2869 {
2870 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2871 goto nla_put_failure;
2872 }
2873
2874 cfg80211_vendor_event(skb, GFP_KERNEL);
2875 return;
2876
2877nla_put_failure:
2878 kfree_skb(skb);
2879 return;
2880}
2881
2882static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
2883 void *pMsg)
2884{
2885 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2886 struct sk_buff *skb = NULL;
2887 tpSirEXTScanResultsAvailableIndParams pData =
2888 (tpSirEXTScanResultsAvailableIndParams) pMsg;
2889
2890 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2891 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2892 "or pData(%p) is null"), pData);
2893 return;
2894 }
2895
2896 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2897 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2898 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
2899 GFP_KERNEL);
2900
2901 if (!skb) {
2902 hddLog(VOS_TRACE_LEVEL_ERROR,
2903 FL("cfg80211_vendor_event_alloc failed"));
2904 return;
2905 }
2906
2907 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2908 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2909 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
2910 pData->numResultsAvailable);
2911 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2912 pData->requestId) ||
2913 nla_put_u32(skb,
2914 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2915 pData->numResultsAvailable)) {
2916 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2917 goto nla_put_failure;
2918 }
2919
2920 cfg80211_vendor_event(skb, GFP_KERNEL);
2921 return;
2922
2923nla_put_failure:
2924 kfree_skb(skb);
2925 return;
2926}
2927
2928static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
2929{
2930 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2931 struct sk_buff *skb = NULL;
2932 tpSirEXTScanProgressIndParams pData =
2933 (tpSirEXTScanProgressIndParams) pMsg;
2934
2935 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2936 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2937 "or pData(%p) is null"), pData);
2938 return;
2939 }
2940
2941 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2942 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2943 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
2944 GFP_KERNEL);
2945
2946 if (!skb) {
2947 hddLog(VOS_TRACE_LEVEL_ERROR,
2948 FL("cfg80211_vendor_event_alloc failed"));
2949 return;
2950 }
2951 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2952 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
2953 pData->extScanEventType);
2954 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
2955 pData->status);
2956
2957 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
2958 pData->extScanEventType) ||
2959 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05302960 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2961 pData->requestId) ||
2962 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302963 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
2964 pData->status)) {
2965 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2966 goto nla_put_failure;
2967 }
2968
2969 cfg80211_vendor_event(skb, GFP_KERNEL);
2970 return;
2971
2972nla_put_failure:
2973 kfree_skb(skb);
2974 return;
2975}
2976
2977void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
2978 void *pMsg)
2979{
2980 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2981
2982 if (wlan_hdd_validate_context(pHddCtx)) {
Dasari Srinivasb46ed1d2014-10-08 13:03:08 +05302983 hddLog(VOS_TRACE_LEVEL_INFO, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302984 return;
2985 }
2986
2987 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
2988
2989
2990 switch(evType) {
2991 case SIR_HAL_EXTSCAN_START_RSP:
2992 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
2993 break;
2994
2995 case SIR_HAL_EXTSCAN_STOP_RSP:
2996 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
2997 break;
2998 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
2999 /* There is no need to send this response to upper layer
3000 Just log the message */
3001 hddLog(VOS_TRACE_LEVEL_INFO,
3002 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3003 break;
3004 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3005 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3006 break;
3007
3008 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3009 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3010 break;
3011
3012 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
3013 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
3014 break;
3015
3016 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
3017 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
3018 break;
3019 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
3020 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
3021 break;
3022 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3023 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3024 break;
3025 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3026 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3027 break;
3028 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3029 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3030 break;
3031 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3032 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3033 break;
3034 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
3035 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
3036 break;
3037 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3038 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3039 break;
3040 default:
3041 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3042 break;
3043 }
3044}
3045
3046static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3047 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303048 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303049{
Dino Myclee8843b32014-07-04 14:21:45 +05303050 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303051 struct net_device *dev = wdev->netdev;
3052 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3053 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3054 struct nlattr
3055 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3056 eHalStatus status;
3057
3058 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3059 status = wlan_hdd_validate_context(pHddCtx);
3060 if (0 != status)
3061 {
3062 hddLog(VOS_TRACE_LEVEL_ERROR,
3063 FL("HDD context is not valid"));
3064 return -EINVAL;
3065 }
Dino Myclee8843b32014-07-04 14:21:45 +05303066 /* check the EXTScan Capability */
3067 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3068 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3069 {
3070 hddLog(VOS_TRACE_LEVEL_ERROR,
3071 FL("EXTScan not enabled/supported by Firmware"));
3072 return -EINVAL;
3073 }
3074
Dino Mycle6fb96c12014-06-10 11:52:40 +05303075 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3076 data, dataLen,
3077 wlan_hdd_extscan_config_policy)) {
3078 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3079 return -EINVAL;
3080 }
3081
3082 /* Parse and fetch request Id */
3083 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3084 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3085 return -EINVAL;
3086 }
3087
Dino Mycle6fb96c12014-06-10 11:52:40 +05303088
Dino Myclee8843b32014-07-04 14:21:45 +05303089 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303090 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303091 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303092
Dino Myclee8843b32014-07-04 14:21:45 +05303093 reqMsg.sessionId = pAdapter->sessionId;
3094 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303095
Dino Myclee8843b32014-07-04 14:21:45 +05303096 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303097 if (!HAL_STATUS_SUCCESS(status)) {
3098 hddLog(VOS_TRACE_LEVEL_ERROR,
3099 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303100 return -EINVAL;
3101 }
3102
3103 return 0;
3104}
3105
3106
3107static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3108 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303109 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303110{
Dino Myclee8843b32014-07-04 14:21:45 +05303111 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303112 struct net_device *dev = wdev->netdev;
3113 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3114 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3115 struct nlattr
3116 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3117 eHalStatus status;
3118
3119 status = wlan_hdd_validate_context(pHddCtx);
3120 if (0 != status)
3121 {
3122 hddLog(VOS_TRACE_LEVEL_ERROR,
3123 FL("HDD context is not valid"));
3124 return -EINVAL;
3125 }
Dino Myclee8843b32014-07-04 14:21:45 +05303126 /* check the EXTScan Capability */
3127 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3128 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3129 {
3130 hddLog(VOS_TRACE_LEVEL_ERROR,
3131 FL("EXTScan not enabled/supported by Firmware"));
3132 return -EINVAL;
3133 }
3134
Dino Mycle6fb96c12014-06-10 11:52:40 +05303135 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3136 data, dataLen,
3137 wlan_hdd_extscan_config_policy)) {
3138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3139 return -EINVAL;
3140 }
3141 /* Parse and fetch request Id */
3142 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3143 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3144 return -EINVAL;
3145 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303146
Dino Myclee8843b32014-07-04 14:21:45 +05303147 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303148 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3149
Dino Myclee8843b32014-07-04 14:21:45 +05303150 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303151
Dino Myclee8843b32014-07-04 14:21:45 +05303152 reqMsg.sessionId = pAdapter->sessionId;
3153 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303154
3155 /* Parse and fetch flush parameter */
3156 if (!tb
3157 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3158 {
3159 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3160 goto failed;
3161 }
Dino Myclee8843b32014-07-04 14:21:45 +05303162 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303163 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3164
Dino Myclee8843b32014-07-04 14:21:45 +05303165 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303166
Dino Myclee8843b32014-07-04 14:21:45 +05303167 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303168 if (!HAL_STATUS_SUCCESS(status)) {
3169 hddLog(VOS_TRACE_LEVEL_ERROR,
3170 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303171 return -EINVAL;
3172 }
3173 return 0;
3174
3175failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303176 return -EINVAL;
3177}
3178
3179static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3180 struct wireless_dev *wdev,
3181 void *data, int dataLen)
3182{
3183 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3184 struct net_device *dev = wdev->netdev;
3185 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3186 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3187 struct nlattr
3188 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3189 struct nlattr
3190 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3191 struct nlattr *apTh;
3192 eHalStatus status;
3193 tANI_U8 i = 0;
3194 int rem;
3195
3196 status = wlan_hdd_validate_context(pHddCtx);
3197 if (0 != status)
3198 {
3199 hddLog(VOS_TRACE_LEVEL_ERROR,
3200 FL("HDD context is not valid"));
3201 return -EINVAL;
3202 }
Dino Myclee8843b32014-07-04 14:21:45 +05303203 /* check the EXTScan Capability */
3204 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3205 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3206 {
3207 hddLog(VOS_TRACE_LEVEL_ERROR,
3208 FL("EXTScan not enabled/supported by Firmware"));
3209 return -EINVAL;
3210 }
3211
Dino Mycle6fb96c12014-06-10 11:52:40 +05303212 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3213 data, dataLen,
3214 wlan_hdd_extscan_config_policy)) {
3215 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3216 return -EINVAL;
3217 }
3218
3219 /* Parse and fetch request Id */
3220 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3221 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3222 return -EINVAL;
3223 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303224 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3225 vos_mem_malloc(sizeof(*pReqMsg));
3226 if (!pReqMsg) {
3227 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3228 return -ENOMEM;
3229 }
3230
Dino Myclee8843b32014-07-04 14:21:45 +05303231
Dino Mycle6fb96c12014-06-10 11:52:40 +05303232 pReqMsg->requestId = nla_get_u32(
3233 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3234 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3235
3236 /* Parse and fetch number of APs */
3237 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3238 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3239 goto fail;
3240 }
3241
3242 pReqMsg->sessionId = pAdapter->sessionId;
3243 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3244
3245 pReqMsg->numAp = nla_get_u32(
3246 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3247 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3248
3249 nla_for_each_nested(apTh,
3250 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3251 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3252 nla_data(apTh), nla_len(apTh),
3253 NULL)) {
3254 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3255 goto fail;
3256 }
3257
3258 /* Parse and fetch MAC address */
3259 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3260 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3261 goto fail;
3262 }
3263 memcpy(pReqMsg->ap[i].bssid, nla_data(
3264 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3265 sizeof(tSirMacAddr));
3266 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3267
3268 /* Parse and fetch low RSSI */
3269 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3271 goto fail;
3272 }
3273 pReqMsg->ap[i].low = nla_get_s32(
3274 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3275 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3276
3277 /* Parse and fetch high RSSI */
3278 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3279 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3280 goto fail;
3281 }
3282 pReqMsg->ap[i].high = nla_get_s32(
3283 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3284 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3285 pReqMsg->ap[i].high);
3286
3287 /* Parse and fetch channel */
3288 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3289 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3290 goto fail;
3291 }
3292 pReqMsg->ap[i].channel = nla_get_u32(
3293 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3294 hddLog(VOS_TRACE_LEVEL_INFO,
3295 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3296 i++;
3297 }
3298 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3299 if (!HAL_STATUS_SUCCESS(status)) {
3300 hddLog(VOS_TRACE_LEVEL_ERROR,
3301 FL("sme_SetBssHotlist failed(err=%d)"), status);
3302 vos_mem_free(pReqMsg);
3303 return -EINVAL;
3304 }
3305
Dino Myclee8843b32014-07-04 14:21:45 +05303306 vos_mem_free(pReqMsg);
3307
Dino Mycle6fb96c12014-06-10 11:52:40 +05303308 return 0;
3309
3310fail:
3311 vos_mem_free(pReqMsg);
3312 return -EINVAL;
3313}
3314
3315static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3316 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303317 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303318{
3319 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3320 struct net_device *dev = wdev->netdev;
3321 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3322 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3323 struct nlattr
3324 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3325 struct nlattr
3326 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3327 struct nlattr *apTh;
3328 eHalStatus status;
3329 int i = 0;
3330 int rem;
3331
3332 status = wlan_hdd_validate_context(pHddCtx);
3333 if (0 != status)
3334 {
3335 hddLog(VOS_TRACE_LEVEL_ERROR,
3336 FL("HDD context is not valid"));
3337 return -EINVAL;
3338 }
Dino Myclee8843b32014-07-04 14:21:45 +05303339 /* check the EXTScan Capability */
3340 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3341 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3342 {
3343 hddLog(VOS_TRACE_LEVEL_ERROR,
3344 FL("EXTScan not enabled/supported by Firmware"));
3345 return -EINVAL;
3346 }
3347
Dino Mycle6fb96c12014-06-10 11:52:40 +05303348 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3349 data, dataLen,
3350 wlan_hdd_extscan_config_policy)) {
3351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3352 return -EINVAL;
3353 }
3354
3355 /* Parse and fetch request Id */
3356 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3357 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3358 return -EINVAL;
3359 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303360 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303361 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303362 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303363 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3364 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303365 }
3366
Dino Myclee8843b32014-07-04 14:21:45 +05303367
3368
Dino Mycle6fb96c12014-06-10 11:52:40 +05303369 pReqMsg->requestId = nla_get_u32(
3370 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3371 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3372
3373 /* Parse and fetch RSSI sample size */
3374 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3375 {
3376 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3377 goto fail;
3378 }
3379 pReqMsg->rssiSampleSize = nla_get_u32(
3380 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3381 hddLog(VOS_TRACE_LEVEL_INFO,
3382 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3383
3384 /* Parse and fetch lost AP sample size */
3385 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3386 {
3387 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3388 goto fail;
3389 }
3390 pReqMsg->lostApSampleSize = nla_get_u32(
3391 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3392 hddLog(VOS_TRACE_LEVEL_INFO,
3393 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3394 /* Parse and fetch minimum Breaching */
3395 if (!tb
3396 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3397 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3398 goto fail;
3399 }
3400 pReqMsg->minBreaching = nla_get_u32(
3401 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3402 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3403
3404 /* Parse and fetch number of APs */
3405 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3406 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3407 goto fail;
3408 }
3409 pReqMsg->numAp = nla_get_u32(
3410 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3411 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3412
3413 pReqMsg->sessionId = pAdapter->sessionId;
3414 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3415
3416 nla_for_each_nested(apTh,
3417 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3418 if(nla_parse(tb2,
3419 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3420 nla_data(apTh), nla_len(apTh),
3421 NULL)) {
3422 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3423 goto fail;
3424 }
3425
3426 /* Parse and fetch MAC address */
3427 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3428 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3429 goto fail;
3430 }
3431 memcpy(pReqMsg->ap[i].bssid, nla_data(
3432 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3433 sizeof(tSirMacAddr));
3434
3435 /* Parse and fetch low RSSI */
3436 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3437 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3438 goto fail;
3439 }
3440 pReqMsg->ap[i].low = nla_get_s32(
3441 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3442 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3443
3444 /* Parse and fetch high RSSI */
3445 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3446 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3447 goto fail;
3448 }
3449 pReqMsg->ap[i].high = nla_get_s32(
3450 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3451 hddLog(VOS_TRACE_LEVEL_INFO,
3452 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3453
3454 /* Parse and fetch channel */
3455 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3456 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3457 goto fail;
3458 }
3459 pReqMsg->ap[i].channel = nla_get_u32(
3460 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3461 hddLog(VOS_TRACE_LEVEL_INFO,
3462 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3463 i++;
3464 }
3465
3466 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3467 if (!HAL_STATUS_SUCCESS(status)) {
3468 hddLog(VOS_TRACE_LEVEL_ERROR,
3469 FL("sme_SetSignificantChange failed(err=%d)"), status);
3470 vos_mem_free(pReqMsg);
3471 return -EINVAL;
3472 }
Dino Myclee8843b32014-07-04 14:21:45 +05303473 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303474 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3475 return 0;
3476
3477fail:
3478 vos_mem_free(pReqMsg);
3479 return -EINVAL;
3480}
3481
3482static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3483 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303484 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303485{
3486 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3487 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3488 tANI_U8 numChannels = 0;
3489 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3490 tANI_U32 requestId;
3491 tWifiBand wifiBand;
3492 eHalStatus status;
3493 struct sk_buff *replySkb;
3494 tANI_U8 i;
3495
3496 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3497 status = wlan_hdd_validate_context(pHddCtx);
3498 if (0 != status)
3499 {
3500 hddLog(VOS_TRACE_LEVEL_ERROR,
3501 FL("HDD context is not valid"));
3502 return -EINVAL;
3503 }
Dino Myclee8843b32014-07-04 14:21:45 +05303504 /* check the EXTScan Capability */
3505 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3506 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3507 {
3508 hddLog(VOS_TRACE_LEVEL_ERROR,
3509 FL("EXTScan not enabled/supported by Firmware"));
3510 return -EINVAL;
3511 }
3512
Dino Mycle6fb96c12014-06-10 11:52:40 +05303513 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3514 data, dataLen,
3515 wlan_hdd_extscan_config_policy)) {
3516 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3517 return -EINVAL;
3518 }
3519
3520 /* Parse and fetch request Id */
3521 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3522 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3523 return -EINVAL;
3524 }
3525 requestId = nla_get_u32(
3526 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3527 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3528
3529 /* Parse and fetch wifi band */
3530 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3531 {
3532 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3533 return -EINVAL;
3534 }
3535 wifiBand = nla_get_u32(
3536 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3537 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3538
3539 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3540 wifiBand, ChannelList,
3541 &numChannels);
3542 if (eHAL_STATUS_SUCCESS != status) {
3543 hddLog(VOS_TRACE_LEVEL_ERROR,
3544 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3545 return -EINVAL;
3546 }
3547 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3548 for (i = 0; i < numChannels; i++)
3549 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3550
3551 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3552 sizeof(u32) * numChannels +
3553 NLMSG_HDRLEN);
3554
3555 if (!replySkb) {
3556 hddLog(VOS_TRACE_LEVEL_ERROR,
3557 FL("valid channels: buffer alloc fail"));
3558 return -EINVAL;
3559 }
3560 if (nla_put_u32(replySkb,
3561 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3562 numChannels) ||
3563 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3564 sizeof(u32) * numChannels, ChannelList)) {
3565
3566 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3567 kfree_skb(replySkb);
3568 return -EINVAL;
3569 }
3570
3571 return cfg80211_vendor_cmd_reply(replySkb);
3572}
3573
3574static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3575 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303576 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303577{
Dino Myclee8843b32014-07-04 14:21:45 +05303578 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303579 struct net_device *dev = wdev->netdev;
3580 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3581 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3582 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3583 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3584 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3585 struct nlattr *buckets;
3586 struct nlattr *channels;
3587 int rem1;
3588 int rem2;
3589 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303590 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303591
3592 status = wlan_hdd_validate_context(pHddCtx);
3593 if (0 != status)
3594 {
3595 hddLog(VOS_TRACE_LEVEL_ERROR,
3596 FL("HDD context is not valid"));
3597 return -EINVAL;
3598 }
Dino Myclee8843b32014-07-04 14:21:45 +05303599 /* check the EXTScan Capability */
3600 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3601 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3602 {
3603 hddLog(VOS_TRACE_LEVEL_ERROR,
3604 FL("EXTScan not enabled/supported by Firmware"));
3605 return -EINVAL;
3606 }
3607
Dino Mycle6fb96c12014-06-10 11:52:40 +05303608 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3609 data, dataLen,
3610 wlan_hdd_extscan_config_policy)) {
3611 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3612 return -EINVAL;
3613 }
3614
3615 /* Parse and fetch request Id */
3616 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3618 return -EINVAL;
3619 }
3620
Dino Myclee8843b32014-07-04 14:21:45 +05303621 pReqMsg = (tpSirEXTScanStartReqParams)
3622 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303623 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303624 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3625 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303626 }
3627
3628 pReqMsg->requestId = nla_get_u32(
3629 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3630 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3631
3632 pReqMsg->sessionId = pAdapter->sessionId;
3633 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3634
3635 /* Parse and fetch base period */
3636 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3637 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3638 goto fail;
3639 }
3640 pReqMsg->basePeriod = nla_get_u32(
3641 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3642 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3643 pReqMsg->basePeriod);
3644
3645 /* Parse and fetch max AP per scan */
3646 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3647 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3648 goto fail;
3649 }
3650 pReqMsg->maxAPperScan = nla_get_u32(
3651 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3652 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3653 pReqMsg->maxAPperScan);
3654
3655 /* Parse and fetch report threshold */
3656 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3657 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3658 goto fail;
3659 }
3660 pReqMsg->reportThreshold = nla_get_u8(
3661 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3662 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3663 pReqMsg->reportThreshold);
3664
3665 /* Parse and fetch number of buckets */
3666 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3668 goto fail;
3669 }
3670 pReqMsg->numBuckets = nla_get_u8(
3671 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3672 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3673 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3674 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3675 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3676 }
3677 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3678 pReqMsg->numBuckets);
3679 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3680 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3681 goto fail;
3682 }
3683
3684 nla_for_each_nested(buckets,
3685 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3686 if(nla_parse(bucket,
3687 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3688 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3689 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3690 goto fail;
3691 }
3692
3693 /* Parse and fetch bucket spec */
3694 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3696 goto fail;
3697 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303698
3699 pReqMsg->buckets[index].bucket = nla_get_u8(
3700 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3701
3702 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
3703 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303704
3705 /* Parse and fetch wifi band */
3706 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3707 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3708 goto fail;
3709 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303710 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303711 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3712 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303713 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303714
3715 /* Parse and fetch period */
3716 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3717 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3718 goto fail;
3719 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303720 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303721 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3722 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303723 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303724
3725 /* Parse and fetch report events */
3726 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3727 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3728 goto fail;
3729 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303730 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303731 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3732 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303733 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303734
3735 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303736 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
3737 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303738 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3739 goto fail;
3740 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303741 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303742 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3743 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303744 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303745
3746 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3747 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3748 goto fail;
3749 }
3750
3751 j = 0;
3752 nla_for_each_nested(channels,
3753 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3754 if(nla_parse(channel,
3755 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3756 nla_data(channels), nla_len(channels),
3757 NULL)) { //wlan_hdd_extscan_config_policy here
3758 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3759 goto fail;
3760 }
3761
3762 /* Parse and fetch channel */
3763 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3764 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3765 goto fail;
3766 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303767 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303768 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3769 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303770 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303771
3772 /* Parse and fetch dwell time */
3773 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3775 goto fail;
3776 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303777 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303778 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3779 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303780 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303781
3782 /* Parse and fetch channel spec passive */
3783 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3784 hddLog(VOS_TRACE_LEVEL_ERROR,
3785 FL("attr channel spec passive failed"));
3786 goto fail;
3787 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303788 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303789 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3790 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303791 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303792 j++;
3793 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303794 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303795 }
3796 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3797 if (!HAL_STATUS_SUCCESS(status)) {
3798 hddLog(VOS_TRACE_LEVEL_ERROR,
3799 FL("sme_EXTScanStart failed(err=%d)"), status);
3800 vos_mem_free(pReqMsg);
3801 return -EINVAL;
3802 }
3803
Dino Myclee8843b32014-07-04 14:21:45 +05303804 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303805 return 0;
3806
3807fail:
3808 vos_mem_free(pReqMsg);
3809 return -EINVAL;
3810}
3811
3812static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
3813 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303814 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303815{
Dino Myclee8843b32014-07-04 14:21:45 +05303816 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303817 struct net_device *dev = wdev->netdev;
3818 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3819 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3820 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3821 eHalStatus status;
3822
3823 status = wlan_hdd_validate_context(pHddCtx);
3824 if (0 != status)
3825 {
3826 hddLog(VOS_TRACE_LEVEL_ERROR,
3827 FL("HDD context is not valid"));
3828 return -EINVAL;
3829 }
Dino Myclee8843b32014-07-04 14:21:45 +05303830 /* check the EXTScan Capability */
3831 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3832 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3833 {
3834 hddLog(VOS_TRACE_LEVEL_ERROR,
3835 FL("EXTScan not enabled/supported by Firmware"));
3836 return -EINVAL;
3837 }
3838
Dino Mycle6fb96c12014-06-10 11:52:40 +05303839 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3840 data, dataLen,
3841 wlan_hdd_extscan_config_policy)) {
3842 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3843 return -EINVAL;
3844 }
3845
3846 /* Parse and fetch request Id */
3847 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3848 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3849 return -EINVAL;
3850 }
3851
Dino Myclee8843b32014-07-04 14:21:45 +05303852 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303853 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303854 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303855
Dino Myclee8843b32014-07-04 14:21:45 +05303856 reqMsg.sessionId = pAdapter->sessionId;
3857 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303858
Dino Myclee8843b32014-07-04 14:21:45 +05303859 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303860 if (!HAL_STATUS_SUCCESS(status)) {
3861 hddLog(VOS_TRACE_LEVEL_ERROR,
3862 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303863 return -EINVAL;
3864 }
3865
3866 return 0;
3867}
3868
3869static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
3870 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303871 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303872{
Dino Myclee8843b32014-07-04 14:21:45 +05303873 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303874 struct net_device *dev = wdev->netdev;
3875 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3876 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3877 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3878 eHalStatus status;
3879
3880 status = wlan_hdd_validate_context(pHddCtx);
3881 if (0 != status)
3882 {
3883 hddLog(VOS_TRACE_LEVEL_ERROR,
3884 FL("HDD context is not valid"));
3885 return -EINVAL;
3886 }
Dino Myclee8843b32014-07-04 14:21:45 +05303887 /* check the EXTScan Capability */
3888 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3889 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3890 {
3891 hddLog(VOS_TRACE_LEVEL_ERROR,
3892 FL("EXTScan not enabled/supported by Firmware"));
3893 return -EINVAL;
3894 }
3895
Dino Mycle6fb96c12014-06-10 11:52:40 +05303896 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3897 data, dataLen,
3898 wlan_hdd_extscan_config_policy)) {
3899 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3900 return -EINVAL;
3901 }
3902
3903 /* Parse and fetch request Id */
3904 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3905 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3906 return -EINVAL;
3907 }
3908
Dino Myclee8843b32014-07-04 14:21:45 +05303909 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303910 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303911 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303912
Dino Myclee8843b32014-07-04 14:21:45 +05303913 reqMsg.sessionId = pAdapter->sessionId;
3914 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303915
Dino Myclee8843b32014-07-04 14:21:45 +05303916 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303917 if (!HAL_STATUS_SUCCESS(status)) {
3918 hddLog(VOS_TRACE_LEVEL_ERROR,
3919 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303920 return -EINVAL;
3921 }
3922
3923 return 0;
3924}
3925
3926static int wlan_hdd_cfg80211_extscan_reset_significant_change(
3927 struct wiphy *wiphy,
3928 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303929 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303930{
Dino Myclee8843b32014-07-04 14:21:45 +05303931 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303932 struct net_device *dev = wdev->netdev;
3933 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3934 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3935 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3936 eHalStatus status;
3937
3938 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
3939 status = wlan_hdd_validate_context(pHddCtx);
3940 if (0 != status)
3941 {
3942 hddLog(VOS_TRACE_LEVEL_ERROR,
3943 FL("HDD context is not valid"));
3944 return -EINVAL;
3945 }
Dino Myclee8843b32014-07-04 14:21:45 +05303946 /* check the EXTScan Capability */
3947 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3948 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3949 {
3950 hddLog(VOS_TRACE_LEVEL_ERROR,
3951 FL("EXTScan not enabled/supported by Firmware"));
3952 return -EINVAL;
3953 }
3954
Dino Mycle6fb96c12014-06-10 11:52:40 +05303955 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3956 data, dataLen,
3957 wlan_hdd_extscan_config_policy)) {
3958 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3959 return -EINVAL;
3960 }
3961
3962 /* Parse and fetch request Id */
3963 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3964 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3965 return -EINVAL;
3966 }
3967
Dino Mycle6fb96c12014-06-10 11:52:40 +05303968
Dino Myclee8843b32014-07-04 14:21:45 +05303969 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303970 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303971 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303972
Dino Myclee8843b32014-07-04 14:21:45 +05303973 reqMsg.sessionId = pAdapter->sessionId;
3974 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303975
Dino Myclee8843b32014-07-04 14:21:45 +05303976 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303977 if (!HAL_STATUS_SUCCESS(status)) {
3978 hddLog(VOS_TRACE_LEVEL_ERROR,
3979 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303980 return -EINVAL;
3981 }
3982
3983 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3984 return 0;
3985}
3986
3987#endif /* WLAN_FEATURE_EXTSCAN */
3988
Atul Mittal115287b2014-07-08 13:26:33 +05303989/*EXT TDLS*/
3990static const struct nla_policy
3991wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
3992{
3993 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
3994 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
3995 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
3996 {.type = NLA_S32 },
3997 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
3998 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
3999
4000};
4001
4002static const struct nla_policy
4003wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4004{
4005 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4006
4007};
4008
4009static const struct nla_policy
4010wlan_hdd_tdls_config_state_change_policy[
4011 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4012{
4013 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4014 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4015 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304016 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4017 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4018 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304019
4020};
4021
4022static const struct nla_policy
4023wlan_hdd_tdls_config_get_status_policy[
4024 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4025{
4026 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4027 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4028 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304029 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4030 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4031 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304032
4033};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304034
4035static const struct nla_policy
4036wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4037{
4038 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4039};
4040
4041static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
4042 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304043 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304044 int data_len)
4045{
4046
4047 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4048 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4049
4050 if (0 != wlan_hdd_validate_context(pHddCtx)){
4051 hddLog(VOS_TRACE_LEVEL_ERROR, FL("hdd Ctx invalid while spoof macAddr"));
4052 return -EINVAL;
4053 }
4054 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
4055 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN disabled in ini"));
4056 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304057 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304058 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
4059 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN not supported by FW"));
4060 return -ENOTSUPP;
4061 }
4062
4063 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4064 data, data_len, wlan_hdd_mac_config)) {
4065 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4066 return -EINVAL;
4067 }
4068
4069 /* Parse and fetch mac address */
4070 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4071 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4072 return -EINVAL;
4073 }
4074
4075 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4076 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4077 VOS_MAC_ADDR_LAST_3_BYTES);
4078
Siddharth Bhal76972212014-10-15 16:22:51 +05304079 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4080
4081 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304082 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4083 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304084 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4085 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4086 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4087 {
4088 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4089 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4090 VOS_MAC_ADDRESS_LEN);
4091 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304092 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304093
Siddharth Bhal76972212014-10-15 16:22:51 +05304094 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
4095 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304096 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4097 }
4098
4099 return 0;
4100}
4101
Atul Mittal115287b2014-07-08 13:26:33 +05304102static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4103 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304104 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304105 int data_len)
4106{
4107 u8 peer[6] = {0};
4108 struct net_device *dev = wdev->netdev;
4109 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4110 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4111 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4112 eHalStatus ret;
4113 tANI_S32 state;
4114 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304115 tANI_S32 global_operating_class = 0;
4116 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304117 struct sk_buff *skb = NULL;
4118
4119 ret = wlan_hdd_validate_context(pHddCtx);
4120 if (0 != ret) {
4121
4122 return -EINVAL;
4123 }
4124 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4125
4126 return -ENOTSUPP;
4127 }
4128 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4129 data, data_len,
4130 wlan_hdd_tdls_config_get_status_policy)) {
4131 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4132 return -EINVAL;
4133 }
4134
4135 /* Parse and fetch mac address */
4136 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4137 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4138 return -EINVAL;
4139 }
4140
4141 memcpy(peer, nla_data(
4142 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4143 sizeof(peer));
4144 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4145
4146 ret = wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
4147
4148 if (0 != ret) {
4149 hddLog(VOS_TRACE_LEVEL_ERROR,
4150 FL("get status Failed"));
4151 return -EINVAL;
4152 }
4153 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304154 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304155 NLMSG_HDRLEN);
4156
4157 if (!skb) {
4158 hddLog(VOS_TRACE_LEVEL_ERROR,
4159 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4160 return -EINVAL;
4161 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304162 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 +05304163 reason,
4164 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304165 global_operating_class,
4166 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304167 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304168 if (nla_put_s32(skb,
4169 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4170 state) ||
4171 nla_put_s32(skb,
4172 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4173 reason) ||
4174 nla_put_s32(skb,
4175 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4176 global_operating_class) ||
4177 nla_put_s32(skb,
4178 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4179 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304180
4181 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4182 goto nla_put_failure;
4183 }
4184
4185 return cfg80211_vendor_cmd_reply(skb);
4186
4187nla_put_failure:
4188 kfree_skb(skb);
4189 return -EINVAL;
4190}
4191
4192static int wlan_hdd_cfg80211_exttdls_callback(tANI_U8* mac,
4193 tANI_S32 state,
4194 tANI_S32 reason,
4195 void *ctx)
4196{
4197 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
4198 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4199 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304200 tANI_S32 global_operating_class = 0;
4201 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304202
4203 if (wlan_hdd_validate_context(pHddCtx)) {
4204 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "));
4205 return -EINVAL;
4206 }
4207
4208 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4209
4210 return -ENOTSUPP;
4211 }
4212 skb = cfg80211_vendor_event_alloc(
4213 pHddCtx->wiphy,
4214 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4215 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4216 GFP_KERNEL);
4217
4218 if (!skb) {
4219 hddLog(VOS_TRACE_LEVEL_ERROR,
4220 FL("cfg80211_vendor_event_alloc failed"));
4221 return -EINVAL;
4222 }
4223 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304224 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4225 reason,
4226 state,
4227 global_operating_class,
4228 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304229 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4230 MAC_ADDR_ARRAY(mac));
4231
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304232 if (nla_put(skb,
4233 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4234 VOS_MAC_ADDR_SIZE, mac) ||
4235 nla_put_s32(skb,
4236 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4237 state) ||
4238 nla_put_s32(skb,
4239 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4240 reason) ||
4241 nla_put_s32(skb,
4242 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4243 channel) ||
4244 nla_put_s32(skb,
4245 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4246 global_operating_class)
4247 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304248 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4249 goto nla_put_failure;
4250 }
4251
4252 cfg80211_vendor_event(skb, GFP_KERNEL);
4253 return (0);
4254
4255nla_put_failure:
4256 kfree_skb(skb);
4257 return -EINVAL;
4258}
4259
4260static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4261 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304262 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304263 int data_len)
4264{
4265 u8 peer[6] = {0};
4266 struct net_device *dev = wdev->netdev;
4267 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4268 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4269 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4270 eHalStatus status;
4271 tdls_req_params_t pReqMsg = {0};
4272
4273 status = wlan_hdd_validate_context(pHddCtx);
4274 if (0 != status) {
4275 hddLog(VOS_TRACE_LEVEL_ERROR,
4276 FL("HDD context is not valid"));
4277 return -EINVAL;
4278 }
4279 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4280
4281 return -ENOTSUPP;
4282 }
4283 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4284 data, data_len,
4285 wlan_hdd_tdls_config_enable_policy)) {
4286 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4287 return -EINVAL;
4288 }
4289
4290 /* Parse and fetch mac address */
4291 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4292 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4293 return -EINVAL;
4294 }
4295
4296 memcpy(peer, nla_data(
4297 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4298 sizeof(peer));
4299 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4300
4301 /* Parse and fetch channel */
4302 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4303 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4304 return -EINVAL;
4305 }
4306 pReqMsg.channel = nla_get_s32(
4307 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4308 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4309
4310 /* Parse and fetch global operating class */
4311 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4312 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4313 return -EINVAL;
4314 }
4315 pReqMsg.global_operating_class = nla_get_s32(
4316 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4317 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4318 pReqMsg.global_operating_class);
4319
4320 /* Parse and fetch latency ms */
4321 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4322 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4323 return -EINVAL;
4324 }
4325 pReqMsg.max_latency_ms = nla_get_s32(
4326 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4327 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4328 pReqMsg.max_latency_ms);
4329
4330 /* Parse and fetch required bandwidth kbps */
4331 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4332 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4333 return -EINVAL;
4334 }
4335
4336 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4337 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4338 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4339 pReqMsg.min_bandwidth_kbps);
4340
4341 return (wlan_hdd_tdls_extctrl_config_peer(pAdapter,
4342 peer,
4343 wlan_hdd_cfg80211_exttdls_callback));
4344}
4345
4346static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4347 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304348 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304349 int data_len)
4350{
4351 u8 peer[6] = {0};
4352 struct net_device *dev = wdev->netdev;
4353 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4354 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4355 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4356 eHalStatus status;
4357
4358 status = wlan_hdd_validate_context(pHddCtx);
4359 if (0 != status) {
4360 hddLog(VOS_TRACE_LEVEL_ERROR,
4361 FL("HDD context is not valid"));
4362 return -EINVAL;
4363 }
4364 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4365
4366 return -ENOTSUPP;
4367 }
4368 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4369 data, data_len,
4370 wlan_hdd_tdls_config_disable_policy)) {
4371 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4372 return -EINVAL;
4373 }
4374 /* Parse and fetch mac address */
4375 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4376 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4377 return -EINVAL;
4378 }
4379
4380 memcpy(peer, nla_data(
4381 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4382 sizeof(peer));
4383 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4384
4385 return (wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer));
4386}
4387
Dasari Srinivas7875a302014-09-26 17:50:57 +05304388static int
4389wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
4390 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304391 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05304392{
4393 struct net_device *dev = wdev->netdev;
4394 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4395 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4396 struct sk_buff *skb = NULL;
4397 tANI_U32 fset = 0;
4398
4399 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
4400 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
4401 fset |= WIFI_FEATURE_INFRA;
4402 }
4403
4404 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
4405 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
4406 fset |= WIFI_FEATURE_INFRA_5G;
4407 }
4408
4409#ifdef WLAN_FEATURE_P2P
4410 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
4411 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
4412 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
4413 fset |= WIFI_FEATURE_P2P;
4414 }
4415#endif
4416
4417 /* Soft-AP is supported currently by default */
4418 fset |= WIFI_FEATURE_SOFT_AP;
4419
4420#ifdef WLAN_FEATURE_EXTSCAN
4421 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
4422 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
4423 hddLog(LOG1, FL("EXTScan is supported by firmware"));
4424 fset |= WIFI_FEATURE_EXTSCAN;
4425 }
4426#endif
4427
4428#ifdef WLAN_FEATURE_NAN
4429 if (sme_IsFeatureSupportedByFW(NAN)) {
4430 hddLog(LOG1, FL("NAN is supported by firmware"));
4431 fset |= WIFI_FEATURE_NAN;
4432 }
4433#endif
4434
4435 /* D2D RTT is not supported currently by default */
4436 if (sme_IsFeatureSupportedByFW(RTT)) {
4437 hddLog(LOG1, FL("RTT is supported by firmware"));
4438 fset |= WIFI_FEATURE_D2AP_RTT;
4439 }
4440
4441#ifdef FEATURE_WLAN_BATCH_SCAN
4442 if (fset & WIFI_FEATURE_EXTSCAN) {
4443 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
4444 fset &= ~WIFI_FEATURE_BATCH_SCAN;
4445 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
4446 hddLog(LOG1, FL("Batch scan is supported by firmware"));
4447 fset |= WIFI_FEATURE_BATCH_SCAN;
4448 }
4449#endif
4450
4451#ifdef FEATURE_WLAN_SCAN_PNO
4452 if (pHddCtx->cfg_ini->configPNOScanSupport &&
4453 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
4454 hddLog(LOG1, FL("PNO is supported by firmware"));
4455 fset |= WIFI_FEATURE_PNO;
4456 }
4457#endif
4458
4459 /* STA+STA is supported currently by default */
4460 fset |= WIFI_FEATURE_ADDITIONAL_STA;
4461
4462#ifdef FEATURE_WLAN_TDLS
4463 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
4464 sme_IsFeatureSupportedByFW(TDLS)) {
4465 hddLog(LOG1, FL("TDLS is supported by firmware"));
4466 fset |= WIFI_FEATURE_TDLS;
4467 }
4468
4469 /* TDLS_OFFCHANNEL is not supported currently by default */
4470#endif
4471
4472#ifdef WLAN_AP_STA_CONCURRENCY
4473 /* AP+STA concurrency is supported currently by default */
4474 fset |= WIFI_FEATURE_AP_STA;
4475#endif
4476
4477 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
4478 NLMSG_HDRLEN);
4479
4480 if (!skb) {
4481 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4482 return -EINVAL;
4483 }
4484 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
4485
4486 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
4487 hddLog(LOGE, FL("nla put fail"));
4488 goto nla_put_failure;
4489 }
4490
4491 return cfg80211_vendor_cmd_reply(skb);
4492
4493nla_put_failure:
4494 kfree_skb(skb);
4495 return -EINVAL;
4496}
4497
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304498static int
4499wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
4500 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304501 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304502{
4503 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
4504 uint8_t i, feature_sets, max_feature_sets;
4505 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
4506 struct sk_buff *reply_skb;
4507
4508 ENTER();
4509
4510 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
4511 data, data_len, NULL)) {
4512 hddLog(LOGE, FL("Invalid ATTR"));
4513 return -EINVAL;
4514 }
4515
4516 /* Parse and fetch max feature set */
4517 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
4518 hddLog(LOGE, FL("Attr max feature set size failed"));
4519 return -EINVAL;
4520 }
4521 max_feature_sets = nla_get_u32(
4522 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
4523 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
4524
4525 /* Fill feature combination matrix */
4526 feature_sets = 0;
4527 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4528 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4529 WIFI_FEATURE_P2P;
4530
4531 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4532 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4533 WIFI_FEATURE_SOFT_AP;
4534
4535 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4536 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
4537 WIFI_FEATURE_SOFT_AP;
4538
4539 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4540 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4541 WIFI_FEATURE_SOFT_AP |
4542 WIFI_FEATURE_P2P;
4543
4544 /* Add more feature combinations here */
4545
4546 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
4547 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
4548 hddLog(LOG1, "Feature set matrix");
4549 for (i = 0; i < feature_sets; i++)
4550 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
4551
4552 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4553 sizeof(u32) * feature_sets +
4554 NLMSG_HDRLEN);
4555
4556 if (reply_skb) {
4557 if (nla_put_u32(reply_skb,
4558 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
4559 feature_sets) ||
4560 nla_put(reply_skb,
4561 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
4562 sizeof(u32) * feature_sets, feature_set_matrix)) {
4563 hddLog(LOGE, FL("nla put fail"));
4564 kfree_skb(reply_skb);
4565 return -EINVAL;
4566 }
4567
4568 return cfg80211_vendor_cmd_reply(reply_skb);
4569 }
4570 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
4571 return -ENOMEM;
4572
4573max_buffer_err:
4574 hddLog(LOGE, FL("Feature set max buffer size reached. feature_sets(%d) max(%d)"),
4575 feature_sets, WLAN_HDD_MAX_FEATURE_SET);
4576 return -EINVAL;
4577}
4578
Agarwal Ashish738843c2014-09-25 12:27:56 +05304579static const struct nla_policy
4580wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
4581 +1] =
4582{
4583 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
4584};
4585
4586static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
4587 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304588 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05304589 int data_len)
4590{
4591 struct net_device *dev = wdev->netdev;
4592 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4593 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4594 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4595 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
4596 eHalStatus status;
4597 u32 dfsFlag = 0;
4598
4599 status = wlan_hdd_validate_context(pHddCtx);
4600 if (0 != status) {
4601 hddLog(VOS_TRACE_LEVEL_ERROR,
4602 FL("HDD context is not valid"));
4603 return -EINVAL;
4604 }
4605 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
4606 data, data_len,
4607 wlan_hdd_set_no_dfs_flag_config_policy)) {
4608 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4609 return -EINVAL;
4610 }
4611
4612 /* Parse and fetch required bandwidth kbps */
4613 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
4614 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
4615 return -EINVAL;
4616 }
4617
4618 dfsFlag = nla_get_u32(
4619 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
4620 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
4621 dfsFlag);
4622
4623 pHddCtx->disable_dfs_flag = dfsFlag;
4624
4625 sme_disable_dfs_channel(hHal, dfsFlag);
4626 sme_FilterScanResults(hHal, pAdapter->sessionId);
4627 return 0;
4628}
Atul Mittal115287b2014-07-08 13:26:33 +05304629
Mukul Sharma2a271632014-10-13 14:59:01 +05304630const struct
4631nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
4632{
4633 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
4634 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
4635};
4636
4637static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05304638 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05304639{
4640
4641 u8 bssid[6] = {0};
4642 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4643 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
4644 eHalStatus status = eHAL_STATUS_SUCCESS;
4645 v_U32_t isFwrRoamEnabled = FALSE;
4646 int ret;
4647
4648 if (NULL == pHddCtx) {
4649 hddLog(VOS_TRACE_LEVEL_ERROR,
4650 FL("HDD context is not valid"));
4651 return -EINVAL;
4652 }
4653
4654 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
4655 data, data_len,
4656 qca_wlan_vendor_attr);
4657 if (ret){
4658 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4659 return -EINVAL;
4660 }
4661
4662 /* Parse and fetch Enable flag */
4663 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
4664 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
4665 return -EINVAL;
4666 }
4667
4668 isFwrRoamEnabled = nla_get_u32(
4669 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
4670
4671 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
4672
4673 /* Parse and fetch bssid */
4674 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
4675 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
4676 return -EINVAL;
4677 }
4678
4679 memcpy(bssid, nla_data(
4680 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
4681 sizeof(bssid));
4682 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
4683
4684 //Update roaming
4685 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
4686 return status;
4687}
4688
Sunil Duttc69bccb2014-05-26 21:30:20 +05304689const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
4690{
Mukul Sharma2a271632014-10-13 14:59:01 +05304691 {
4692 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4693 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
4694 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4695 WIPHY_VENDOR_CMD_NEED_NETDEV |
4696 WIPHY_VENDOR_CMD_NEED_RUNNING,
Jeff Johnson393c2702014-12-16 11:09:35 +05304697 .doit = (void *)wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05304698 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304699#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4700 {
4701 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4702 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
4703 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4704 WIPHY_VENDOR_CMD_NEED_NETDEV |
4705 WIPHY_VENDOR_CMD_NEED_RUNNING,
Jeff Johnson393c2702014-12-16 11:09:35 +05304706 .doit = (void *)wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05304707 },
4708
4709 {
4710 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4711 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
4712 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4713 WIPHY_VENDOR_CMD_NEED_NETDEV |
4714 WIPHY_VENDOR_CMD_NEED_RUNNING,
Jeff Johnson393c2702014-12-16 11:09:35 +05304715 .doit = (void *)wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05304716 },
4717
4718 {
4719 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4720 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
4721 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4722 WIPHY_VENDOR_CMD_NEED_NETDEV |
4723 WIPHY_VENDOR_CMD_NEED_RUNNING,
Jeff Johnson393c2702014-12-16 11:09:35 +05304724 .doit = (void *)wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05304725 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304726#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304727#ifdef WLAN_FEATURE_EXTSCAN
4728 {
4729 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4730 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
4731 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4732 WIPHY_VENDOR_CMD_NEED_NETDEV |
4733 WIPHY_VENDOR_CMD_NEED_RUNNING,
Jeff Johnson393c2702014-12-16 11:09:35 +05304734 .doit = (void *)wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05304735 },
4736 {
4737 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4738 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
4739 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4740 WIPHY_VENDOR_CMD_NEED_NETDEV |
4741 WIPHY_VENDOR_CMD_NEED_RUNNING,
Jeff Johnson393c2702014-12-16 11:09:35 +05304742 .doit = (void *)wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05304743 },
4744 {
4745 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4746 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
4747 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4748 WIPHY_VENDOR_CMD_NEED_NETDEV,
Jeff Johnson393c2702014-12-16 11:09:35 +05304749 .doit = (void *)wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05304750 },
4751 {
4752 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4753 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
4754 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4755 WIPHY_VENDOR_CMD_NEED_NETDEV |
4756 WIPHY_VENDOR_CMD_NEED_RUNNING,
Jeff Johnson393c2702014-12-16 11:09:35 +05304757 .doit = (void *)wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05304758 },
4759 {
4760 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4761 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
4762 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4763 WIPHY_VENDOR_CMD_NEED_NETDEV |
4764 WIPHY_VENDOR_CMD_NEED_RUNNING,
Jeff Johnson393c2702014-12-16 11:09:35 +05304765 .doit = (void *)wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05304766 },
4767 {
4768 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4769 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
4770 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4771 WIPHY_VENDOR_CMD_NEED_NETDEV |
4772 WIPHY_VENDOR_CMD_NEED_RUNNING,
Jeff Johnson393c2702014-12-16 11:09:35 +05304773 .doit = (void *)wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05304774 },
4775 {
4776 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4777 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
4778 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4779 WIPHY_VENDOR_CMD_NEED_NETDEV |
4780 WIPHY_VENDOR_CMD_NEED_RUNNING,
Jeff Johnson393c2702014-12-16 11:09:35 +05304781 .doit = (void *)wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05304782 },
4783 {
4784 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4785 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
4786 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4787 WIPHY_VENDOR_CMD_NEED_NETDEV |
4788 WIPHY_VENDOR_CMD_NEED_RUNNING,
Jeff Johnson393c2702014-12-16 11:09:35 +05304789 .doit = (void *)wlan_hdd_cfg80211_extscan_set_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05304790 },
4791 {
4792 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4793 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
4794 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4795 WIPHY_VENDOR_CMD_NEED_NETDEV |
4796 WIPHY_VENDOR_CMD_NEED_RUNNING,
Jeff Johnson393c2702014-12-16 11:09:35 +05304797 .doit = (void *)wlan_hdd_cfg80211_extscan_reset_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05304798 },
4799#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304800/*EXT TDLS*/
4801 {
4802 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4803 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
4804 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4805 WIPHY_VENDOR_CMD_NEED_NETDEV |
4806 WIPHY_VENDOR_CMD_NEED_RUNNING,
Jeff Johnson393c2702014-12-16 11:09:35 +05304807 .doit = (void *)wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05304808 },
4809 {
4810 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4811 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
4812 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4813 WIPHY_VENDOR_CMD_NEED_NETDEV |
4814 WIPHY_VENDOR_CMD_NEED_RUNNING,
Jeff Johnson393c2702014-12-16 11:09:35 +05304815 .doit = (void *)wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05304816 },
4817 {
4818 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4819 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
4820 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4821 WIPHY_VENDOR_CMD_NEED_NETDEV,
Jeff Johnson393c2702014-12-16 11:09:35 +05304822 .doit = (void *)wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05304823 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05304824 {
4825 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4826 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
4827 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4828 WIPHY_VENDOR_CMD_NEED_NETDEV,
Jeff Johnson393c2702014-12-16 11:09:35 +05304829 .doit = (void *)wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05304830 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05304831 {
4832 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4833 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
4834 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4835 WIPHY_VENDOR_CMD_NEED_NETDEV,
Jeff Johnson393c2702014-12-16 11:09:35 +05304836 .doit = (void *)wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05304837 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304838 {
4839 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4840 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
4841 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4842 WIPHY_VENDOR_CMD_NEED_NETDEV,
Jeff Johnson393c2702014-12-16 11:09:35 +05304843 .doit = (void *) wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304844 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304845 {
4846 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4847 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
4848 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4849 WIPHY_VENDOR_CMD_NEED_NETDEV,
Jeff Johnson393c2702014-12-16 11:09:35 +05304850 .doit = (void *)wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304851 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304852};
4853
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004854/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05304855static const
4856struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004857{
4858#ifdef FEATURE_WLAN_CH_AVOID
4859 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05304860 .vendor_id = QCA_NL80211_VENDOR_ID,
4861 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004862 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304863#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
4864#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4865 {
4866 /* Index = 1*/
4867 .vendor_id = QCA_NL80211_VENDOR_ID,
4868 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
4869 },
4870 {
4871 /* Index = 2*/
4872 .vendor_id = QCA_NL80211_VENDOR_ID,
4873 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
4874 },
4875 {
4876 /* Index = 3*/
4877 .vendor_id = QCA_NL80211_VENDOR_ID,
4878 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
4879 },
4880 {
4881 /* Index = 4*/
4882 .vendor_id = QCA_NL80211_VENDOR_ID,
4883 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
4884 },
4885 {
4886 /* Index = 5*/
4887 .vendor_id = QCA_NL80211_VENDOR_ID,
4888 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
4889 },
4890 {
4891 /* Index = 6*/
4892 .vendor_id = QCA_NL80211_VENDOR_ID,
4893 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
4894 },
4895#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304896#ifdef WLAN_FEATURE_EXTSCAN
4897 {
4898 .vendor_id = QCA_NL80211_VENDOR_ID,
4899 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
4900 },
4901 {
4902 .vendor_id = QCA_NL80211_VENDOR_ID,
4903 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
4904 },
4905 {
4906 .vendor_id = QCA_NL80211_VENDOR_ID,
4907 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
4908 },
4909 {
4910 .vendor_id = QCA_NL80211_VENDOR_ID,
4911 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
4912 },
4913 {
4914 .vendor_id = QCA_NL80211_VENDOR_ID,
4915 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
4916 },
4917 {
4918 .vendor_id = QCA_NL80211_VENDOR_ID,
4919 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
4920 },
4921 {
4922 .vendor_id = QCA_NL80211_VENDOR_ID,
4923 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
4924 },
4925 {
4926 .vendor_id = QCA_NL80211_VENDOR_ID,
4927 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
4928 },
4929 {
4930 .vendor_id = QCA_NL80211_VENDOR_ID,
4931 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
4932 },
4933 {
4934 .vendor_id = QCA_NL80211_VENDOR_ID,
4935 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
4936 },
4937 {
4938 .vendor_id = QCA_NL80211_VENDOR_ID,
4939 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
4940 },
4941 {
4942 .vendor_id = QCA_NL80211_VENDOR_ID,
4943 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
4944 },
4945 {
4946 .vendor_id = QCA_NL80211_VENDOR_ID,
4947 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
4948 },
4949#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304950/*EXT TDLS*/
4951 {
4952 .vendor_id = QCA_NL80211_VENDOR_ID,
4953 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
4954 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004955};
4956
Jeff Johnson295189b2012-06-20 16:38:30 -07004957/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304958 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304959 * This function is called by hdd_wlan_startup()
4960 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304961 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07004962 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304963struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07004964{
4965 struct wiphy *wiphy;
4966 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304967 /*
4968 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07004969 */
4970 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
4971
4972 if (!wiphy)
4973 {
4974 /* Print error and jump into err label and free the memory */
4975 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
4976 return NULL;
4977 }
4978
Sunil Duttc69bccb2014-05-26 21:30:20 +05304979
Jeff Johnson295189b2012-06-20 16:38:30 -07004980 return wiphy;
4981}
4982
4983/*
4984 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304985 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07004986 * private ioctl to change the band value
4987 */
4988int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
4989{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304990 int i, j;
4991 eNVChannelEnabledType channelEnabledState;
4992
Jeff Johnsone7245742012-09-05 17:12:55 -07004993 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304994
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304995 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07004996 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304997
4998 if (NULL == wiphy->bands[i])
4999 {
5000 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5001 __func__, i);
5002 continue;
5003 }
5004
5005 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5006 {
5007 struct ieee80211_supported_band *band = wiphy->bands[i];
5008
5009 channelEnabledState = vos_nv_getChannelEnabledState(
5010 band->channels[j].hw_value);
5011
5012 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
5013 {
Abhishek Singh678227a2014-11-04 10:52:38 +05305014 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305015 continue;
5016 }
5017 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
5018 {
5019 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5020 continue;
5021 }
5022
5023 if (NV_CHANNEL_DISABLE == channelEnabledState ||
5024 NV_CHANNEL_INVALID == channelEnabledState)
5025 {
5026 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5027 }
5028 else if (NV_CHANNEL_DFS == channelEnabledState)
5029 {
5030 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5031 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
5032 }
5033 else
5034 {
5035 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
5036 |IEEE80211_CHAN_RADAR);
5037 }
5038 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005039 }
5040 return 0;
5041}
5042/*
5043 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305044 * This function is called by hdd_wlan_startup()
5045 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005046 * This function is used to initialize and register wiphy structure.
5047 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305048int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005049 struct wiphy *wiphy,
5050 hdd_config_t *pCfg
5051 )
5052{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305053 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305054 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5055
Jeff Johnsone7245742012-09-05 17:12:55 -07005056 ENTER();
5057
Jeff Johnson295189b2012-06-20 16:38:30 -07005058 /* Now bind the underlying wlan device with wiphy */
5059 set_wiphy_dev(wiphy, dev);
5060
5061 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005062
Kiet Lam6c583332013-10-14 05:37:09 +05305063#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005064 /* the flag for the other case would be initialzed in
5065 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005066 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305067#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005068
Amar Singhalfddc28c2013-09-05 13:03:40 -07005069 /* This will disable updating of NL channels from passive to
5070 * active if a beacon is received on passive channel. */
5071 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07005072
Amar Singhalfddc28c2013-09-05 13:03:40 -07005073
Amar Singhala49cbc52013-10-08 18:37:44 -07005074
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005075#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005076 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5077 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5078 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005079 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05305080 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005081#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005082
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005083#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005084 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005085#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005086 || pCfg->isFastRoamIniFeatureEnabled
5087#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005088#ifdef FEATURE_WLAN_ESE
5089 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005090#endif
5091 )
5092 {
5093 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5094 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005095#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005096#ifdef FEATURE_WLAN_TDLS
5097 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5098 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5099#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305100#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305101 if (pCfg->configPNOScanSupport)
5102 {
5103 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5104 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5105 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5106 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5107 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305108#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005109
Amar Singhalfddc28c2013-09-05 13:03:40 -07005110#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005111 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5112 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005113 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005114 driver need to determine what to do with both
5115 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005116
5117 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005118#else
5119 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005120#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005121
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305122 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5123
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05305124 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005125
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305126 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5127
Jeff Johnson295189b2012-06-20 16:38:30 -07005128 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305129 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07005130 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07005131 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5132 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005133 | BIT(NL80211_IFTYPE_AP);
5134
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305135 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005136 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305137#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5138 if( pCfg->enableMCC )
5139 {
5140 /* Currently, supports up to two channels */
5141 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005142
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305143 if( !pCfg->allowMCCGODiffBI )
5144 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005145
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305146 }
5147 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5148 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005149#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305150 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005151
Jeff Johnson295189b2012-06-20 16:38:30 -07005152 /* Before registering we need to update the ht capabilitied based
5153 * on ini values*/
5154 if( !pCfg->ShortGI20MhzEnable )
5155 {
5156 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5157 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5158 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5159 }
5160
5161 if( !pCfg->ShortGI40MhzEnable )
5162 {
5163 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5164 }
5165
5166 if( !pCfg->nChannelBondingMode5GHz )
5167 {
5168 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5169 }
5170
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305171 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305172 if (true == hdd_is_5g_supported(pHddCtx))
5173 {
5174 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5175 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305176
5177 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5178 {
5179
5180 if (NULL == wiphy->bands[i])
5181 {
5182 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5183 __func__, i);
5184 continue;
5185 }
5186
5187 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5188 {
5189 struct ieee80211_supported_band *band = wiphy->bands[i];
5190
5191 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5192 {
5193 // Enable social channels for P2P
5194 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5195 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5196 else
5197 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5198 continue;
5199 }
5200 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5201 {
5202 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5203 continue;
5204 }
5205 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005206 }
5207 /*Initialise the supported cipher suite details*/
5208 wiphy->cipher_suites = hdd_cipher_suites;
5209 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5210
5211 /*signal strength in mBm (100*dBm) */
5212 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5213
5214#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305215 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005216#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005217
Sunil Duttc69bccb2014-05-26 21:30:20 +05305218 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
5219 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005220 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
5221 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
5222
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305223 EXIT();
5224 return 0;
5225}
5226
5227/* In this function we are registering wiphy. */
5228int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
5229{
5230 ENTER();
5231 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005232 if (0 > wiphy_register(wiphy))
5233 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305234 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07005235 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
5236 return -EIO;
5237 }
5238
5239 EXIT();
5240 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305241}
Jeff Johnson295189b2012-06-20 16:38:30 -07005242
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305243/* In this function we are updating channel list when,
5244 regulatory domain is FCC and country code is US.
5245 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
5246 As per FCC smart phone is not a indoor device.
5247 GO should not opeate on indoor channels */
5248void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
5249{
5250 int j;
5251 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5252 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
5253 //Default counrtycode from NV at the time of wiphy initialization.
5254 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
5255 &defaultCountryCode[0]))
5256 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005257 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305258 }
5259 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
5260 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305261 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
5262 {
5263 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
5264 return;
5265 }
5266 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
5267 {
5268 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
5269 // Mark UNII -1 band channel as passive
5270 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
5271 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
5272 }
5273 }
5274}
5275
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305276/* This function registers for all frame which supplicant is interested in */
5277void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005278{
Jeff Johnson295189b2012-06-20 16:38:30 -07005279 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5280 /* Register for all P2P action, public action etc frames */
5281 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5282
Jeff Johnsone7245742012-09-05 17:12:55 -07005283 ENTER();
5284
Jeff Johnson295189b2012-06-20 16:38:30 -07005285 /* Right now we are registering these frame when driver is getting
5286 initialized. Once we will move to 2.6.37 kernel, in which we have
5287 frame register ops, we will move this code as a part of that */
5288 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305289 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07005290 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5291
5292 /* GAS Initial Response */
5293 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5294 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305295
Jeff Johnson295189b2012-06-20 16:38:30 -07005296 /* GAS Comeback Request */
5297 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5298 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5299
5300 /* GAS Comeback Response */
5301 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5302 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5303
5304 /* P2P Public Action */
5305 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305306 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005307 P2P_PUBLIC_ACTION_FRAME_SIZE );
5308
5309 /* P2P Action */
5310 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5311 (v_U8_t*)P2P_ACTION_FRAME,
5312 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07005313
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05305314 /* WNM BSS Transition Request frame */
5315 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5316 (v_U8_t*)WNM_BSS_ACTION_FRAME,
5317 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005318
5319 /* WNM-Notification */
5320 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5321 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5322 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005323}
5324
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305325void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005326{
Jeff Johnson295189b2012-06-20 16:38:30 -07005327 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5328 /* Register for all P2P action, public action etc frames */
5329 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5330
Jeff Johnsone7245742012-09-05 17:12:55 -07005331 ENTER();
5332
Jeff Johnson295189b2012-06-20 16:38:30 -07005333 /* Right now we are registering these frame when driver is getting
5334 initialized. Once we will move to 2.6.37 kernel, in which we have
5335 frame register ops, we will move this code as a part of that */
5336 /* GAS Initial Request */
5337
5338 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5339 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5340
5341 /* GAS Initial Response */
5342 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5343 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305344
Jeff Johnson295189b2012-06-20 16:38:30 -07005345 /* GAS Comeback Request */
5346 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5347 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5348
5349 /* GAS Comeback Response */
5350 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5351 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5352
5353 /* P2P Public Action */
5354 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305355 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005356 P2P_PUBLIC_ACTION_FRAME_SIZE );
5357
5358 /* P2P Action */
5359 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5360 (v_U8_t*)P2P_ACTION_FRAME,
5361 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005362 /* WNM-Notification */
5363 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5364 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5365 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005366}
5367
5368#ifdef FEATURE_WLAN_WAPI
5369void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
5370 const u8 *mac_addr, u8 *key , int key_Len)
5371{
5372 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5373 tCsrRoamSetKey setKey;
5374 v_BOOL_t isConnected = TRUE;
5375 int status = 0;
5376 v_U32_t roamId= 0xFF;
5377 tANI_U8 *pKeyPtr = NULL;
5378 int n = 0;
5379
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305380 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
5381 __func__, hdd_device_modetoString(pAdapter->device_mode),
5382 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005383
Gopichand Nakkalae7480202013-02-11 15:24:22 +05305384 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005385 setKey.keyId = key_index; // Store Key ID
5386 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
5387 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
5388 setKey.paeRole = 0 ; // the PAE role
5389 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
5390 {
5391 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
5392 }
5393 else
5394 {
5395 isConnected = hdd_connIsConnected(pHddStaCtx);
5396 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
5397 }
5398 setKey.keyLength = key_Len;
5399 pKeyPtr = setKey.Key;
5400 memcpy( pKeyPtr, key, key_Len);
5401
Arif Hussain6d2a3322013-11-17 19:50:10 -08005402 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005403 __func__, key_Len);
5404 for (n = 0 ; n < key_Len; n++)
5405 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
5406 __func__,n,setKey.Key[n]);
5407
5408 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
5409 if ( isConnected )
5410 {
5411 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
5412 pAdapter->sessionId, &setKey, &roamId );
5413 }
5414 if ( status != 0 )
5415 {
5416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5417 "[%4d] sme_RoamSetKey returned ERROR status= %d",
5418 __LINE__, status );
5419 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
5420 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05305421 /* Need to clear any trace of key value in the memory.
5422 * Thus zero out the memory even though it is local
5423 * variable.
5424 */
5425 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005426}
5427#endif /* FEATURE_WLAN_WAPI*/
5428
5429#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305430int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005431 beacon_data_t **ppBeacon,
5432 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005433#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305434int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005435 beacon_data_t **ppBeacon,
5436 struct cfg80211_beacon_data *params,
5437 int dtim_period)
5438#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305439{
Jeff Johnson295189b2012-06-20 16:38:30 -07005440 int size;
5441 beacon_data_t *beacon = NULL;
5442 beacon_data_t *old = NULL;
5443 int head_len,tail_len;
5444
Jeff Johnsone7245742012-09-05 17:12:55 -07005445 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005446 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305447 {
5448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5449 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005450 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305451 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005452
5453 old = pAdapter->sessionCtx.ap.beacon;
5454
5455 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305456 {
5457 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5458 FL("session(%d) old and new heads points to NULL"),
5459 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005460 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305461 }
5462
5463 if (params->tail && !params->tail_len)
5464 {
5465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5466 FL("tail_len is zero but tail is not NULL"));
5467 return -EINVAL;
5468 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005469
Jeff Johnson295189b2012-06-20 16:38:30 -07005470#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
5471 /* Kernel 3.0 is not updating dtim_period for set beacon */
5472 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305473 {
5474 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5475 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005476 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305477 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005478#endif
5479
5480 if(params->head)
5481 head_len = params->head_len;
5482 else
5483 head_len = old->head_len;
5484
5485 if(params->tail || !old)
5486 tail_len = params->tail_len;
5487 else
5488 tail_len = old->tail_len;
5489
5490 size = sizeof(beacon_data_t) + head_len + tail_len;
5491
5492 beacon = kzalloc(size, GFP_KERNEL);
5493
5494 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305495 {
5496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5497 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005498 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305499 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005500
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005501#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005502 if(params->dtim_period || !old )
5503 beacon->dtim_period = params->dtim_period;
5504 else
5505 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005506#else
5507 if(dtim_period || !old )
5508 beacon->dtim_period = dtim_period;
5509 else
5510 beacon->dtim_period = old->dtim_period;
5511#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305512
Jeff Johnson295189b2012-06-20 16:38:30 -07005513 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
5514 beacon->tail = beacon->head + head_len;
5515 beacon->head_len = head_len;
5516 beacon->tail_len = tail_len;
5517
5518 if(params->head) {
5519 memcpy (beacon->head,params->head,beacon->head_len);
5520 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305521 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07005522 if(old)
5523 memcpy (beacon->head,old->head,beacon->head_len);
5524 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305525
Jeff Johnson295189b2012-06-20 16:38:30 -07005526 if(params->tail) {
5527 memcpy (beacon->tail,params->tail,beacon->tail_len);
5528 }
5529 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305530 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07005531 memcpy (beacon->tail,old->tail,beacon->tail_len);
5532 }
5533
5534 *ppBeacon = beacon;
5535
5536 kfree(old);
5537
5538 return 0;
5539
5540}
Jeff Johnson295189b2012-06-20 16:38:30 -07005541
5542v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
5543{
5544 int left = length;
5545 v_U8_t *ptr = pIes;
5546 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305547
Jeff Johnson295189b2012-06-20 16:38:30 -07005548 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305549 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005550 elem_id = ptr[0];
5551 elem_len = ptr[1];
5552 left -= 2;
5553 if(elem_len > left)
5554 {
5555 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005556 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005557 eid,elem_len,left);
5558 return NULL;
5559 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305560 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005561 {
5562 return ptr;
5563 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305564
Jeff Johnson295189b2012-06-20 16:38:30 -07005565 left -= elem_len;
5566 ptr += (elem_len + 2);
5567 }
5568 return NULL;
5569}
5570
Jeff Johnson295189b2012-06-20 16:38:30 -07005571/* Check if rate is 11g rate or not */
5572static int wlan_hdd_rate_is_11g(u8 rate)
5573{
Sanjay Devnani28322e22013-06-21 16:13:40 -07005574 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005575 u8 i;
5576 for (i = 0; i < 8; i++)
5577 {
5578 if(rate == gRateArray[i])
5579 return TRUE;
5580 }
5581 return FALSE;
5582}
5583
5584/* Check for 11g rate and set proper 11g only mode */
5585static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
5586 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
5587{
5588 u8 i, num_rates = pIe[0];
5589
5590 pIe += 1;
5591 for ( i = 0; i < num_rates; i++)
5592 {
5593 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
5594 {
5595 /* If rate set have 11g rate than change the mode to 11G */
5596 *pSapHw_mode = eSAP_DOT11_MODE_11g;
5597 if (pIe[i] & BASIC_RATE_MASK)
5598 {
5599 /* If we have 11g rate as basic rate, it means mode
5600 is 11g only mode.
5601 */
5602 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
5603 *pCheckRatesfor11g = FALSE;
5604 }
5605 }
5606 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
5607 {
5608 *require_ht = TRUE;
5609 }
5610 }
5611 return;
5612}
5613
5614static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
5615{
5616 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5617 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5618 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5619 u8 checkRatesfor11g = TRUE;
5620 u8 require_ht = FALSE;
5621 u8 *pIe=NULL;
5622
5623 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
5624
5625 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
5626 pBeacon->head_len, WLAN_EID_SUPP_RATES);
5627 if (pIe != NULL)
5628 {
5629 pIe += 1;
5630 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5631 &pConfig->SapHw_mode);
5632 }
5633
5634 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5635 WLAN_EID_EXT_SUPP_RATES);
5636 if (pIe != NULL)
5637 {
5638
5639 pIe += 1;
5640 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5641 &pConfig->SapHw_mode);
5642 }
5643
5644 if( pConfig->channel > 14 )
5645 {
5646 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
5647 }
5648
5649 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5650 WLAN_EID_HT_CAPABILITY);
5651
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305652 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005653 {
5654 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
5655 if(require_ht)
5656 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
5657 }
5658}
5659
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305660static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
5661 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
5662{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005663 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305664 v_U8_t *pIe = NULL;
5665 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5666
5667 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
5668 pBeacon->tail, pBeacon->tail_len);
5669
5670 if (pIe)
5671 {
5672 ielen = pIe[1] + 2;
5673 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5674 {
5675 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
5676 }
5677 else
5678 {
5679 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
5680 return -EINVAL;
5681 }
5682 *total_ielen += ielen;
5683 }
5684 return 0;
5685}
5686
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005687static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
5688 v_U8_t *genie, v_U8_t *total_ielen)
5689{
5690 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5691 int left = pBeacon->tail_len;
5692 v_U8_t *ptr = pBeacon->tail;
5693 v_U8_t elem_id, elem_len;
5694 v_U16_t ielen = 0;
5695
5696 if ( NULL == ptr || 0 == left )
5697 return;
5698
5699 while (left >= 2)
5700 {
5701 elem_id = ptr[0];
5702 elem_len = ptr[1];
5703 left -= 2;
5704 if (elem_len > left)
5705 {
5706 hddLog( VOS_TRACE_LEVEL_ERROR,
5707 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
5708 elem_id, elem_len, left);
5709 return;
5710 }
5711 if (IE_EID_VENDOR == elem_id)
5712 {
5713 /* skipping the VSIE's which we don't want to include or
5714 * it will be included by existing code
5715 */
5716 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
5717#ifdef WLAN_FEATURE_WFD
5718 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
5719#endif
5720 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5721 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5722 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
5723 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5724 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
5725 {
5726 ielen = ptr[1] + 2;
5727 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5728 {
5729 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
5730 *total_ielen += ielen;
5731 }
5732 else
5733 {
5734 hddLog( VOS_TRACE_LEVEL_ERROR,
5735 "IE Length is too big "
5736 "IEs eid=%d elem_len=%d total_ie_lent=%d",
5737 elem_id, elem_len, *total_ielen);
5738 }
5739 }
5740 }
5741
5742 left -= elem_len;
5743 ptr += (elem_len + 2);
5744 }
5745 return;
5746}
5747
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005748#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005749static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5750 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005751#else
5752static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5753 struct cfg80211_beacon_data *params)
5754#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005755{
5756 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305757 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005758 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07005759 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005760
5761 genie = vos_mem_malloc(MAX_GENIE_LEN);
5762
5763 if(genie == NULL) {
5764
5765 return -ENOMEM;
5766 }
5767
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305768 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5769 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005770 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305771 hddLog(LOGE,
5772 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305773 ret = -EINVAL;
5774 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005775 }
5776
5777#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305778 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5779 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
5780 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305781 hddLog(LOGE,
5782 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305783 ret = -EINVAL;
5784 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005785 }
5786#endif
5787
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305788 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5789 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005790 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305791 hddLog(LOGE,
5792 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305793 ret = -EINVAL;
5794 goto done;
5795 }
5796
5797 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
5798 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005799 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07005800 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005801
5802 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5803 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
5804 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
5805 {
5806 hddLog(LOGE,
5807 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005808 ret = -EINVAL;
5809 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005810 }
5811
5812 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5813 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5814 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5815 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5816 ==eHAL_STATUS_FAILURE)
5817 {
5818 hddLog(LOGE,
5819 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005820 ret = -EINVAL;
5821 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005822 }
5823
5824 // Added for ProResp IE
5825 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
5826 {
5827 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
5828 u8 probe_rsp_ie_len[3] = {0};
5829 u8 counter = 0;
5830 /* Check Probe Resp Length if it is greater then 255 then Store
5831 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
5832 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
5833 Store More then 255 bytes into One Variable.
5834 */
5835 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
5836 {
5837 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
5838 {
5839 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
5840 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
5841 }
5842 else
5843 {
5844 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
5845 rem_probe_resp_ie_len = 0;
5846 }
5847 }
5848
5849 rem_probe_resp_ie_len = 0;
5850
5851 if (probe_rsp_ie_len[0] > 0)
5852 {
5853 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5854 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
5855 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5856 probe_rsp_ie_len[0], NULL,
5857 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5858 {
5859 hddLog(LOGE,
5860 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005861 ret = -EINVAL;
5862 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005863 }
5864 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
5865 }
5866
5867 if (probe_rsp_ie_len[1] > 0)
5868 {
5869 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5870 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
5871 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5872 probe_rsp_ie_len[1], NULL,
5873 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5874 {
5875 hddLog(LOGE,
5876 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005877 ret = -EINVAL;
5878 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005879 }
5880 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
5881 }
5882
5883 if (probe_rsp_ie_len[2] > 0)
5884 {
5885 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5886 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
5887 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5888 probe_rsp_ie_len[2], NULL,
5889 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5890 {
5891 hddLog(LOGE,
5892 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005893 ret = -EINVAL;
5894 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005895 }
5896 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
5897 }
5898
5899 if (probe_rsp_ie_len[1] == 0 )
5900 {
5901 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5902 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
5903 eANI_BOOLEAN_FALSE) )
5904 {
5905 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005906 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005907 }
5908 }
5909
5910 if (probe_rsp_ie_len[2] == 0 )
5911 {
5912 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5913 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
5914 eANI_BOOLEAN_FALSE) )
5915 {
5916 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005917 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005918 }
5919 }
5920
5921 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5922 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5923 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5924 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5925 == eHAL_STATUS_FAILURE)
5926 {
5927 hddLog(LOGE,
5928 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005929 ret = -EINVAL;
5930 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005931 }
5932 }
5933 else
5934 {
5935 // Reset WNI_CFG_PROBE_RSP Flags
5936 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
5937
5938 hddLog(VOS_TRACE_LEVEL_INFO,
5939 "%s: No Probe Response IE received in set beacon",
5940 __func__);
5941 }
5942
5943 // Added for AssocResp IE
5944 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
5945 {
5946 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5947 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
5948 params->assocresp_ies_len, NULL,
5949 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5950 {
5951 hddLog(LOGE,
5952 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005953 ret = -EINVAL;
5954 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005955 }
5956
5957 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5958 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
5959 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5960 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5961 == eHAL_STATUS_FAILURE)
5962 {
5963 hddLog(LOGE,
5964 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005965 ret = -EINVAL;
5966 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005967 }
5968 }
5969 else
5970 {
5971 hddLog(VOS_TRACE_LEVEL_INFO,
5972 "%s: No Assoc Response IE received in set beacon",
5973 __func__);
5974
5975 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5976 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5977 eANI_BOOLEAN_FALSE) )
5978 {
5979 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005980 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005981 }
5982 }
5983
Jeff Johnsone7245742012-09-05 17:12:55 -07005984done:
Jeff Johnson295189b2012-06-20 16:38:30 -07005985 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305986 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005987}
Jeff Johnson295189b2012-06-20 16:38:30 -07005988
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305989/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005990 * FUNCTION: wlan_hdd_validate_operation_channel
5991 * called by wlan_hdd_cfg80211_start_bss() and
5992 * wlan_hdd_cfg80211_set_channel()
5993 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305994 * channel list.
5995 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005996VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005997{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305998
Jeff Johnson295189b2012-06-20 16:38:30 -07005999 v_U32_t num_ch = 0;
6000 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6001 u32 indx = 0;
6002 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306003 v_U8_t fValidChannel = FALSE, count = 0;
6004 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306005
Jeff Johnson295189b2012-06-20 16:38:30 -07006006 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6007
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306008 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006009 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306010 /* Validate the channel */
6011 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006012 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306013 if ( channel == rfChannels[count].channelNum )
6014 {
6015 fValidChannel = TRUE;
6016 break;
6017 }
6018 }
6019 if (fValidChannel != TRUE)
6020 {
6021 hddLog(VOS_TRACE_LEVEL_ERROR,
6022 "%s: Invalid Channel [%d]", __func__, channel);
6023 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006024 }
6025 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306026 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006027 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306028 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6029 valid_ch, &num_ch))
6030 {
6031 hddLog(VOS_TRACE_LEVEL_ERROR,
6032 "%s: failed to get valid channel list", __func__);
6033 return VOS_STATUS_E_FAILURE;
6034 }
6035 for (indx = 0; indx < num_ch; indx++)
6036 {
6037 if (channel == valid_ch[indx])
6038 {
6039 break;
6040 }
6041 }
6042
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306043 if (indx >= num_ch)
6044 {
6045 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6046 {
6047 eCsrBand band;
6048 unsigned int freq;
6049
6050 sme_GetFreqBand(hHal, &band);
6051
6052 if (eCSR_BAND_5G == band)
6053 {
6054#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6055 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6056 {
6057 freq = ieee80211_channel_to_frequency(channel,
6058 IEEE80211_BAND_2GHZ);
6059 }
6060 else
6061 {
6062 freq = ieee80211_channel_to_frequency(channel,
6063 IEEE80211_BAND_5GHZ);
6064 }
6065#else
6066 freq = ieee80211_channel_to_frequency(channel);
6067#endif
6068 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6069 return VOS_STATUS_SUCCESS;
6070 }
6071 }
6072
6073 hddLog(VOS_TRACE_LEVEL_ERROR,
6074 "%s: Invalid Channel [%d]", __func__, channel);
6075 return VOS_STATUS_E_FAILURE;
6076 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006077 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306078
Jeff Johnson295189b2012-06-20 16:38:30 -07006079 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306080
Jeff Johnson295189b2012-06-20 16:38:30 -07006081}
6082
Viral Modi3a32cc52013-02-08 11:14:52 -08006083/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306084 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08006085 * This function is used to set the channel number
6086 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306087static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08006088 struct ieee80211_channel *chan,
6089 enum nl80211_channel_type channel_type
6090 )
6091{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306092 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006093 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006094 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006095 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306096 hdd_context_t *pHddCtx;
6097 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006098
6099 ENTER();
6100
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306101
Viral Modi3a32cc52013-02-08 11:14:52 -08006102 if( NULL == dev )
6103 {
6104 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006105 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006106 return -ENODEV;
6107 }
6108 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306109
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306110 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6111 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6112 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006113 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306114 "%s: device_mode = %s (%d) freq = %d", __func__,
6115 hdd_device_modetoString(pAdapter->device_mode),
6116 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306117
6118 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6119 status = wlan_hdd_validate_context(pHddCtx);
6120
6121 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006122 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6124 "%s: HDD context is not valid", __func__);
6125 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006126 }
6127
6128 /*
6129 * Do freq to chan conversion
6130 * TODO: for 11a
6131 */
6132
6133 channel = ieee80211_frequency_to_channel(freq);
6134
6135 /* Check freq range */
6136 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6137 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6138 {
6139 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006140 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006141 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6142 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6143 return -EINVAL;
6144 }
6145
6146 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6147
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306148 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6149 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006150 {
6151 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6152 {
6153 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006154 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006155 return -EINVAL;
6156 }
6157 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6158 "%s: set channel to [%d] for device mode =%d",
6159 __func__, channel,pAdapter->device_mode);
6160 }
6161 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006162 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006163 )
6164 {
6165 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6166 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6167 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6168
6169 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6170 {
6171 /* Link is up then return cant set channel*/
6172 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006173 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006174 return -EINVAL;
6175 }
6176
6177 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6178 pHddStaCtx->conn_info.operationChannel = channel;
6179 pRoamProfile->ChannelInfo.ChannelList =
6180 &pHddStaCtx->conn_info.operationChannel;
6181 }
6182 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006183 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006184 )
6185 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306186 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6187 {
6188 if(VOS_STATUS_SUCCESS !=
6189 wlan_hdd_validate_operation_channel(pAdapter,channel))
6190 {
6191 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006192 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306193 return -EINVAL;
6194 }
6195 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6196 }
6197 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006198 {
6199 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6200
6201 /* If auto channel selection is configured as enable/ 1 then ignore
6202 channel set by supplicant
6203 */
6204 if ( cfg_param->apAutoChannelSelection )
6205 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306206 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6207 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006208 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306209 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6210 __func__, hdd_device_modetoString(pAdapter->device_mode),
6211 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006212 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306213 else
6214 {
6215 if(VOS_STATUS_SUCCESS !=
6216 wlan_hdd_validate_operation_channel(pAdapter,channel))
6217 {
6218 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006219 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306220 return -EINVAL;
6221 }
6222 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6223 }
Viral Modi3a32cc52013-02-08 11:14:52 -08006224 }
6225 }
6226 else
6227 {
6228 hddLog(VOS_TRACE_LEVEL_FATAL,
6229 "%s: Invalid device mode failed to set valid channel", __func__);
6230 return -EINVAL;
6231 }
6232 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306233 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006234}
6235
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306236static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
6237 struct net_device *dev,
6238 struct ieee80211_channel *chan,
6239 enum nl80211_channel_type channel_type
6240 )
6241{
6242 int ret;
6243
6244 vos_ssr_protect(__func__);
6245 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
6246 vos_ssr_unprotect(__func__);
6247
6248 return ret;
6249}
6250
Jeff Johnson295189b2012-06-20 16:38:30 -07006251#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6252static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6253 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006254#else
6255static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6256 struct cfg80211_beacon_data *params,
6257 const u8 *ssid, size_t ssid_len,
6258 enum nl80211_hidden_ssid hidden_ssid)
6259#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006260{
6261 tsap_Config_t *pConfig;
6262 beacon_data_t *pBeacon = NULL;
6263 struct ieee80211_mgmt *pMgmt_frame;
6264 v_U8_t *pIe=NULL;
6265 v_U16_t capab_info;
6266 eCsrAuthType RSNAuthType;
6267 eCsrEncryptionType RSNEncryptType;
6268 eCsrEncryptionType mcRSNEncryptType;
6269 int status = VOS_STATUS_SUCCESS;
6270 tpWLAN_SAPEventCB pSapEventCallback;
6271 hdd_hostapd_state_t *pHostapdState;
6272 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
6273 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306274 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006275 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306276 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07006277 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08006278 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05306279 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07006280 v_BOOL_t MFPCapable = VOS_FALSE;
6281 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306282 eHddDot11Mode sapDot11Mode =
6283 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07006284
6285 ENTER();
6286
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306287 iniConfig = pHddCtx->cfg_ini;
6288
Jeff Johnson295189b2012-06-20 16:38:30 -07006289 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
6290
6291 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6292
6293 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6294
6295 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6296
6297 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
6298
6299 //channel is already set in the set_channel Call back
6300 //pConfig->channel = pCommitConfig->channel;
6301
6302 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306303 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07006304 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
6305
6306 pConfig->dtim_period = pBeacon->dtim_period;
6307
Arif Hussain6d2a3322013-11-17 19:50:10 -08006308 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07006309 pConfig->dtim_period);
6310
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08006311 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07006312 {
6313 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006314 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05306315 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
6316 {
6317 tANI_BOOLEAN restartNeeded;
6318 pConfig->ieee80211d = 1;
6319 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
6320 sme_setRegInfo(hHal, pConfig->countryCode);
6321 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
6322 }
6323 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006324 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07006325 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07006326 pConfig->ieee80211d = 1;
6327 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
6328 sme_setRegInfo(hHal, pConfig->countryCode);
6329 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07006330 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006331 else
6332 {
6333 pConfig->ieee80211d = 0;
6334 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306335 /*
6336 * If auto channel is configured i.e. channel is 0,
6337 * so skip channel validation.
6338 */
6339 if( AUTO_CHANNEL_SELECT != pConfig->channel )
6340 {
6341 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
6342 {
6343 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006344 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306345 return -EINVAL;
6346 }
6347 }
6348 else
6349 {
6350 if(1 != pHddCtx->is_dynamic_channel_range_set)
6351 {
6352 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
6353 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
6354 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
6355 }
6356 pHddCtx->is_dynamic_channel_range_set = 0;
6357 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006358 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006359 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006360 {
6361 pConfig->ieee80211d = 0;
6362 }
6363 pConfig->authType = eSAP_AUTO_SWITCH;
6364
6365 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306366
6367 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07006368 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
6369
6370 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
6371
6372 /*Set wps station to configured*/
6373 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
6374
6375 if(pIe)
6376 {
6377 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
6378 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006379 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07006380 return -EINVAL;
6381 }
6382 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
6383 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006384 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07006385 /* Check 15 bit of WPS IE as it contain information for wps state
6386 * WPS state
6387 */
6388 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
6389 {
6390 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
6391 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
6392 {
6393 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
6394 }
6395 }
6396 }
6397 else
6398 {
6399 pConfig->wps_state = SAP_WPS_DISABLED;
6400 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306401 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07006402
c_hpothufe599e92014-06-16 11:38:55 +05306403 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6404 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6405 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
6406 eCSR_ENCRYPT_TYPE_NONE;
6407
Jeff Johnson295189b2012-06-20 16:38:30 -07006408 pConfig->RSNWPAReqIELength = 0;
6409 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306410 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006411 WLAN_EID_RSN);
6412 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306413 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006414 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6415 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6416 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306417 /* The actual processing may eventually be more extensive than
6418 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07006419 * by the app.
6420 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306421 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006422 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6423 &RSNEncryptType,
6424 &mcRSNEncryptType,
6425 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006426 &MFPCapable,
6427 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006428 pConfig->pRSNWPAReqIE[1]+2,
6429 pConfig->pRSNWPAReqIE );
6430
6431 if( VOS_STATUS_SUCCESS == status )
6432 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306433 /* Now copy over all the security attributes you have
6434 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006435 * */
6436 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6437 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6438 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6439 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306440 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006441 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006442 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6443 }
6444 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306445
Jeff Johnson295189b2012-06-20 16:38:30 -07006446 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6447 pBeacon->tail, pBeacon->tail_len);
6448
6449 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
6450 {
6451 if (pConfig->pRSNWPAReqIE)
6452 {
6453 /*Mixed mode WPA/WPA2*/
6454 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
6455 pConfig->RSNWPAReqIELength += pIe[1] + 2;
6456 }
6457 else
6458 {
6459 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6460 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6461 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306462 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006463 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6464 &RSNEncryptType,
6465 &mcRSNEncryptType,
6466 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006467 &MFPCapable,
6468 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006469 pConfig->pRSNWPAReqIE[1]+2,
6470 pConfig->pRSNWPAReqIE );
6471
6472 if( VOS_STATUS_SUCCESS == status )
6473 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306474 /* Now copy over all the security attributes you have
6475 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006476 * */
6477 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6478 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6479 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6480 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306481 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006482 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006483 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6484 }
6485 }
6486 }
6487
Jeff Johnson4416a782013-03-25 14:17:50 -07006488 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
6489 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
6490 return -EINVAL;
6491 }
6492
Jeff Johnson295189b2012-06-20 16:38:30 -07006493 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
6494
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006495#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006496 if (params->ssid != NULL)
6497 {
6498 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
6499 pConfig->SSIDinfo.ssid.length = params->ssid_len;
6500 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6501 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6502 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006503#else
6504 if (ssid != NULL)
6505 {
6506 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
6507 pConfig->SSIDinfo.ssid.length = ssid_len;
6508 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6509 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6510 }
6511#endif
6512
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306513 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07006514 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306515
Jeff Johnson295189b2012-06-20 16:38:30 -07006516 /* default value */
6517 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
6518 pConfig->num_accept_mac = 0;
6519 pConfig->num_deny_mac = 0;
6520
6521 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6522 pBeacon->tail, pBeacon->tail_len);
6523
6524 /* pIe for black list is following form:
6525 type : 1 byte
6526 length : 1 byte
6527 OUI : 4 bytes
6528 acl type : 1 byte
6529 no of mac addr in black list: 1 byte
6530 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306531 */
6532 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006533 {
6534 pConfig->SapMacaddr_acl = pIe[6];
6535 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006536 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006537 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306538 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
6539 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006540 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6541 for (i = 0; i < pConfig->num_deny_mac; i++)
6542 {
6543 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6544 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306545 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006546 }
6547 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6548 pBeacon->tail, pBeacon->tail_len);
6549
6550 /* pIe for white list is following form:
6551 type : 1 byte
6552 length : 1 byte
6553 OUI : 4 bytes
6554 acl type : 1 byte
6555 no of mac addr in white list: 1 byte
6556 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306557 */
6558 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006559 {
6560 pConfig->SapMacaddr_acl = pIe[6];
6561 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006562 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006563 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306564 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
6565 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006566 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6567 for (i = 0; i < pConfig->num_accept_mac; i++)
6568 {
6569 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6570 acl_entry++;
6571 }
6572 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306573
Jeff Johnson295189b2012-06-20 16:38:30 -07006574 wlan_hdd_set_sapHwmode(pHostapdAdapter);
6575
Jeff Johnsone7245742012-09-05 17:12:55 -07006576#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006577 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05306578 * This is valid only if mode is set to 11n in hostapd, either AUTO or
6579 * 11ac in .ini and 11ac is supported by both host and firmware.
6580 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
6581 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006582 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
6583 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306584 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
6585 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
6586 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
6587 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
6588 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07006589 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306590 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07006591 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306592 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006593
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306594 /* If ACS disable and selected channel <= 14
6595 * OR
6596 * ACS enabled and ACS operating band is choosen as 2.4
6597 * AND
6598 * VHT in 2.4G Disabled
6599 * THEN
6600 * Fallback to 11N mode
6601 */
6602 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
6603 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05306604 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306605 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006606 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306607 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
6608 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006609 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
6610 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006611 }
6612#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306613
Jeff Johnson295189b2012-06-20 16:38:30 -07006614 // ht_capab is not what the name conveys,this is used for protection bitmap
6615 pConfig->ht_capab =
6616 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
6617
6618 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
6619 {
6620 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
6621 return -EINVAL;
6622 }
6623
6624 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306625 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07006626 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
6627 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306628 pConfig->obssProtEnabled =
6629 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07006630
Chet Lanctot8cecea22014-02-11 19:09:36 -08006631#ifdef WLAN_FEATURE_11W
6632 pConfig->mfpCapable = MFPCapable;
6633 pConfig->mfpRequired = MFPRequired;
6634 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
6635 pConfig->mfpCapable, pConfig->mfpRequired);
6636#endif
6637
Arif Hussain6d2a3322013-11-17 19:50:10 -08006638 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07006639 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006640 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
6641 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
6642 (int)pConfig->channel);
6643 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
6644 pConfig->SapHw_mode, pConfig->privacy,
6645 pConfig->authType);
6646 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
6647 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
6648 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
6649 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07006650
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306651 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006652 {
6653 //Bss already started. just return.
6654 //TODO Probably it should update some beacon params.
6655 hddLog( LOGE, "Bss Already started...Ignore the request");
6656 EXIT();
6657 return 0;
6658 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306659
Agarwal Ashish51325b52014-06-16 16:50:49 +05306660 if (vos_max_concurrent_connections_reached()) {
6661 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6662 return -EINVAL;
6663 }
6664
Jeff Johnson295189b2012-06-20 16:38:30 -07006665 pConfig->persona = pHostapdAdapter->device_mode;
6666
Peng Xu2446a892014-09-05 17:21:18 +05306667 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
6668 if ( NULL != psmeConfig)
6669 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05306670 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05306671 sme_GetConfigParam(hHal, psmeConfig);
6672 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05306673#ifdef WLAN_FEATURE_AP_HT40_24G
6674 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
6675 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
6676 && pHddCtx->cfg_ini->apHT40_24GEnabled)
6677 {
6678 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
6679 sme_UpdateConfig (hHal, psmeConfig);
6680 }
6681#endif
Peng Xu2446a892014-09-05 17:21:18 +05306682 vos_mem_free(psmeConfig);
6683 }
Peng Xuafc34e32014-09-25 13:23:55 +05306684 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05306685
Jeff Johnson295189b2012-06-20 16:38:30 -07006686 pSapEventCallback = hdd_hostapd_SAPEventCB;
6687 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
6688 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
6689 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006690 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006691 return -EINVAL;
6692 }
6693
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306694 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07006695 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
6696
6697 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306698
Jeff Johnson295189b2012-06-20 16:38:30 -07006699 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306700 {
6701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006702 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07006703 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07006704 VOS_ASSERT(0);
6705 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306706
Jeff Johnson295189b2012-06-20 16:38:30 -07006707 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05306708 /* Initialize WMM configuation */
6709 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306710 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006711
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006712#ifdef WLAN_FEATURE_P2P_DEBUG
6713 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
6714 {
6715 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
6716 {
6717 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6718 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006719 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006720 }
6721 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
6722 {
6723 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6724 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006725 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006726 }
6727 }
6728#endif
6729
Jeff Johnson295189b2012-06-20 16:38:30 -07006730 pHostapdState->bCommit = TRUE;
6731 EXIT();
6732
6733 return 0;
6734}
6735
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006736#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05306737static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306738 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006739 struct beacon_parameters *params)
6740{
6741 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306742 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306743 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006744
6745 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306746
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306747 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6748 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
6749 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306750 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
6751 hdd_device_modetoString(pAdapter->device_mode),
6752 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006753
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306754 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6755 status = wlan_hdd_validate_context(pHddCtx);
6756
6757 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006758 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6760 "%s: HDD context is not valid", __func__);
6761 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006762 }
6763
Agarwal Ashish51325b52014-06-16 16:50:49 +05306764 if (vos_max_concurrent_connections_reached()) {
6765 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6766 return -EINVAL;
6767 }
6768
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306769 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006770 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006771 )
6772 {
6773 beacon_data_t *old,*new;
6774
6775 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306776
Jeff Johnson295189b2012-06-20 16:38:30 -07006777 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306778 {
6779 hddLog(VOS_TRACE_LEVEL_WARN,
6780 FL("already beacon info added to session(%d)"),
6781 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006782 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306783 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006784
6785 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6786
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306787 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07006788 {
6789 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006790 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006791 return -EINVAL;
6792 }
6793
6794 pAdapter->sessionCtx.ap.beacon = new;
6795
6796 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6797 }
6798
6799 EXIT();
6800 return status;
6801}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306802
Mukul Sharmab0e0a982014-12-15 18:58:53 +05306803static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
6804 struct net_device *dev,
6805 struct beacon_parameters *params)
6806{
6807 int ret;
6808
6809 vos_ssr_protect(__func__);
6810 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
6811 vos_ssr_unprotect(__func__);
6812
6813 return ret;
6814}
6815
6816static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006817 struct net_device *dev,
6818 struct beacon_parameters *params)
6819{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306820 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306821 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6822 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306823 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006824
6825 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306826 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6827 TRACE_CODE_HDD_CFG80211_SET_BEACON,
6828 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
6829 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6830 __func__, hdd_device_modetoString(pAdapter->device_mode),
6831 pAdapter->device_mode);
6832
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306833 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6834 status = wlan_hdd_validate_context(pHddCtx);
6835
6836 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006837 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6839 "%s: HDD context is not valid", __func__);
6840 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006841 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306842
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306843 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006844 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306845 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006846 {
6847 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306848
Jeff Johnson295189b2012-06-20 16:38:30 -07006849 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306850
Jeff Johnson295189b2012-06-20 16:38:30 -07006851 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306852 {
6853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6854 FL("session(%d) old and new heads points to NULL"),
6855 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006856 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306857 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006858
6859 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6860
6861 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306862 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006863 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006864 return -EINVAL;
6865 }
6866
6867 pAdapter->sessionCtx.ap.beacon = new;
6868
6869 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6870 }
6871
6872 EXIT();
6873 return status;
6874}
6875
Mukul Sharmab0e0a982014-12-15 18:58:53 +05306876static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
6877 struct net_device *dev,
6878 struct beacon_parameters *params)
6879{
6880 int ret;
6881
6882 vos_ssr_protect(__func__);
6883 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
6884 vos_ssr_unprotect(__func__);
6885
6886 return ret;
6887}
6888
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006889#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6890
6891#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05306892static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006893 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006894#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05306895static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006896 struct net_device *dev)
6897#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006898{
6899 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07006900 hdd_context_t *pHddCtx = NULL;
6901 hdd_scaninfo_t *pScanInfo = NULL;
6902 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306903 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306904 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006905
6906 ENTER();
6907
6908 if (NULL == pAdapter)
6909 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006911 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006912 return -ENODEV;
6913 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006914
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306915 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6916 TRACE_CODE_HDD_CFG80211_STOP_AP,
6917 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306918 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6919 status = wlan_hdd_validate_context(pHddCtx);
6920
6921 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006922 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306923 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6924 "%s: HDD context is not valid", __func__);
6925 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07006926 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006927
6928 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
6929 if (NULL == staAdapter)
6930 {
6931 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
6932 if (NULL == staAdapter)
6933 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07006934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6935 "%s: HDD adapter context for STA/P2P-CLI is Null",
6936 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006937 }
6938 }
6939
6940 pScanInfo = &pHddCtx->scan_info;
6941
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306942 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6943 __func__, hdd_device_modetoString(pAdapter->device_mode),
6944 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006945
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306946 ret = wlan_hdd_scan_abort(pAdapter);
6947
Girish Gowli4bf7a632014-06-12 13:42:11 +05306948 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07006949 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6951 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306952
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306953 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07006954 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306955 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6956 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08006957
Jeff Johnsone7245742012-09-05 17:12:55 -07006958 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306959 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07006960 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306961 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07006962 }
6963
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05306964 /* Delete all associated STAs before stopping AP/P2P GO */
6965 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05306966 hdd_hostapd_stop(dev);
6967
Jeff Johnson295189b2012-06-20 16:38:30 -07006968 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006969 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006970 )
6971 {
6972 beacon_data_t *old;
6973
6974 old = pAdapter->sessionCtx.ap.beacon;
6975
6976 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306977 {
6978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6979 FL("session(%d) beacon data points to NULL"),
6980 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006981 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306982 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006983
Jeff Johnson295189b2012-06-20 16:38:30 -07006984 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006985
6986 mutex_lock(&pHddCtx->sap_lock);
6987 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6988 {
Jeff Johnson4416a782013-03-25 14:17:50 -07006989 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006990 {
6991 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6992
6993 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6994
6995 if (!VOS_IS_STATUS_SUCCESS(status))
6996 {
6997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006998 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006999 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307000 }
7001 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007002 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307003 /* BSS stopped, clear the active sessions for this device mode */
7004 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007005 }
7006 mutex_unlock(&pHddCtx->sap_lock);
7007
7008 if(status != VOS_STATUS_SUCCESS)
7009 {
7010 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007011 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007012 return -EINVAL;
7013 }
7014
Jeff Johnson4416a782013-03-25 14:17:50 -07007015 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007016 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
7017 ==eHAL_STATUS_FAILURE)
7018 {
7019 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007020 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007021 }
7022
Jeff Johnson4416a782013-03-25 14:17:50 -07007023 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007024 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7025 eANI_BOOLEAN_FALSE) )
7026 {
7027 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007028 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007029 }
7030
7031 // Reset WNI_CFG_PROBE_RSP Flags
7032 wlan_hdd_reset_prob_rspies(pAdapter);
7033
7034 pAdapter->sessionCtx.ap.beacon = NULL;
7035 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007036#ifdef WLAN_FEATURE_P2P_DEBUG
7037 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7038 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
7039 {
7040 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
7041 "GO got removed");
7042 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
7043 }
7044#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007045 }
7046 EXIT();
7047 return status;
7048}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007049
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307050#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7051static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
7052 struct net_device *dev)
7053{
7054 int ret;
7055
7056 vos_ssr_protect(__func__);
7057 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
7058 vos_ssr_unprotect(__func__);
7059
7060 return ret;
7061}
7062#else
7063static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7064 struct net_device *dev)
7065{
7066 int ret;
7067
7068 vos_ssr_protect(__func__);
7069 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7070 vos_ssr_unprotect(__func__);
7071
7072 return ret;
7073}
7074#endif
7075
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007076#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7077
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307078static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307079 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007080 struct cfg80211_ap_settings *params)
7081{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307082 hdd_adapter_t *pAdapter;
7083 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307084 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007085
7086 ENTER();
7087
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307088 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007089 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307090 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307091 "%s: Device is Null", __func__);
7092 return -ENODEV;
7093 }
7094
7095 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7096 if (NULL == pAdapter)
7097 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307099 "%s: HDD adapter is Null", __func__);
7100 return -ENODEV;
7101 }
7102
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307103 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7104 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
7105 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307106 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7107 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307109 "%s: HDD adapter magic is invalid", __func__);
7110 return -ENODEV;
7111 }
7112
7113 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307114 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307115
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307116 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307117 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7119 "%s: HDD context is not valid", __func__);
7120 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307121 }
7122
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307123 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7124 __func__, hdd_device_modetoString(pAdapter->device_mode),
7125 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307126
7127 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007128 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007129 )
7130 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307131 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007132
7133 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307134
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007135 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307136 {
7137 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7138 FL("already beacon info added to session(%d)"),
7139 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007140 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307141 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007142
7143 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
7144
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307145 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007146 {
7147 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307148 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007149 return -EINVAL;
7150 }
7151 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007152#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007153 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7154#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7155 params->channel, params->channel_type);
7156#else
7157 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7158#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007159#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007160 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
7161 params->ssid_len, params->hidden_ssid);
7162 }
7163
7164 EXIT();
7165 return status;
7166}
7167
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307168static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7169 struct net_device *dev,
7170 struct cfg80211_ap_settings *params)
7171{
7172 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007173
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307174 vos_ssr_protect(__func__);
7175 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
7176 vos_ssr_unprotect(__func__);
7177
7178 return ret;
7179}
7180
7181static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007182 struct net_device *dev,
7183 struct cfg80211_beacon_data *params)
7184{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307185 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307186 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307187 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007188
7189 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307190
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307191 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7192 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7193 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007194 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007195 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307196
7197 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7198 status = wlan_hdd_validate_context(pHddCtx);
7199
7200 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007201 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7203 "%s: HDD context is not valid", __func__);
7204 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007205 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007206
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307207 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007208 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307209 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007210 {
7211 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307212
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007213 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307214
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007215 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307216 {
7217 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7218 FL("session(%d) beacon data points to NULL"),
7219 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007220 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307221 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007222
7223 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
7224
7225 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307226 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007227 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007228 return -EINVAL;
7229 }
7230
7231 pAdapter->sessionCtx.ap.beacon = new;
7232
7233 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
7234 }
7235
7236 EXIT();
7237 return status;
7238}
7239
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307240static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
7241 struct net_device *dev,
7242 struct cfg80211_beacon_data *params)
7243{
7244 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007245
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307246 vos_ssr_protect(__func__);
7247 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
7248 vos_ssr_unprotect(__func__);
7249
7250 return ret;
7251}
7252
7253#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007254
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307255static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007256 struct net_device *dev,
7257 struct bss_parameters *params)
7258{
7259 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7260
7261 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307262
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307263 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7264 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
7265 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307266 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7267 __func__, hdd_device_modetoString(pAdapter->device_mode),
7268 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007269
7270 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007271 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307272 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007273 {
7274 /* ap_isolate == -1 means that in change bss, upper layer doesn't
7275 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307276 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07007277 {
7278 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307279 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007280 }
7281
7282 EXIT();
7283 return 0;
7284}
7285
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307286static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
7287 struct net_device *dev,
7288 struct bss_parameters *params)
7289{
7290 int ret;
7291
7292 vos_ssr_protect(__func__);
7293 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
7294 vos_ssr_unprotect(__func__);
7295
7296 return ret;
7297}
Kiet Lam10841362013-11-01 11:36:50 +05307298/* FUNCTION: wlan_hdd_change_country_code_cd
7299* to wait for contry code completion
7300*/
7301void* wlan_hdd_change_country_code_cb(void *pAdapter)
7302{
7303 hdd_adapter_t *call_back_pAdapter = pAdapter;
7304 complete(&call_back_pAdapter->change_country_code);
7305 return NULL;
7306}
7307
Jeff Johnson295189b2012-06-20 16:38:30 -07007308/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307309 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07007310 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
7311 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307312int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007313 struct net_device *ndev,
7314 enum nl80211_iftype type,
7315 u32 *flags,
7316 struct vif_params *params
7317 )
7318{
7319 struct wireless_dev *wdev;
7320 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007321 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07007322 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007323 tCsrRoamProfile *pRoamProfile = NULL;
7324 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307325 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007326 eMib_dot11DesiredBssType connectedBssType;
7327 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307328 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007329
7330 ENTER();
7331
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307332 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007333 {
7334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7335 "%s: Adapter context is null", __func__);
7336 return VOS_STATUS_E_FAILURE;
7337 }
7338
7339 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7340 if (!pHddCtx)
7341 {
7342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7343 "%s: HDD context is null", __func__);
7344 return VOS_STATUS_E_FAILURE;
7345 }
7346
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307347 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7348 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
7349 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307350 status = wlan_hdd_validate_context(pHddCtx);
7351
7352 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007353 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307354 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7355 "%s: HDD context is not valid", __func__);
7356 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007357 }
7358
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307359 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7360 __func__, hdd_device_modetoString(pAdapter->device_mode),
7361 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007362
Agarwal Ashish51325b52014-06-16 16:50:49 +05307363 if (vos_max_concurrent_connections_reached()) {
7364 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7365 return -EINVAL;
7366 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307367 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007368 wdev = ndev->ieee80211_ptr;
7369
7370#ifdef WLAN_BTAMP_FEATURE
7371 if((NL80211_IFTYPE_P2P_CLIENT == type)||
7372 (NL80211_IFTYPE_ADHOC == type)||
7373 (NL80211_IFTYPE_AP == type)||
7374 (NL80211_IFTYPE_P2P_GO == type))
7375 {
7376 pHddCtx->isAmpAllowed = VOS_FALSE;
7377 // stop AMP traffic
7378 status = WLANBAP_StopAmp();
7379 if(VOS_STATUS_SUCCESS != status )
7380 {
7381 pHddCtx->isAmpAllowed = VOS_TRUE;
7382 hddLog(VOS_TRACE_LEVEL_FATAL,
7383 "%s: Failed to stop AMP", __func__);
7384 return -EINVAL;
7385 }
7386 }
7387#endif //WLAN_BTAMP_FEATURE
7388 /* Reset the current device mode bit mask*/
7389 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7390
7391 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007392 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07007393 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07007394 )
7395 {
7396 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007397 if (!pWextState)
7398 {
7399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7400 "%s: pWextState is null", __func__);
7401 return VOS_STATUS_E_FAILURE;
7402 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007403 pRoamProfile = &pWextState->roamProfile;
7404 LastBSSType = pRoamProfile->BSSType;
7405
7406 switch (type)
7407 {
7408 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007409 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007410 hddLog(VOS_TRACE_LEVEL_INFO,
7411 "%s: setting interface Type to INFRASTRUCTURE", __func__);
7412 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07007413#ifdef WLAN_FEATURE_11AC
7414 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
7415 {
7416 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
7417 }
7418#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307419 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07007420 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007421 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007422 //Check for sub-string p2p to confirm its a p2p interface
7423 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307424 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007425 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7426 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7427 }
7428 else
7429 {
7430 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007431 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007432 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05307433#ifdef FEATURE_WLAN_TDLS
7434 /* The open adapter for the p2p shall skip initializations in
7435 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
7436 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
7437 * tdls_init when the change_iface sets the device mode to
7438 * WLAN_HDD_P2P_CLIENT.
7439 */
7440
7441 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
7442 {
Agarwal Ashish4b87f922014-06-18 03:03:21 +05307443 if (0 != wlan_hdd_sta_tdls_init (pAdapter))
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05307444 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307445 hddLog(VOS_TRACE_LEVEL_ERROR,
7446 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05307447 return -EINVAL;
7448 }
7449 }
7450#endif
7451
Jeff Johnson295189b2012-06-20 16:38:30 -07007452 break;
7453 case NL80211_IFTYPE_ADHOC:
7454 hddLog(VOS_TRACE_LEVEL_INFO,
7455 "%s: setting interface Type to ADHOC", __func__);
7456 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
7457 pRoamProfile->phyMode =
7458 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07007459 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007460 wdev->iftype = type;
7461 break;
7462
7463 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007464 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007465 {
7466 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7467 "%s: setting interface Type to %s", __func__,
7468 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
7469
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007470 //Cancel any remain on channel for GO mode
7471 if (NL80211_IFTYPE_P2P_GO == type)
7472 {
7473 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
7474 }
Mohit Khanna0f232092012-09-11 14:46:08 -07007475 if (NL80211_IFTYPE_AP == type)
7476 {
7477 /* As Loading WLAN Driver one interface being created for p2p device
7478 * address. This will take one HW STA and the max number of clients
7479 * that can connect to softAP will be reduced by one. so while changing
7480 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
7481 * interface as it is not required in SoftAP mode.
7482 */
7483
7484 // Get P2P Adapter
7485 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
7486
7487 if (pP2pAdapter)
7488 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307489 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07007490 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
7491 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
7492 }
7493 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05307494 //Disable IMPS & BMPS for SAP/GO
7495 if(VOS_STATUS_E_FAILURE ==
7496 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
7497 {
7498 //Fail to Exit BMPS
7499 VOS_ASSERT(0);
7500 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05307501
7502 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
7503
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307504#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07007505
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307506 /* A Mutex Lock is introduced while changing the mode to
7507 * protect the concurrent access for the Adapters by TDLS
7508 * module.
7509 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307510 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307511#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007512 //De-init the adapter.
Jeff Johnson295189b2012-06-20 16:38:30 -07007513 hdd_deinit_adapter( pHddCtx, pAdapter );
7514 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07007515 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7516 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307517#ifdef FEATURE_WLAN_TDLS
7518 mutex_unlock(&pHddCtx->tdls_lock);
7519#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007520 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
7521 (pConfig->apRandomBssidEnabled))
7522 {
7523 /* To meet Android requirements create a randomized
7524 MAC address of the form 02:1A:11:Fx:xx:xx */
7525 get_random_bytes(&ndev->dev_addr[3], 3);
7526 ndev->dev_addr[0] = 0x02;
7527 ndev->dev_addr[1] = 0x1A;
7528 ndev->dev_addr[2] = 0x11;
7529 ndev->dev_addr[3] |= 0xF0;
7530 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
7531 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08007532 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
7533 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007534 }
7535
Jeff Johnson295189b2012-06-20 16:38:30 -07007536 hdd_set_ap_ops( pAdapter->dev );
7537
Kiet Lam10841362013-11-01 11:36:50 +05307538 /* This is for only SAP mode where users can
7539 * control country through ini.
7540 * P2P GO follows station country code
7541 * acquired during the STA scanning. */
7542 if((NL80211_IFTYPE_AP == type) &&
7543 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
7544 {
7545 int status = 0;
7546 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
7547 "%s: setting country code from INI ", __func__);
7548 init_completion(&pAdapter->change_country_code);
7549 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
7550 (void *)(tSmeChangeCountryCallback)
7551 wlan_hdd_change_country_code_cb,
7552 pConfig->apCntryCode, pAdapter,
7553 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05307554 eSIR_FALSE,
7555 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05307556 if (eHAL_STATUS_SUCCESS == status)
7557 {
7558 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307559 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05307560 &pAdapter->change_country_code,
7561 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307562 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05307563 {
7564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307565 FL("SME Timed out while setting country code %ld"),
7566 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08007567
7568 if (pHddCtx->isLogpInProgress)
7569 {
7570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7571 "%s: LOGP in Progress. Ignore!!!", __func__);
7572 return -EAGAIN;
7573 }
Kiet Lam10841362013-11-01 11:36:50 +05307574 }
7575 }
7576 else
7577 {
7578 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007579 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05307580 return -EINVAL;
7581 }
7582 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007583 status = hdd_init_ap_mode(pAdapter);
7584 if(status != VOS_STATUS_SUCCESS)
7585 {
7586 hddLog(VOS_TRACE_LEVEL_FATAL,
7587 "%s: Error initializing the ap mode", __func__);
7588 return -EINVAL;
7589 }
7590 hdd_set_conparam(1);
7591
Jeff Johnson295189b2012-06-20 16:38:30 -07007592 /*interface type changed update in wiphy structure*/
7593 if(wdev)
7594 {
7595 wdev->iftype = type;
7596 pHddCtx->change_iface = type;
7597 }
7598 else
7599 {
7600 hddLog(VOS_TRACE_LEVEL_ERROR,
7601 "%s: ERROR !!!! Wireless dev is NULL", __func__);
7602 return -EINVAL;
7603 }
7604 goto done;
7605 }
7606
7607 default:
7608 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7609 __func__);
7610 return -EOPNOTSUPP;
7611 }
7612 }
7613 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007614 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007615 )
7616 {
7617 switch(type)
7618 {
7619 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007620 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007621 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05307622
7623 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307624#ifdef FEATURE_WLAN_TDLS
7625
7626 /* A Mutex Lock is introduced while changing the mode to
7627 * protect the concurrent access for the Adapters by TDLS
7628 * module.
7629 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307630 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307631#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07007632 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007633 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007634 //Check for sub-string p2p to confirm its a p2p interface
7635 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007636 {
7637 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7638 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7639 }
7640 else
7641 {
7642 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007643 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007644 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007645 hdd_set_conparam(0);
7646 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007647 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
7648 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307649#ifdef FEATURE_WLAN_TDLS
7650 mutex_unlock(&pHddCtx->tdls_lock);
7651#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05307652 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007653 if( VOS_STATUS_SUCCESS != status )
7654 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07007655 /* In case of JB, for P2P-GO, only change interface will be called,
7656 * This is the right place to enable back bmps_imps()
7657 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307658 if (pHddCtx->hdd_wlan_suspended)
7659 {
7660 hdd_set_pwrparams(pHddCtx);
7661 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007662 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007663 goto done;
7664 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007665 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007666 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007667 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7668 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007669 goto done;
7670 default:
7671 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7672 __func__);
7673 return -EOPNOTSUPP;
7674
7675 }
7676
7677 }
7678 else
7679 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307680 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
7681 __func__, hdd_device_modetoString(pAdapter->device_mode),
7682 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007683 return -EOPNOTSUPP;
7684 }
7685
7686
7687 if(pRoamProfile)
7688 {
7689 if ( LastBSSType != pRoamProfile->BSSType )
7690 {
7691 /*interface type changed update in wiphy structure*/
7692 wdev->iftype = type;
7693
7694 /*the BSS mode changed, We need to issue disconnect
7695 if connected or in IBSS disconnect state*/
7696 if ( hdd_connGetConnectedBssType(
7697 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
7698 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
7699 {
7700 /*need to issue a disconnect to CSR.*/
7701 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7702 if( eHAL_STATUS_SUCCESS ==
7703 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
7704 pAdapter->sessionId,
7705 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
7706 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307707 ret = wait_for_completion_interruptible_timeout(
7708 &pAdapter->disconnect_comp_var,
7709 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7710 if (ret <= 0)
7711 {
7712 hddLog(VOS_TRACE_LEVEL_ERROR,
7713 FL("wait on disconnect_comp_var failed %ld"), ret);
7714 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007715 }
7716 }
7717 }
7718 }
7719
7720done:
7721 /*set bitmask based on updated value*/
7722 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07007723
7724 /* Only STA mode support TM now
7725 * all other mode, TM feature should be disabled */
7726 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
7727 (~VOS_STA & pHddCtx->concurrency_mode) )
7728 {
7729 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
7730 }
7731
Jeff Johnson295189b2012-06-20 16:38:30 -07007732#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307733 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05307734 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07007735 {
7736 //we are ok to do AMP
7737 pHddCtx->isAmpAllowed = VOS_TRUE;
7738 }
7739#endif //WLAN_BTAMP_FEATURE
7740 EXIT();
7741 return 0;
7742}
7743
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307744/*
7745 * FUNCTION: wlan_hdd_cfg80211_change_iface
7746 * wrapper function to protect the actual implementation from SSR.
7747 */
7748int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
7749 struct net_device *ndev,
7750 enum nl80211_iftype type,
7751 u32 *flags,
7752 struct vif_params *params
7753 )
7754{
7755 int ret;
7756
7757 vos_ssr_protect(__func__);
7758 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
7759 vos_ssr_unprotect(__func__);
7760
7761 return ret;
7762}
7763
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007764#ifdef FEATURE_WLAN_TDLS
7765static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
7766 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
7767{
7768 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7769 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7770 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007771 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307772 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307773 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007774
7775 ENTER();
7776
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307777 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007778 {
7779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7780 "Invalid arguments");
7781 return -EINVAL;
7782 }
Hoonki Lee27511902013-03-14 18:19:06 -07007783
7784 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
7785 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
7786 {
7787 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7788 "%s: TDLS mode is disabled OR not enabled in FW."
7789 MAC_ADDRESS_STR " Request declined.",
7790 __func__, MAC_ADDR_ARRAY(mac));
7791 return -ENOTSUPP;
7792 }
7793
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007794 if (pHddCtx->isLogpInProgress)
7795 {
7796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7797 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05307798 wlan_hdd_tdls_set_link_status(pAdapter,
7799 mac,
7800 eTDLS_LINK_IDLE,
7801 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007802 return -EBUSY;
7803 }
7804
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05307805 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007806
7807 if ( NULL == pTdlsPeer ) {
7808 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7809 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
7810 __func__, MAC_ADDR_ARRAY(mac), update);
7811 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007812 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007813
7814 /* in add station, we accept existing valid staId if there is */
7815 if ((0 == update) &&
7816 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
7817 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007818 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007819 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007820 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007821 " link_status %d. staId %d. add station ignored.",
7822 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
7823 return 0;
7824 }
7825 /* in change station, we accept only when staId is valid */
7826 if ((1 == update) &&
7827 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
7828 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
7829 {
7830 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7831 "%s: " MAC_ADDRESS_STR
7832 " link status %d. staId %d. change station %s.",
7833 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
7834 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
7835 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007836 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007837
7838 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307839 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007840 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7842 "%s: " MAC_ADDRESS_STR
7843 " TDLS setup is ongoing. Request declined.",
7844 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07007845 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007846 }
7847
7848 /* first to check if we reached to maximum supported TDLS peer.
7849 TODO: for now, return -EPERM looks working fine,
7850 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307851 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
7852 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007853 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7855 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307856 " TDLS Max peer already connected. Request declined."
7857 " Num of peers (%d), Max allowed (%d).",
7858 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
7859 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007860 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007861 }
7862 else
7863 {
7864 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307865 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007866 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007867 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7869 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
7870 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007871 return -EPERM;
7872 }
7873 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007874 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05307875 wlan_hdd_tdls_set_link_status(pAdapter,
7876 mac,
7877 eTDLS_LINK_CONNECTING,
7878 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007879
Jeff Johnsond75fe012013-04-06 10:53:06 -07007880 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307881 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007882 {
7883 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7884 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007885 if(StaParams->htcap_present)
7886 {
7887 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7888 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
7889 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7890 "ht_capa->extended_capabilities: %0x",
7891 StaParams->HTCap.extendedHtCapInfo);
7892 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007893 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7894 "params->capability: %0x",StaParams->capability);
7895 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007896 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007897 if(StaParams->vhtcap_present)
7898 {
7899 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7900 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
7901 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
7902 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
7903 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007904 {
7905 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007906 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007907 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
7908 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7909 "[%d]: %x ", i, StaParams->supported_rates[i]);
7910 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07007911 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307912 else if ((1 == update) && (NULL == StaParams))
7913 {
7914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7915 "%s : update is true, but staParams is NULL. Error!", __func__);
7916 return -EPERM;
7917 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007918
7919 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
7920
7921 if (!update)
7922 {
7923 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7924 pAdapter->sessionId, mac);
7925 }
7926 else
7927 {
7928 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7929 pAdapter->sessionId, mac, StaParams);
7930 }
7931
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307932 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007933 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
7934
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307935 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007936 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007937 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307938 "%s: timeout waiting for tdls add station indication %ld",
7939 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007940 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007941 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307942
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007943 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
7944 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007946 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007947 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007948 }
7949
7950 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007951
7952error:
Atul Mittal115287b2014-07-08 13:26:33 +05307953 wlan_hdd_tdls_set_link_status(pAdapter,
7954 mac,
7955 eTDLS_LINK_IDLE,
7956 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007957 return -EPERM;
7958
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007959}
7960#endif
7961
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307962static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007963 struct net_device *dev,
7964 u8 *mac,
7965 struct station_parameters *params)
7966{
7967 VOS_STATUS status = VOS_STATUS_SUCCESS;
7968 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05307969 hdd_context_t *pHddCtx;
7970 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007971 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007972#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007973 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007974 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307975 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007976#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007977 ENTER();
7978
Gopichand Nakkala29149562013-05-10 21:43:41 +05307979 if ((NULL == pAdapter))
7980 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05307982 "invalid adapter ");
7983 return -EINVAL;
7984 }
7985
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307986 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7987 TRACE_CODE_HDD_CHANGE_STATION,
7988 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05307989 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7990 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7991
7992 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
7993 {
7994 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7995 "invalid HDD state or HDD station context");
7996 return -EINVAL;
7997 }
7998
7999 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008000 {
8001 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8002 "%s:LOGP in Progress. Ignore!!!", __func__);
8003 return -EAGAIN;
8004 }
8005
Jeff Johnson295189b2012-06-20 16:38:30 -07008006 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
8007
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008008 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8009 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07008010 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008011 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07008012 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308013 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07008014 WLANTL_STA_AUTHENTICATED);
8015
Gopichand Nakkala29149562013-05-10 21:43:41 +05308016 if (status != VOS_STATUS_SUCCESS)
8017 {
8018 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8019 "%s: Not able to change TL state to AUTHENTICATED", __func__);
8020 return -EINVAL;
8021 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008022 }
8023 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07008024 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8025 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308026#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008027 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8028 StaParams.capability = params->capability;
8029 StaParams.uapsd_queues = params->uapsd_queues;
8030 StaParams.max_sp = params->max_sp;
8031
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308032 /* Convert (first channel , number of channels) tuple to
8033 * the total list of channels. This goes with the assumption
8034 * that if the first channel is < 14, then the next channels
8035 * are an incremental of 1 else an incremental of 4 till the number
8036 * of channels.
8037 */
8038 if (0 != params->supported_channels_len) {
8039 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
8040 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
8041 {
8042 int wifi_chan_index;
8043 StaParams.supported_channels[j] = params->supported_channels[i];
8044 wifi_chan_index =
8045 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
8046 no_of_channels = params->supported_channels[i+1];
8047 for(k=1; k <= no_of_channels; k++)
8048 {
8049 StaParams.supported_channels[j+1] =
8050 StaParams.supported_channels[j] + wifi_chan_index;
8051 j+=1;
8052 }
8053 }
8054 StaParams.supported_channels_len = j;
8055 }
8056 vos_mem_copy(StaParams.supported_oper_classes,
8057 params->supported_oper_classes,
8058 params->supported_oper_classes_len);
8059 StaParams.supported_oper_classes_len =
8060 params->supported_oper_classes_len;
8061
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008062 if (0 != params->ext_capab_len)
8063 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
8064 sizeof(StaParams.extn_capability));
8065
8066 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008067 {
8068 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008069 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008070 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008071
8072 StaParams.supported_rates_len = params->supported_rates_len;
8073
8074 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
8075 * The supported_rates array , for all the structures propogating till Add Sta
8076 * to the firmware has to be modified , if the supplicant (ieee80211) is
8077 * modified to send more rates.
8078 */
8079
8080 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
8081 */
8082 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
8083 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
8084
8085 if (0 != StaParams.supported_rates_len) {
8086 int i = 0;
8087 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
8088 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008089 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008090 "Supported Rates with Length %d", StaParams.supported_rates_len);
8091 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008092 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008093 "[%d]: %0x", i, StaParams.supported_rates[i]);
8094 }
8095
8096 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008097 {
8098 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008099 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008100 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008101
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008102 if (0 != params->ext_capab_len ) {
8103 /*Define A Macro : TODO Sunil*/
8104 if ((1<<4) & StaParams.extn_capability[3]) {
8105 isBufSta = 1;
8106 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308107 /* TDLS Channel Switching Support */
8108 if ((1<<6) & StaParams.extn_capability[3]) {
8109 isOffChannelSupported = 1;
8110 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008111 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308112 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
8113 &StaParams, isBufSta,
8114 isOffChannelSupported);
8115
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308116 if (VOS_STATUS_SUCCESS != status) {
8117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8118 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
8119 return -EINVAL;
8120 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008121 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
8122
8123 if (VOS_STATUS_SUCCESS != status) {
8124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8125 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
8126 return -EINVAL;
8127 }
8128 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008129#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05308130 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008131 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008132 return status;
8133}
8134
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308135static int wlan_hdd_change_station(struct wiphy *wiphy,
8136 struct net_device *dev,
8137 u8 *mac,
8138 struct station_parameters *params)
8139{
8140 int ret;
8141
8142 vos_ssr_protect(__func__);
8143 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
8144 vos_ssr_unprotect(__func__);
8145
8146 return ret;
8147}
8148
Jeff Johnson295189b2012-06-20 16:38:30 -07008149/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308150 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008151 * This function is used to initialize the key information
8152 */
8153#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308154static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008155 struct net_device *ndev,
8156 u8 key_index, bool pairwise,
8157 const u8 *mac_addr,
8158 struct key_params *params
8159 )
8160#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308161static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008162 struct net_device *ndev,
8163 u8 key_index, const u8 *mac_addr,
8164 struct key_params *params
8165 )
8166#endif
8167{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008168 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07008169 tCsrRoamSetKey setKey;
8170 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308171 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008172 v_U32_t roamId= 0xFF;
8173 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008174 hdd_hostapd_state_t *pHostapdState;
8175 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008176 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308177 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008178
8179 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308180
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308181 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8182 TRACE_CODE_HDD_CFG80211_ADD_KEY,
8183 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308184 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8185 status = wlan_hdd_validate_context(pHddCtx);
8186
8187 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008188 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308189 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8190 "%s: HDD context is not valid", __func__);
8191 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008192 }
8193
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308194 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8195 __func__, hdd_device_modetoString(pAdapter->device_mode),
8196 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008197
8198 if (CSR_MAX_NUM_KEY <= key_index)
8199 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008200 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008201 key_index);
8202
8203 return -EINVAL;
8204 }
8205
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008206 if (CSR_MAX_KEY_LEN < params->key_len)
8207 {
8208 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
8209 params->key_len);
8210
8211 return -EINVAL;
8212 }
8213
8214 hddLog(VOS_TRACE_LEVEL_INFO,
8215 "%s: called with key index = %d & key length %d",
8216 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008217
8218 /*extract key idx, key len and key*/
8219 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8220 setKey.keyId = key_index;
8221 setKey.keyLength = params->key_len;
8222 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
8223
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008224 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07008225 {
8226 case WLAN_CIPHER_SUITE_WEP40:
8227 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
8228 break;
8229
8230 case WLAN_CIPHER_SUITE_WEP104:
8231 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
8232 break;
8233
8234 case WLAN_CIPHER_SUITE_TKIP:
8235 {
8236 u8 *pKey = &setKey.Key[0];
8237 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
8238
8239 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
8240
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008241 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07008242
8243 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008244 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008245 |--------------|----------|----------|
8246 <---16bytes---><--8bytes--><--8bytes-->
8247
8248 */
8249 /*Sme expects the 32 bytes key to be in the below order
8250
8251 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008252 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008253 |--------------|----------|----------|
8254 <---16bytes---><--8bytes--><--8bytes-->
8255 */
8256 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008257 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07008258
8259 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008260 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008261
8262 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008263 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008264
8265
8266 break;
8267 }
8268
8269 case WLAN_CIPHER_SUITE_CCMP:
8270 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
8271 break;
8272
8273#ifdef FEATURE_WLAN_WAPI
8274 case WLAN_CIPHER_SUITE_SMS4:
8275 {
8276 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8277 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
8278 params->key, params->key_len);
8279 return 0;
8280 }
8281#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008282
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008283#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07008284 case WLAN_CIPHER_SUITE_KRK:
8285 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
8286 break;
8287#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008288
8289#ifdef WLAN_FEATURE_11W
8290 case WLAN_CIPHER_SUITE_AES_CMAC:
8291 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07008292 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07008293#endif
8294
Jeff Johnson295189b2012-06-20 16:38:30 -07008295 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008296 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07008297 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308298 status = -EOPNOTSUPP;
8299 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008300 }
8301
8302 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
8303 __func__, setKey.encType);
8304
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008305 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07008306#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8307 (!pairwise)
8308#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008309 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07008310#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008311 )
8312 {
8313 /* set group key*/
8314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8315 "%s- %d: setting Broadcast key",
8316 __func__, __LINE__);
8317 setKey.keyDirection = eSIR_RX_ONLY;
8318 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8319 }
8320 else
8321 {
8322 /* set pairwise key*/
8323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8324 "%s- %d: setting pairwise key",
8325 __func__, __LINE__);
8326 setKey.keyDirection = eSIR_TX_RX;
8327 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8328 }
8329 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
8330 {
8331 setKey.keyDirection = eSIR_TX_RX;
8332 /*Set the group key*/
8333 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8334 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07008335
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008336 if ( 0 != status )
8337 {
8338 hddLog(VOS_TRACE_LEVEL_ERROR,
8339 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308340 status = -EINVAL;
8341 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008342 }
8343 /*Save the keys here and call sme_RoamSetKey for setting
8344 the PTK after peer joins the IBSS network*/
8345 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
8346 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308347 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008348 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05308349 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
8350 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
8351 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008352 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008353 if( pHostapdState->bssState == BSS_START )
8354 {
c_hpothu7c55da62014-01-23 18:34:02 +05308355 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8356 vos_status = wlan_hdd_check_ula_done(pAdapter);
8357
8358 if ( vos_status != VOS_STATUS_SUCCESS )
8359 {
8360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8361 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8362 __LINE__, vos_status );
8363
8364 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8365
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308366 status = -EINVAL;
8367 goto end;
c_hpothu7c55da62014-01-23 18:34:02 +05308368 }
8369
Jeff Johnson295189b2012-06-20 16:38:30 -07008370 status = WLANSAP_SetKeySta( pVosContext, &setKey);
8371
8372 if ( status != eHAL_STATUS_SUCCESS )
8373 {
8374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8375 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8376 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308377 status = -EINVAL;
8378 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008379 }
8380 }
8381
8382 /* Saving WEP keys */
8383 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
8384 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
8385 {
8386 //Save the wep key in ap context. Issue setkey after the BSS is started.
8387 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8388 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
8389 }
8390 else
8391 {
8392 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008393 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008394 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
8395 }
8396 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008397 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
8398 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008399 {
8400 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8401 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8402
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308403#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8404 if (!pairwise)
8405#else
8406 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8407#endif
8408 {
8409 /* set group key*/
8410 if (pHddStaCtx->roam_info.deferKeyComplete)
8411 {
8412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8413 "%s- %d: Perform Set key Complete",
8414 __func__, __LINE__);
8415 hdd_PerformRoamSetKeyComplete(pAdapter);
8416 }
8417 }
8418
Jeff Johnson295189b2012-06-20 16:38:30 -07008419 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
8420
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08008421 pWextState->roamProfile.Keys.defaultIndex = key_index;
8422
8423
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008424 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008425 params->key, params->key_len);
8426
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308427
Jeff Johnson295189b2012-06-20 16:38:30 -07008428 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8429
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308430 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008431 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308432 __func__, setKey.peerMac[0], setKey.peerMac[1],
8433 setKey.peerMac[2], setKey.peerMac[3],
8434 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008435 setKey.keyDirection);
8436
8437 vos_status = wlan_hdd_check_ula_done(pAdapter);
8438
8439 if ( vos_status != VOS_STATUS_SUCCESS )
8440 {
8441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8442 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8443 __LINE__, vos_status );
8444
8445 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8446
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308447 status = -EINVAL;
8448 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008449
8450 }
8451
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008452#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308453 /* The supplicant may attempt to set the PTK once pre-authentication
8454 is done. Save the key in the UMAC and include it in the ADD BSS
8455 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008456 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308457 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008458 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308459 hddLog(VOS_TRACE_LEVEL_INFO_MED,
8460 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308461 status = 0;
8462 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308463 }
8464 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
8465 {
8466 hddLog(VOS_TRACE_LEVEL_ERROR,
8467 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308468 status = -EINVAL;
8469 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008470 }
8471#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07008472
8473 /* issue set key request to SME*/
8474 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8475 pAdapter->sessionId, &setKey, &roamId );
8476
8477 if ( 0 != status )
8478 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308479 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008480 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
8481 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308482 status = -EINVAL;
8483 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008484 }
8485
8486
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308487 /* in case of IBSS as there was no information available about WEP keys during
8488 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07008489 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308490 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
8491 !( ( IW_AUTH_KEY_MGMT_802_1X
8492 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07008493 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
8494 )
8495 &&
8496 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
8497 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
8498 )
8499 )
8500 {
8501 setKey.keyDirection = eSIR_RX_ONLY;
8502 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8503
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308504 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008505 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308506 __func__, setKey.peerMac[0], setKey.peerMac[1],
8507 setKey.peerMac[2], setKey.peerMac[3],
8508 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008509 setKey.keyDirection);
8510
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308511 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008512 pAdapter->sessionId, &setKey, &roamId );
8513
8514 if ( 0 != status )
8515 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308516 hddLog(VOS_TRACE_LEVEL_ERROR,
8517 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008518 __func__, status);
8519 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308520 status = -EINVAL;
8521 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008522 }
8523 }
8524 }
8525
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308526end:
8527 /* Need to clear any trace of key value in the memory.
8528 * Thus zero out the memory even though it is local
8529 * variable.
8530 */
8531 vos_mem_zero(&setKey, sizeof(setKey));
8532
8533 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008534}
8535
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308536#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8537static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8538 struct net_device *ndev,
8539 u8 key_index, bool pairwise,
8540 const u8 *mac_addr,
8541 struct key_params *params
8542 )
8543#else
8544static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8545 struct net_device *ndev,
8546 u8 key_index, const u8 *mac_addr,
8547 struct key_params *params
8548 )
8549#endif
8550{
8551 int ret;
8552 vos_ssr_protect(__func__);
8553#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8554 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
8555 mac_addr, params);
8556#else
8557 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
8558 params);
8559#endif
8560 vos_ssr_unprotect(__func__);
8561
8562 return ret;
8563}
8564
Jeff Johnson295189b2012-06-20 16:38:30 -07008565/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308566 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008567 * This function is used to get the key information
8568 */
8569#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308570static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308571 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008572 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308573 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008574 const u8 *mac_addr, void *cookie,
8575 void (*callback)(void *cookie, struct key_params*)
8576 )
8577#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308578static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308579 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008580 struct net_device *ndev,
8581 u8 key_index, const u8 *mac_addr, void *cookie,
8582 void (*callback)(void *cookie, struct key_params*)
8583 )
8584#endif
8585{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308586 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308587 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8588 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Jeff Johnson295189b2012-06-20 16:38:30 -07008589 struct key_params params;
8590
8591 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308592
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308593 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8594 __func__, hdd_device_modetoString(pAdapter->device_mode),
8595 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308596
Jeff Johnson295189b2012-06-20 16:38:30 -07008597 memset(&params, 0, sizeof(params));
8598
8599 if (CSR_MAX_NUM_KEY <= key_index)
8600 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308601 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07008602 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308603 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008604
8605 switch(pRoamProfile->EncryptionType.encryptionType[0])
8606 {
8607 case eCSR_ENCRYPT_TYPE_NONE:
8608 params.cipher = IW_AUTH_CIPHER_NONE;
8609 break;
8610
8611 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
8612 case eCSR_ENCRYPT_TYPE_WEP40:
8613 params.cipher = WLAN_CIPHER_SUITE_WEP40;
8614 break;
8615
8616 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
8617 case eCSR_ENCRYPT_TYPE_WEP104:
8618 params.cipher = WLAN_CIPHER_SUITE_WEP104;
8619 break;
8620
8621 case eCSR_ENCRYPT_TYPE_TKIP:
8622 params.cipher = WLAN_CIPHER_SUITE_TKIP;
8623 break;
8624
8625 case eCSR_ENCRYPT_TYPE_AES:
8626 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
8627 break;
8628
8629 default:
8630 params.cipher = IW_AUTH_CIPHER_NONE;
8631 break;
8632 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308633
c_hpothuaaf19692014-05-17 17:01:48 +05308634 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8635 TRACE_CODE_HDD_CFG80211_GET_KEY,
8636 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308637
Jeff Johnson295189b2012-06-20 16:38:30 -07008638 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
8639 params.seq_len = 0;
8640 params.seq = NULL;
8641 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
8642 callback(cookie, &params);
8643 return 0;
8644}
8645
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308646#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8647static int wlan_hdd_cfg80211_get_key(
8648 struct wiphy *wiphy,
8649 struct net_device *ndev,
8650 u8 key_index, bool pairwise,
8651 const u8 *mac_addr, void *cookie,
8652 void (*callback)(void *cookie, struct key_params*)
8653 )
8654#else
8655static int wlan_hdd_cfg80211_get_key(
8656 struct wiphy *wiphy,
8657 struct net_device *ndev,
8658 u8 key_index, const u8 *mac_addr, void *cookie,
8659 void (*callback)(void *cookie, struct key_params*)
8660 )
8661#endif
8662{
8663 int ret;
8664
8665 vos_ssr_protect(__func__);
8666#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8667 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
8668 mac_addr, cookie, callback);
8669#else
8670 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
8671 callback);
8672#endif
8673 vos_ssr_unprotect(__func__);
8674
8675 return ret;
8676}
8677
Jeff Johnson295189b2012-06-20 16:38:30 -07008678/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308679 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008680 * This function is used to delete the key information
8681 */
8682#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308683static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008684 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308685 u8 key_index,
8686 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008687 const u8 *mac_addr
8688 )
8689#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308690static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008691 struct net_device *ndev,
8692 u8 key_index,
8693 const u8 *mac_addr
8694 )
8695#endif
8696{
8697 int status = 0;
8698
8699 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308700 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07008701 //it is observed that this is invalidating peer
8702 //key index whenever re-key is done. This is affecting data link.
8703 //It should be ok to ignore del_key.
8704#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308705 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
8706 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008707 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
8708 tCsrRoamSetKey setKey;
8709 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308710
Jeff Johnson295189b2012-06-20 16:38:30 -07008711 ENTER();
8712
8713 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
8714 __func__,pAdapter->device_mode);
8715
8716 if (CSR_MAX_NUM_KEY <= key_index)
8717 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308718 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008719 key_index);
8720
8721 return -EINVAL;
8722 }
8723
8724 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8725 setKey.keyId = key_index;
8726
8727 if (mac_addr)
8728 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8729 else
8730 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
8731
8732 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
8733
8734 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008735 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308736 )
8737 {
8738
8739 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07008740 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8741 if( pHostapdState->bssState == BSS_START)
8742 {
8743 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308744
Jeff Johnson295189b2012-06-20 16:38:30 -07008745 if ( status != eHAL_STATUS_SUCCESS )
8746 {
8747 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8748 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8749 __LINE__, status );
8750 }
8751 }
8752 }
8753 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308754 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07008755 )
8756 {
8757 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8758
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308759 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8760
8761 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008762 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308763 __func__, setKey.peerMac[0], setKey.peerMac[1],
8764 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07008765 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308766 if(pAdapter->sessionCtx.station.conn_info.connState ==
8767 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07008768 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308769 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008770 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308771
Jeff Johnson295189b2012-06-20 16:38:30 -07008772 if ( 0 != status )
8773 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308774 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008775 "%s: sme_RoamSetKey failure, returned %d",
8776 __func__, status);
8777 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8778 return -EINVAL;
8779 }
8780 }
8781 }
8782#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008783 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008784 return status;
8785}
8786
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308787#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8788static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
8789 struct net_device *ndev,
8790 u8 key_index,
8791 bool pairwise,
8792 const u8 *mac_addr
8793 )
8794#else
8795static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
8796 struct net_device *ndev,
8797 u8 key_index,
8798 const u8 *mac_addr
8799 )
8800#endif
8801{
8802 int ret;
8803
8804 vos_ssr_protect(__func__);
8805#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8806 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
8807 mac_addr);
8808#else
8809 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
8810#endif
8811 vos_ssr_unprotect(__func__);
8812
8813 return ret;
8814}
8815
Jeff Johnson295189b2012-06-20 16:38:30 -07008816/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308817 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008818 * This function is used to set the default tx key index
8819 */
8820#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308821static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008822 struct net_device *ndev,
8823 u8 key_index,
8824 bool unicast, bool multicast)
8825#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308826static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008827 struct net_device *ndev,
8828 u8 key_index)
8829#endif
8830{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308831 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308832 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308833 hdd_wext_state_t *pWextState;
8834 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308835 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008836
8837 ENTER();
8838
Gopichand Nakkala29149562013-05-10 21:43:41 +05308839 if ((NULL == pAdapter))
8840 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308841 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308842 "invalid adapter");
8843 return -EINVAL;
8844 }
8845
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308846 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8847 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
8848 pAdapter->sessionId, key_index));
8849
Gopichand Nakkala29149562013-05-10 21:43:41 +05308850 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8851 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8852
8853 if ((NULL == pWextState) || (NULL == pHddStaCtx))
8854 {
8855 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8856 "invalid Wext state or HDD context");
8857 return -EINVAL;
8858 }
8859
Arif Hussain6d2a3322013-11-17 19:50:10 -08008860 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008861 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308862
Jeff Johnson295189b2012-06-20 16:38:30 -07008863 if (CSR_MAX_NUM_KEY <= key_index)
8864 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308865 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008866 key_index);
8867
8868 return -EINVAL;
8869 }
8870
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308871 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8872 status = wlan_hdd_validate_context(pHddCtx);
8873
8874 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008875 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8877 "%s: HDD context is not valid", __func__);
8878 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008879 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308880
Jeff Johnson295189b2012-06-20 16:38:30 -07008881 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008882 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308883 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008884 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308885 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08008886 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308887 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08008888 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07008889 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308890 {
8891 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07008892 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308893
Jeff Johnson295189b2012-06-20 16:38:30 -07008894 tCsrRoamSetKey setKey;
8895 v_U32_t roamId= 0xFF;
8896 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308897
8898 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008899 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308900
Jeff Johnson295189b2012-06-20 16:38:30 -07008901 Keys->defaultIndex = (u8)key_index;
8902 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8903 setKey.keyId = key_index;
8904 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308905
8906 vos_mem_copy(&setKey.Key[0],
8907 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008908 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308909
Gopichand Nakkala29149562013-05-10 21:43:41 +05308910 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308911
8912 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07008913 &pHddStaCtx->conn_info.bssId[0],
8914 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308915
Gopichand Nakkala29149562013-05-10 21:43:41 +05308916 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
8917 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
8918 eCSR_ENCRYPT_TYPE_WEP104)
8919 {
8920 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
8921 even though ap is configured for WEP-40 encryption. In this canse the key length
8922 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
8923 type(104) and switching encryption type to 40*/
8924 pWextState->roamProfile.EncryptionType.encryptionType[0] =
8925 eCSR_ENCRYPT_TYPE_WEP40;
8926 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
8927 eCSR_ENCRYPT_TYPE_WEP40;
8928 }
8929
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308930 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07008931 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308932
Jeff Johnson295189b2012-06-20 16:38:30 -07008933 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308934 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008935 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308936
Jeff Johnson295189b2012-06-20 16:38:30 -07008937 if ( 0 != status )
8938 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308939 hddLog(VOS_TRACE_LEVEL_ERROR,
8940 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008941 status);
8942 return -EINVAL;
8943 }
8944 }
8945 }
8946
8947 /* In SoftAp mode setting key direction for default mode */
8948 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
8949 {
8950 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
8951 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
8952 (eCSR_ENCRYPT_TYPE_AES !=
8953 pWextState->roamProfile.EncryptionType.encryptionType[0])
8954 )
8955 {
8956 /* Saving key direction for default key index to TX default */
8957 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8958 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
8959 }
8960 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308961
Jeff Johnson295189b2012-06-20 16:38:30 -07008962 return status;
8963}
8964
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308965#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8966static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8967 struct net_device *ndev,
8968 u8 key_index,
8969 bool unicast, bool multicast)
8970#else
8971static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8972 struct net_device *ndev,
8973 u8 key_index)
8974#endif
8975{
8976 int ret;
8977 vos_ssr_protect(__func__);
8978#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8979 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
8980 multicast);
8981#else
8982 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
8983#endif
8984 vos_ssr_unprotect(__func__);
8985
8986 return ret;
8987}
8988
Jeff Johnson295189b2012-06-20 16:38:30 -07008989/*
8990 * FUNCTION: wlan_hdd_cfg80211_inform_bss
8991 * This function is used to inform the BSS details to nl80211 interface.
8992 */
8993static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
8994 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
8995{
8996 struct net_device *dev = pAdapter->dev;
8997 struct wireless_dev *wdev = dev->ieee80211_ptr;
8998 struct wiphy *wiphy = wdev->wiphy;
8999 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
9000 int chan_no;
9001 int ie_length;
9002 const char *ie;
9003 unsigned int freq;
9004 struct ieee80211_channel *chan;
9005 int rssi = 0;
9006 struct cfg80211_bss *bss = NULL;
9007
9008 ENTER();
9009
9010 if( NULL == pBssDesc )
9011 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009012 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009013 return bss;
9014 }
9015
9016 chan_no = pBssDesc->channelId;
9017 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
9018 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
9019
9020 if( NULL == ie )
9021 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009022 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009023 return bss;
9024 }
9025
9026#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9027 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9028 {
9029 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9030 }
9031 else
9032 {
9033 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9034 }
9035#else
9036 freq = ieee80211_channel_to_frequency(chan_no);
9037#endif
9038
9039 chan = __ieee80211_get_channel(wiphy, freq);
9040
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05309041 if (!chan) {
9042 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
9043 return NULL;
9044 }
9045
Abhishek Singhaee43942014-06-16 18:55:47 +05309046 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07009047
Abhishek Singhaee43942014-06-16 18:55:47 +05309048 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309049 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07009050 pBssDesc->capabilityInfo,
9051 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05309052 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07009053}
9054
9055
9056
9057/*
9058 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
9059 * This function is used to inform the BSS details to nl80211 interface.
9060 */
9061struct cfg80211_bss*
9062wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
9063 tSirBssDescription *bss_desc
9064 )
9065{
9066 /*
9067 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
9068 already exists in bss data base of cfg80211 for that particular BSS ID.
9069 Using cfg80211_inform_bss_frame to update the bss entry instead of
9070 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
9071 now there is no possibility to get the mgmt(probe response) frame from PE,
9072 converting bss_desc to ieee80211_mgmt(probe response) and passing to
9073 cfg80211_inform_bss_frame.
9074 */
9075 struct net_device *dev = pAdapter->dev;
9076 struct wireless_dev *wdev = dev->ieee80211_ptr;
9077 struct wiphy *wiphy = wdev->wiphy;
9078 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009079#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9080 qcom_ie_age *qie_age = NULL;
9081 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
9082#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009083 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009084#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009085 const char *ie =
9086 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
9087 unsigned int freq;
9088 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309089 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009090 struct cfg80211_bss *bss_status = NULL;
9091 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
9092 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07009093 hdd_context_t *pHddCtx;
9094 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07009095#ifdef WLAN_OPEN_SOURCE
9096 struct timespec ts;
9097#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009098
Wilson Yangf80a0542013-10-07 13:02:37 -07009099 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9100 status = wlan_hdd_validate_context(pHddCtx);
9101
9102 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309103 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009104 {
9105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9106 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9107 return NULL;
9108 }
9109
9110
9111 if (0 != status)
9112 {
9113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9114 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009115 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009116 }
9117
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309118 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07009119 if (!mgmt)
9120 {
9121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9122 "%s: memory allocation failed ", __func__);
9123 return NULL;
9124 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009125
Jeff Johnson295189b2012-06-20 16:38:30 -07009126 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07009127
9128#ifdef WLAN_OPEN_SOURCE
9129 /* Android does not want the timestamp from the frame.
9130 Instead it wants a monotonic increasing value */
9131 get_monotonic_boottime(&ts);
9132 mgmt->u.probe_resp.timestamp =
9133 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
9134#else
9135 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009136 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
9137 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07009138
9139#endif
9140
Jeff Johnson295189b2012-06-20 16:38:30 -07009141 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
9142 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009143
9144#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9145 /* GPS Requirement: need age ie per entry. Using vendor specific. */
9146 /* Assuming this is the last IE, copy at the end */
9147 ie_length -=sizeof(qcom_ie_age);
9148 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
9149 qie_age->element_id = QCOM_VENDOR_IE_ID;
9150 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
9151 qie_age->oui_1 = QCOM_OUI1;
9152 qie_age->oui_2 = QCOM_OUI2;
9153 qie_age->oui_3 = QCOM_OUI3;
9154 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
9155 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
9156#endif
9157
Jeff Johnson295189b2012-06-20 16:38:30 -07009158 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05309159 if (bss_desc->fProbeRsp)
9160 {
9161 mgmt->frame_control |=
9162 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
9163 }
9164 else
9165 {
9166 mgmt->frame_control |=
9167 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
9168 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009169
9170#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309171 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009172 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
9173 {
9174 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9175 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309176 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009177 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
9178
9179 {
9180 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9181 }
9182 else
9183 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309184 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
9185 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07009186 kfree(mgmt);
9187 return NULL;
9188 }
9189#else
9190 freq = ieee80211_channel_to_frequency(chan_no);
9191#endif
9192 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009193 /*when the band is changed on the fly using the GUI, three things are done
9194 * 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)
9195 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
9196 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
9197 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
9198 * and discards the channels correponding to previous band and calls back with zero bss results.
9199 * 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
9200 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
9201 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
9202 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
9203 * So drop the bss and continue to next bss.
9204 */
9205 if(chan == NULL)
9206 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309207 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07009208 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009209 return NULL;
9210 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009211 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309212 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07009213 * */
9214 if (( eConnectionState_Associated ==
9215 pAdapter->sessionCtx.station.conn_info.connState ) &&
9216 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
9217 pAdapter->sessionCtx.station.conn_info.bssId,
9218 WNI_CFG_BSSID_LEN)))
9219 {
9220 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
9221 rssi = (pAdapter->rssi * 100);
9222 }
9223 else
9224 {
9225 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
9226 }
9227
Nirav Shah20ac06f2013-12-12 18:14:06 +05309228 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
9229 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
9230 chan->center_freq, (int)(rssi/100));
9231
Jeff Johnson295189b2012-06-20 16:38:30 -07009232 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
9233 frame_len, rssi, GFP_KERNEL);
9234 kfree(mgmt);
9235 return bss_status;
9236}
9237
9238/*
9239 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
9240 * This function is used to update the BSS data base of CFG8011
9241 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309242struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009243 tCsrRoamInfo *pRoamInfo
9244 )
9245{
9246 tCsrRoamConnectedProfile roamProfile;
9247 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9248 struct cfg80211_bss *bss = NULL;
9249
9250 ENTER();
9251
9252 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
9253 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
9254
9255 if (NULL != roamProfile.pBssDesc)
9256 {
Girish Gowlif4b68022014-08-28 23:18:57 +05309257 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9258 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009259
9260 if (NULL == bss)
9261 {
9262 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
9263 __func__);
9264 }
9265
9266 sme_RoamFreeConnectProfile(hHal, &roamProfile);
9267 }
9268 else
9269 {
9270 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
9271 __func__);
9272 }
9273 return bss;
9274}
9275
9276/*
9277 * FUNCTION: wlan_hdd_cfg80211_update_bss
9278 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309279static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
9280 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07009281 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309282{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309283 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009284 tCsrScanResultInfo *pScanResult;
9285 eHalStatus status = 0;
9286 tScanResultHandle pResult;
9287 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009288 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009289
9290 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309291
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309292 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9293 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
9294 NO_SESSION, pAdapter->sessionId));
9295
Wilson Yangf80a0542013-10-07 13:02:37 -07009296 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9297
9298 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009299 {
Wilson Yangf80a0542013-10-07 13:02:37 -07009300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9301 "%s:LOGP in Progress. Ignore!!!",__func__);
9302 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009303 }
9304
Wilson Yangf80a0542013-10-07 13:02:37 -07009305
9306 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309307 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009308 {
9309 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9310 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9311 return VOS_STATUS_E_PERM;
9312 }
9313
9314
Jeff Johnson295189b2012-06-20 16:38:30 -07009315 /*
9316 * start getting scan results and populate cgf80211 BSS database
9317 */
9318 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
9319
9320 /* no scan results */
9321 if (NULL == pResult)
9322 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309323 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
9324 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009325 return status;
9326 }
9327
9328 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
9329
9330 while (pScanResult)
9331 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309332 /*
9333 * cfg80211_inform_bss() is not updating ie field of bss entry, if
9334 * entry already exists in bss data base of cfg80211 for that
9335 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
9336 * bss entry instead of cfg80211_inform_bss, But this call expects
9337 * mgmt packet as input. As of now there is no possibility to get
9338 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07009339 * ieee80211_mgmt(probe response) and passing to c
9340 * fg80211_inform_bss_frame.
9341 * */
9342
9343 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9344 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309345
Jeff Johnson295189b2012-06-20 16:38:30 -07009346
9347 if (NULL == bss_status)
9348 {
9349 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009350 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009351 }
9352 else
9353 {
Yue Maf49ba872013-08-19 12:04:25 -07009354 cfg80211_put_bss(
9355#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
9356 wiphy,
9357#endif
9358 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009359 }
9360
9361 pScanResult = sme_ScanResultGetNext(hHal, pResult);
9362 }
9363
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309364 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07009365
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309366 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009367}
9368
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009369void
9370hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
9371{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309372 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08009373 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009374} /****** end hddPrintMacAddr() ******/
9375
9376void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009377hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009378{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309379 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009380 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009381 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
9382 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
9383 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009384} /****** end hddPrintPmkId() ******/
9385
9386//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
9387//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
9388
9389//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
9390//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
9391
9392#define dump_bssid(bssid) \
9393 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009394 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
9395 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009396 }
9397
9398#define dump_pmkid(pMac, pmkid) \
9399 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009400 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
9401 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009402 }
9403
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009404#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009405/*
9406 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
9407 * This function is used to notify the supplicant of a new PMKSA candidate.
9408 */
9409int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309410 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009411 int index, bool preauth )
9412{
Jeff Johnsone7245742012-09-05 17:12:55 -07009413#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009414 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009415 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009416
9417 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07009418 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009419
9420 if( NULL == pRoamInfo )
9421 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009422 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009423 return -EINVAL;
9424 }
9425
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009426 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
9427 {
9428 dump_bssid(pRoamInfo->bssid);
9429 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009430 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009431 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009432#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309433 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009434}
9435#endif //FEATURE_WLAN_LFR
9436
Yue Maef608272013-04-08 23:09:17 -07009437#ifdef FEATURE_WLAN_LFR_METRICS
9438/*
9439 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
9440 * 802.11r/LFR metrics reporting function to report preauth initiation
9441 *
9442 */
9443#define MAX_LFR_METRICS_EVENT_LENGTH 100
9444VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
9445 tCsrRoamInfo *pRoamInfo)
9446{
9447 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9448 union iwreq_data wrqu;
9449
9450 ENTER();
9451
9452 if (NULL == pAdapter)
9453 {
9454 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9455 return VOS_STATUS_E_FAILURE;
9456 }
9457
9458 /* create the event */
9459 memset(&wrqu, 0, sizeof(wrqu));
9460 memset(metrics_notification, 0, sizeof(metrics_notification));
9461
9462 wrqu.data.pointer = metrics_notification;
9463 wrqu.data.length = scnprintf(metrics_notification,
9464 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
9465 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9466
9467 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9468
9469 EXIT();
9470
9471 return VOS_STATUS_SUCCESS;
9472}
9473
9474/*
9475 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
9476 * 802.11r/LFR metrics reporting function to report preauth completion
9477 * or failure
9478 */
9479VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
9480 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
9481{
9482 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9483 union iwreq_data wrqu;
9484
9485 ENTER();
9486
9487 if (NULL == pAdapter)
9488 {
9489 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9490 return VOS_STATUS_E_FAILURE;
9491 }
9492
9493 /* create the event */
9494 memset(&wrqu, 0, sizeof(wrqu));
9495 memset(metrics_notification, 0, sizeof(metrics_notification));
9496
9497 scnprintf(metrics_notification, sizeof(metrics_notification),
9498 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
9499 MAC_ADDR_ARRAY(pRoamInfo->bssid));
9500
9501 if (1 == preauth_status)
9502 strncat(metrics_notification, " TRUE", 5);
9503 else
9504 strncat(metrics_notification, " FALSE", 6);
9505
9506 wrqu.data.pointer = metrics_notification;
9507 wrqu.data.length = strlen(metrics_notification);
9508
9509 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9510
9511 EXIT();
9512
9513 return VOS_STATUS_SUCCESS;
9514}
9515
9516/*
9517 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
9518 * 802.11r/LFR metrics reporting function to report handover initiation
9519 *
9520 */
9521VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
9522 tCsrRoamInfo *pRoamInfo)
9523{
9524 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9525 union iwreq_data wrqu;
9526
9527 ENTER();
9528
9529 if (NULL == pAdapter)
9530 {
9531 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9532 return VOS_STATUS_E_FAILURE;
9533 }
9534
9535 /* create the event */
9536 memset(&wrqu, 0, sizeof(wrqu));
9537 memset(metrics_notification, 0, sizeof(metrics_notification));
9538
9539 wrqu.data.pointer = metrics_notification;
9540 wrqu.data.length = scnprintf(metrics_notification,
9541 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
9542 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9543
9544 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9545
9546 EXIT();
9547
9548 return VOS_STATUS_SUCCESS;
9549}
9550#endif
9551
Jeff Johnson295189b2012-06-20 16:38:30 -07009552/*
9553 * FUNCTION: hdd_cfg80211_scan_done_callback
9554 * scanning callback function, called after finishing scan
9555 *
9556 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309557static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07009558 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
9559{
9560 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309561 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009562 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009563 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9564 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07009565 struct cfg80211_scan_request *req = NULL;
9566 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309567 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309568 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +05309569 tANI_U8 i;
Jeff Johnson295189b2012-06-20 16:38:30 -07009570
9571 ENTER();
9572
9573 hddLog(VOS_TRACE_LEVEL_INFO,
9574 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08009575 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009576 __func__, halHandle, pContext, (int) scanId, (int) status);
9577
Kiet Lamac06e2c2013-10-23 16:25:07 +05309578 pScanInfo->mScanPendingCounter = 0;
9579
Jeff Johnson295189b2012-06-20 16:38:30 -07009580 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309581 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009582 &pScanInfo->scan_req_completion_event,
9583 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309584 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009585 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309586 hddLog(VOS_TRACE_LEVEL_ERROR,
9587 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009589 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009590 }
9591
Yue Maef608272013-04-08 23:09:17 -07009592 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07009593 {
9594 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009595 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009596 }
9597
9598 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309599 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07009600 {
9601 hddLog(VOS_TRACE_LEVEL_INFO,
9602 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009603 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07009604 (int) scanId);
9605 }
9606
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309607 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009608 pAdapter);
9609
9610 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309611 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009612
9613
9614 /* If any client wait scan result through WEXT
9615 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009616 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07009617 {
9618 /* The other scan request waiting for current scan finish
9619 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009620 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009621 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009622 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07009623 }
9624 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009625 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009626 {
9627 struct net_device *dev = pAdapter->dev;
9628 union iwreq_data wrqu;
9629 int we_event;
9630 char *msg;
9631
9632 memset(&wrqu, '\0', sizeof(wrqu));
9633 we_event = SIOCGIWSCAN;
9634 msg = NULL;
9635 wireless_send_event(dev, we_event, &wrqu, msg);
9636 }
9637 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009638 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009639
9640 /* Get the Scan Req */
9641 req = pAdapter->request;
9642
9643 if (!req)
9644 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009645 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009646 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07009647 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009648 }
9649
Jeff Johnson295189b2012-06-20 16:38:30 -07009650 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009651 /* Scan is no longer pending */
9652 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009653
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +05309654 /* last_scan_timestamp is used to decide if new scan
9655 * is needed or not on station interface. If last station
9656 * scan time and new station scan time is less then
9657 * last_scan_timestamp ; driver will return cached scan.
9658 */
9659 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
9660 {
9661 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
9662
9663 if ( req->n_channels )
9664 {
9665 for (i = 0; i < req->n_channels ; i++ )
9666 {
9667 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
9668 }
9669 /* store no of channel scanned */
9670 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
9671 }
9672
9673 }
9674
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07009675 /*
9676 * cfg80211_scan_done informing NL80211 about completion
9677 * of scanning
9678 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309679 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
9680 {
9681 aborted = true;
9682 }
9683 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009684 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07009685
Siddharth Bhal76972212014-10-15 16:22:51 +05309686 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
9687 /* Generate new random mac addr for next scan */
9688 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
9689 hdd_processSpoofMacAddrRequest(pHddCtx);
9690 }
9691
Jeff Johnsone7245742012-09-05 17:12:55 -07009692allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009693 /* release the wake lock at the end of the scan*/
9694 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009695
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009696 /* Acquire wakelock to handle the case where APP's tries to suspend
9697 * immediatly after the driver gets connect request(i.e after scan)
9698 * from supplicant, this result in app's is suspending and not able
9699 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309700 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009701
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009702#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05309703 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
9704 {
9705 wlan_hdd_tdls_scan_done_callback(pAdapter);
9706 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009707#endif
9708
Jeff Johnson295189b2012-06-20 16:38:30 -07009709 EXIT();
9710 return 0;
9711}
9712
9713/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05309714 * FUNCTION: hdd_isConnectionInProgress
9715 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009716 *
9717 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +05309718v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009719{
9720 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9721 hdd_station_ctx_t *pHddStaCtx = NULL;
9722 hdd_adapter_t *pAdapter = NULL;
9723 VOS_STATUS status = 0;
9724 v_U8_t staId = 0;
9725 v_U8_t *staMac = NULL;
9726
c_hpothu9b781ba2013-12-30 20:57:45 +05309727 if (TRUE == pHddCtx->btCoexModeSet)
9728 {
9729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05309730 FL("BTCoex Mode operation in progress"));
9731 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05309732 }
9733
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009734 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9735
9736 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9737 {
9738 pAdapter = pAdapterNode->pAdapter;
9739
9740 if( pAdapter )
9741 {
9742 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309743 "%s: Adapter with device mode %s (%d) exists",
9744 __func__, hdd_device_modetoString(pAdapter->device_mode),
9745 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +05309746 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +05309747 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9748 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
9749 (eConnectionState_Connecting ==
9750 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
9751 {
9752 hddLog(VOS_TRACE_LEVEL_ERROR,
9753 "%s: %p(%d) Connection is in progress", __func__,
9754 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
9755 return VOS_TRUE;
9756 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +05309757 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
9758 smeNeighborRoamIsHandoffInProgress(WLAN_HDD_GET_HAL_CTX(pAdapter)))
9759 {
9760 hddLog(VOS_TRACE_LEVEL_ERROR,
9761 "%s: %p(%d) Reassociation is in progress", __func__,
9762 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
9763 return VOS_TRUE;
9764 }
9765 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309766 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9767 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009768 {
9769 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9770 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309771 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009772 {
9773 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
9774 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009775 "%s: client " MAC_ADDRESS_STR
9776 " is in the middle of WPS/EAPOL exchange.", __func__,
9777 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309778 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009779 }
9780 }
9781 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
9782 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
9783 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05309784 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9785 ptSapContext pSapCtx = NULL;
9786 pSapCtx = VOS_GET_SAP_CB(pVosContext);
9787 if(pSapCtx == NULL){
9788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9789 FL("psapCtx is NULL"));
9790 return VOS_FALSE;
9791 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009792 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
9793 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05309794 if ((pSapCtx->aStaInfo[staId].isUsed) &&
9795 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009796 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05309797 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009798
9799 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009800 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
9801 "middle of WPS/EAPOL exchange.", __func__,
9802 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309803 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009804 }
9805 }
9806 }
9807 }
9808 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9809 pAdapterNode = pNext;
9810 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05309811 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309812}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009813
9814/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309815 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07009816 * this scan respond to scan trigger and update cfg80211 scan database
9817 * later, scan dump command can be used to recieve scan results
9818 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309819int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009820#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9821 struct net_device *dev,
9822#endif
9823 struct cfg80211_scan_request *request)
9824{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309825 hdd_adapter_t *pAdapter = NULL;
9826 hdd_context_t *pHddCtx = NULL;
9827 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309828 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009829 tCsrScanRequest scanRequest;
9830 tANI_U8 *channelList = NULL, i;
9831 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309832 int status;
9833 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009834 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +05309835 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009836
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309837#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
9838 struct net_device *dev = NULL;
9839 if (NULL == request)
9840 {
9841 hddLog(VOS_TRACE_LEVEL_ERROR,
9842 "%s: scan req param null", __func__);
9843 return -EINVAL;
9844 }
9845 dev = request->wdev->netdev;
9846#endif
9847
9848 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
9849 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9850 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9851
Jeff Johnson295189b2012-06-20 16:38:30 -07009852 ENTER();
9853
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309854
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309855 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9856 __func__, hdd_device_modetoString(pAdapter->device_mode),
9857 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309858
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309859 status = wlan_hdd_validate_context(pHddCtx);
9860
9861 if (0 != status)
9862 {
9863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9864 "%s: HDD context is not valid", __func__);
9865 return status;
9866 }
9867
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309868 if (NULL == pwextBuf)
9869 {
9870 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
9871 __func__);
9872 return -EIO;
9873 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309874 cfg_param = pHddCtx->cfg_ini;
9875 pScanInfo = &pHddCtx->scan_info;
9876
Jeff Johnson295189b2012-06-20 16:38:30 -07009877#ifdef WLAN_BTAMP_FEATURE
9878 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009879 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07009880 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009881 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009882 "%s: No scanning when AMP is on", __func__);
9883 return -EOPNOTSUPP;
9884 }
9885#endif
9886 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009887 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009888 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009889 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309890 "%s: Not scanning on device_mode = %s (%d)",
9891 __func__, hdd_device_modetoString(pAdapter->device_mode),
9892 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009893 return -EOPNOTSUPP;
9894 }
9895
9896 if (TRUE == pScanInfo->mScanPending)
9897 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309898 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
9899 {
9900 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
9901 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009902 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009903 }
9904
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309905 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07009906 //Channel and action frame is pending
9907 //Otherwise Cancel Remain On Channel and allow Scan
9908 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009909 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07009910 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309911 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009912 return -EBUSY;
9913 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009914#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009915 /* if tdls disagree scan right now, return immediately.
9916 tdls will schedule the scan when scan is allowed. (return SUCCESS)
9917 or will reject the scan if any TDLS is in progress. (return -EBUSY)
9918 */
9919 status = wlan_hdd_tdls_scan_callback (pAdapter,
9920 wiphy,
9921#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9922 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07009923#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009924 request);
9925 if(status <= 0)
9926 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309927 if(!status)
9928 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
9929 "scan rejected %d", __func__, status);
9930 else
9931 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
9932 __func__, status);
9933
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009934 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009935 }
9936#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07009937
Jeff Johnson295189b2012-06-20 16:38:30 -07009938 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
9939 {
9940 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08009941 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009942 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309943 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009944 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
9945 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309946 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009947 "%s: MAX TM Level Scan not allowed", __func__);
9948 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309949 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009950 }
9951 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
9952
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009953 /* Check if scan is allowed at this point of time.
9954 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +05309955 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009956 {
9957 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
9958 return -EBUSY;
9959 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309960
Jeff Johnson295189b2012-06-20 16:38:30 -07009961 vos_mem_zero( &scanRequest, sizeof(scanRequest));
9962
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309963 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
9964 (int)request->n_ssids);
9965
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +05309966
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309967 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
9968 * Becasue of this, driver is assuming that this is not wildcard scan and so
9969 * is not aging out the scan results.
9970 */
9971 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07009972 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309973 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009974 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309975
9976 if ((request->ssids) && (0 < request->n_ssids))
9977 {
9978 tCsrSSIDInfo *SsidInfo;
9979 int j;
9980 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
9981 /* Allocate num_ssid tCsrSSIDInfo structure */
9982 SsidInfo = scanRequest.SSIDs.SSIDList =
9983 ( tCsrSSIDInfo *)vos_mem_malloc(
9984 request->n_ssids*sizeof(tCsrSSIDInfo));
9985
9986 if(NULL == scanRequest.SSIDs.SSIDList)
9987 {
9988 hddLog(VOS_TRACE_LEVEL_ERROR,
9989 "%s: memory alloc failed SSIDInfo buffer", __func__);
9990 return -ENOMEM;
9991 }
9992
9993 /* copy all the ssid's and their length */
9994 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
9995 {
9996 /* get the ssid length */
9997 SsidInfo->SSID.length = request->ssids[j].ssid_len;
9998 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
9999 SsidInfo->SSID.length);
10000 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
10001 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
10002 j, SsidInfo->SSID.ssId);
10003 }
10004 /* set the scan type to active */
10005 scanRequest.scanType = eSIR_ACTIVE_SCAN;
10006 }
10007 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070010008 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010009 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10010 TRACE_CODE_HDD_CFG80211_SCAN,
10011 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070010012 /* set the scan type to active */
10013 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010014 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010015 else
10016 {
10017 /*Set the scan type to default type, in this case it is ACTIVE*/
10018 scanRequest.scanType = pScanInfo->scan_mode;
10019 }
10020 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
10021 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070010022
10023 /* set BSSType to default type */
10024 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
10025
10026 /*TODO: scan the requested channels only*/
10027
10028 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010029 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070010030 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010031 hddLog(VOS_TRACE_LEVEL_WARN,
10032 "No of Scan Channels exceeded limit: %d", request->n_channels);
10033 request->n_channels = MAX_CHANNEL;
10034 }
10035
10036 hddLog(VOS_TRACE_LEVEL_INFO,
10037 "No of Scan Channels: %d", request->n_channels);
10038
10039
10040 if( request->n_channels )
10041 {
10042 char chList [(request->n_channels*5)+1];
10043 int len;
10044 channelList = vos_mem_malloc( request->n_channels );
10045 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053010046 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010047 hddLog(VOS_TRACE_LEVEL_ERROR,
10048 "%s: memory alloc failed channelList", __func__);
10049 status = -ENOMEM;
10050 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053010051 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010052
10053 for( i = 0, len = 0; i < request->n_channels ; i++ )
10054 {
10055 channelList[i] = request->channels[i]->hw_value;
10056 len += snprintf(chList+len, 5, "%d ", channelList[i]);
10057 }
10058
Nirav Shah20ac06f2013-12-12 18:14:06 +053010059 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010060 "Channel-List: %s ", chList);
10061 }
c_hpothu53512302014-04-15 18:49:53 +053010062
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010063 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
10064 scanRequest.ChannelInfo.ChannelList = channelList;
10065
10066 /* set requestType to full scan */
10067 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10068
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010069 /* if there is back to back scan happening in driver with in
10070 * nDeferScanTimeInterval interval driver should defer new scan request
10071 * and should provide last cached scan results instead of new channel list.
10072 * This rule is not applicable if scan is p2p scan.
10073 * This condition will work only in case when last request no of channels
10074 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053010075 * This should be done only in connected state
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010076 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010077
Agarwal Ashish57e84372014-12-05 18:26:53 +053010078 if ((VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
10079 {
10080 if ( pScanInfo->last_scan_timestamp !=0 &&
10081 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
10082 {
10083 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
10084 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
10085 vos_mem_compare(pScanInfo->last_scan_channelList,
10086 channelList, pScanInfo->last_scan_numChannels))
10087 {
10088 hddLog(VOS_TRACE_LEVEL_WARN,
10089 " New and old station scan time differ is less then %u",
10090 pHddCtx->cfg_ini->nDeferScanTimeInterval);
10091
10092 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010093 pAdapter);
10094
Agarwal Ashish57e84372014-12-05 18:26:53 +053010095 hddLog(VOS_TRACE_LEVEL_WARN,
10096 "Return old cached scan as all channels"
10097 "and no of channles are same");
10098 if (0 > ret)
10099 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010100
Agarwal Ashish57e84372014-12-05 18:26:53 +053010101 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
10102 return eHAL_STATUS_SUCCESS ;
10103 }
10104 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010105 }
10106
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010107 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10108 * search (Flush on both full scan and social scan but not on single
10109 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10110 */
10111
10112 /* Supplicant does single channel scan after 8-way handshake
10113 * and in that case driver shoudnt flush scan results. If
10114 * driver flushes the scan results here and unfortunately if
10115 * the AP doesnt respond to our probe req then association
10116 * fails which is not desired
10117 */
10118
10119 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
10120 {
10121 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
10122 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
10123 pAdapter->sessionId );
10124 }
10125
10126 if( request->ie_len )
10127 {
10128 /* save this for future association (join requires this) */
10129 /*TODO: Array needs to be converted to dynamic allocation,
10130 * as multiple ie.s can be sent in cfg80211_scan_request structure
10131 * CR 597966
10132 */
10133 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
10134 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
10135 pScanInfo->scanAddIE.length = request->ie_len;
10136
10137 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10138 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10139 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010140 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010141 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070010142 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010143 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
10144 memcpy( pwextBuf->roamProfile.addIEScan,
10145 request->ie, request->ie_len);
10146 }
10147 else
10148 {
10149 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
10150 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070010151 }
10152
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010153 }
10154 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
10155 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
10156
10157 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
10158 request->ie_len);
10159 if (pP2pIe != NULL)
10160 {
10161#ifdef WLAN_FEATURE_P2P_DEBUG
10162 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
10163 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
10164 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053010165 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010166 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
10167 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10168 "Go nego completed to Connection is started");
10169 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10170 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053010171 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010172 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
10173 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010174 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010175 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
10176 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10177 "Disconnected state to Connection is started");
10178 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10179 "for 4way Handshake");
10180 }
10181#endif
10182
10183 /* no_cck will be set during p2p find to disable 11b rates */
10184 if(TRUE == request->no_cck)
10185 {
10186 hddLog(VOS_TRACE_LEVEL_INFO,
10187 "%s: This is a P2P Search", __func__);
10188 scanRequest.p2pSearch = 1;
10189
10190 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053010191 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010192 /* set requestType to P2P Discovery */
10193 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
10194 }
10195
10196 /*
10197 Skip Dfs Channel in case of P2P Search
10198 if it is set in ini file
10199 */
10200 if(cfg_param->skipDfsChnlInP2pSearch)
10201 {
10202 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010203 }
10204 else
10205 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010206 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010207 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010208
Agarwal Ashish4f616132013-12-30 23:32:50 +053010209 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010210 }
10211 }
10212
10213 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
10214
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010215 /* acquire the wakelock to avoid the apps suspend during the scan. To
10216 * address the following issues.
10217 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
10218 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
10219 * for long time, this result in apps running at full power for long time.
10220 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
10221 * be stuck in full power because of resume BMPS
10222 */
10223 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -070010224
Nirav Shah20ac06f2013-12-12 18:14:06 +053010225 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10226 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010227 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
10228 scanRequest.requestType, scanRequest.scanType,
10229 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053010230 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
10231
Siddharth Bhal76972212014-10-15 16:22:51 +053010232 if (pHddCtx->spoofMacAddr.isEnabled)
10233 {
10234 hddLog(VOS_TRACE_LEVEL_INFO,
10235 "%s: MAC Spoofing enabled for current scan", __func__);
10236 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
10237 * to fill TxBds for probe request during current scan
10238 */
10239 WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
10240 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
10241 }
10242
Jeff Johnsone7245742012-09-05 17:12:55 -070010243 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010244 pAdapter->sessionId, &scanRequest, &scanId,
10245 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070010246
Jeff Johnson295189b2012-06-20 16:38:30 -070010247 if (eHAL_STATUS_SUCCESS != status)
10248 {
10249 hddLog(VOS_TRACE_LEVEL_ERROR,
10250 "%s: sme_ScanRequest returned error %d", __func__, status);
10251 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010252 if(eHAL_STATUS_RESOURCES == status)
10253 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010254 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
10255 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010256 status = -EBUSY;
10257 } else {
10258 status = -EIO;
10259 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010260 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -070010261 goto free_mem;
10262 }
10263
10264 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010265 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070010266 pAdapter->request = request;
10267 pScanInfo->scanId = scanId;
10268
10269 complete(&pScanInfo->scan_req_completion_event);
10270
10271free_mem:
10272 if( scanRequest.SSIDs.SSIDList )
10273 {
10274 vos_mem_free(scanRequest.SSIDs.SSIDList);
10275 }
10276
10277 if( channelList )
10278 vos_mem_free( channelList );
10279
10280 EXIT();
10281
10282 return status;
10283}
10284
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010285int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
10286#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10287 struct net_device *dev,
10288#endif
10289 struct cfg80211_scan_request *request)
10290{
10291 int ret;
10292
10293 vos_ssr_protect(__func__);
10294 ret = __wlan_hdd_cfg80211_scan(wiphy,
10295#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10296 dev,
10297#endif
10298 request);
10299 vos_ssr_unprotect(__func__);
10300
10301 return ret;
10302}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010303
10304void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
10305{
10306 v_U8_t iniDot11Mode =
10307 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
10308 eHddDot11Mode hddDot11Mode = iniDot11Mode;
10309
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010310 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
10311 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010312 switch ( iniDot11Mode )
10313 {
10314 case eHDD_DOT11_MODE_AUTO:
10315 case eHDD_DOT11_MODE_11ac:
10316 case eHDD_DOT11_MODE_11ac_ONLY:
10317#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053010318 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
10319 sme_IsFeatureSupportedByFW(DOT11AC) )
10320 hddDot11Mode = eHDD_DOT11_MODE_11ac;
10321 else
10322 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010323#else
10324 hddDot11Mode = eHDD_DOT11_MODE_11n;
10325#endif
10326 break;
10327 case eHDD_DOT11_MODE_11n:
10328 case eHDD_DOT11_MODE_11n_ONLY:
10329 hddDot11Mode = eHDD_DOT11_MODE_11n;
10330 break;
10331 default:
10332 hddDot11Mode = iniDot11Mode;
10333 break;
10334 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010335#ifdef WLAN_FEATURE_AP_HT40_24G
10336 if (operationChannel > SIR_11B_CHANNEL_END)
10337#endif
10338 {
10339 /* This call decides required channel bonding mode */
10340 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010341 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
10342 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010343 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010344}
10345
Jeff Johnson295189b2012-06-20 16:38:30 -070010346/*
10347 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010348 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010349 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010350int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010351 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010352{
10353 int status = 0;
10354 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080010355 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010356 v_U32_t roamId;
10357 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070010358 eCsrAuthType RSNAuthType;
10359
10360 ENTER();
10361
10362 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080010363 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10364
10365 status = wlan_hdd_validate_context(pHddCtx);
10366 if (status)
10367 {
10368 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10369 "%s: HDD context is not valid!", __func__);
10370 return status;
10371 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010372
Jeff Johnson295189b2012-06-20 16:38:30 -070010373 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
10374 {
10375 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
10376 return -EINVAL;
10377 }
10378
10379 pRoamProfile = &pWextState->roamProfile;
10380
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010381 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070010382 {
Jeff Johnsone7245742012-09-05 17:12:55 -070010383 hdd_station_ctx_t *pHddStaCtx;
10384 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010385
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010386 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070010387 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
10388 {
10389 /*QoS not enabled in cfg file*/
10390 pRoamProfile->uapsd_mask = 0;
10391 }
10392 else
10393 {
10394 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010395 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070010396 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
10397 }
10398
10399 pRoamProfile->SSIDs.numOfSSIDs = 1;
10400 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
10401 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010402 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070010403 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
10404 ssid, ssid_len);
10405
10406 if (bssid)
10407 {
10408 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
10409 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
10410 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010411 /* Save BSSID in seperate variable as well, as RoamProfile
10412 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070010413 case of join failure we should send valid BSSID to supplicant
10414 */
10415 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
10416 WNI_CFG_BSSID_LEN);
10417 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070010418 else
10419 {
10420 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
10421 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010422
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010423 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
10424 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010425 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
10426 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010427 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010428 /*set gen ie*/
10429 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
10430 /*set auth*/
10431 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
10432 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010433#ifdef FEATURE_WLAN_WAPI
10434 if (pAdapter->wapi_info.nWapiMode)
10435 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010436 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010437 switch (pAdapter->wapi_info.wapiAuthMode)
10438 {
10439 case WAPI_AUTH_MODE_PSK:
10440 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010441 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010442 pAdapter->wapi_info.wapiAuthMode);
10443 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
10444 break;
10445 }
10446 case WAPI_AUTH_MODE_CERT:
10447 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010448 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010449 pAdapter->wapi_info.wapiAuthMode);
10450 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
10451 break;
10452 }
10453 } // End of switch
10454 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
10455 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
10456 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010457 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010458 pRoamProfile->AuthType.numEntries = 1;
10459 pRoamProfile->EncryptionType.numEntries = 1;
10460 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10461 pRoamProfile->mcEncryptionType.numEntries = 1;
10462 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10463 }
10464 }
10465#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010466#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010467 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010468 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10469 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
10470 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010471 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
10472 sizeof (tSirGtkOffloadParams));
10473 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010474 }
10475#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010476 pRoamProfile->csrPersona = pAdapter->device_mode;
10477
Jeff Johnson32d95a32012-09-10 13:15:23 -070010478 if( operatingChannel )
10479 {
10480 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
10481 pRoamProfile->ChannelInfo.numOfChannels = 1;
10482 }
Chet Lanctot186b5732013-03-18 10:26:30 -070010483 else
10484 {
10485 pRoamProfile->ChannelInfo.ChannelList = NULL;
10486 pRoamProfile->ChannelInfo.numOfChannels = 0;
10487 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010488 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
10489 {
10490 hdd_select_cbmode(pAdapter,operatingChannel);
10491 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010492
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010493 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
10494 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010495 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010496 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010497 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
10498 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010499 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10500 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053010501 {
10502 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10503 "%s: Set HDD connState to eConnectionState_Connecting",
10504 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010505 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
10506 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053010507 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010508 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010509 pAdapter->sessionId, pRoamProfile, &roamId);
10510
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010511 if ((eHAL_STATUS_SUCCESS != status) &&
10512 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10513 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010514
10515 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010516 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
10517 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
10518 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010519 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010520 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010521 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010522
10523 pRoamProfile->ChannelInfo.ChannelList = NULL;
10524 pRoamProfile->ChannelInfo.numOfChannels = 0;
10525
Jeff Johnson295189b2012-06-20 16:38:30 -070010526 }
10527 else
10528 {
10529 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
10530 return -EINVAL;
10531 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010532 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010533 return status;
10534}
10535
10536/*
10537 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
10538 * This function is used to set the authentication type (OPEN/SHARED).
10539 *
10540 */
10541static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
10542 enum nl80211_auth_type auth_type)
10543{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010544 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010545 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10546
10547 ENTER();
10548
10549 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010550 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070010551 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010552 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010553 hddLog(VOS_TRACE_LEVEL_INFO,
10554 "%s: set authentication type to AUTOSWITCH", __func__);
10555 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
10556 break;
10557
10558 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010559#ifdef WLAN_FEATURE_VOWIFI_11R
10560 case NL80211_AUTHTYPE_FT:
10561#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010562 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010563 "%s: set authentication type to OPEN", __func__);
10564 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
10565 break;
10566
10567 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010568 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010569 "%s: set authentication type to SHARED", __func__);
10570 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
10571 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010572#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010573 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010574 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010575 "%s: set authentication type to CCKM WPA", __func__);
10576 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
10577 break;
10578#endif
10579
10580
10581 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010582 hddLog(VOS_TRACE_LEVEL_ERROR,
10583 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010584 auth_type);
10585 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
10586 return -EINVAL;
10587 }
10588
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010589 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010590 pHddStaCtx->conn_info.authType;
10591 return 0;
10592}
10593
10594/*
10595 * FUNCTION: wlan_hdd_set_akm_suite
10596 * This function is used to set the key mgmt type(PSK/8021x).
10597 *
10598 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010599static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010600 u32 key_mgmt
10601 )
10602{
10603 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10604 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053010605 /* Should be in ieee802_11_defs.h */
10606#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
10607#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070010608 /*set key mgmt type*/
10609 switch(key_mgmt)
10610 {
10611 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053010612 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010613#ifdef WLAN_FEATURE_VOWIFI_11R
10614 case WLAN_AKM_SUITE_FT_PSK:
10615#endif
10616 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070010617 __func__);
10618 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
10619 break;
10620
10621 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053010622 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010623#ifdef WLAN_FEATURE_VOWIFI_11R
10624 case WLAN_AKM_SUITE_FT_8021X:
10625#endif
10626 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070010627 __func__);
10628 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10629 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010630#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010631#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
10632#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
10633 case WLAN_AKM_SUITE_CCKM:
10634 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
10635 __func__);
10636 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
10637 break;
10638#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070010639#ifndef WLAN_AKM_SUITE_OSEN
10640#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
10641 case WLAN_AKM_SUITE_OSEN:
10642 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
10643 __func__);
10644 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10645 break;
10646#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010647
10648 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010649 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010650 __func__, key_mgmt);
10651 return -EINVAL;
10652
10653 }
10654 return 0;
10655}
10656
10657/*
10658 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010659 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070010660 * (NONE/WEP40/WEP104/TKIP/CCMP).
10661 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010662static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
10663 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070010664 bool ucast
10665 )
10666{
10667 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010668 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010669 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10670
10671 ENTER();
10672
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010673 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010674 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010675 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070010676 __func__, cipher);
10677 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10678 }
10679 else
10680 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010681
Jeff Johnson295189b2012-06-20 16:38:30 -070010682 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010683 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010684 {
10685 case IW_AUTH_CIPHER_NONE:
10686 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10687 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010688
Jeff Johnson295189b2012-06-20 16:38:30 -070010689 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010690 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070010691 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010692
Jeff Johnson295189b2012-06-20 16:38:30 -070010693 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010694 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070010695 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010696
Jeff Johnson295189b2012-06-20 16:38:30 -070010697 case WLAN_CIPHER_SUITE_TKIP:
10698 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
10699 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010700
Jeff Johnson295189b2012-06-20 16:38:30 -070010701 case WLAN_CIPHER_SUITE_CCMP:
10702 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10703 break;
10704#ifdef FEATURE_WLAN_WAPI
10705 case WLAN_CIPHER_SUITE_SMS4:
10706 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
10707 break;
10708#endif
10709
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010710#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010711 case WLAN_CIPHER_SUITE_KRK:
10712 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
10713 break;
10714#endif
10715 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010716 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010717 __func__, cipher);
10718 return -EOPNOTSUPP;
10719 }
10720 }
10721
10722 if (ucast)
10723 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010724 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010725 __func__, encryptionType);
10726 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10727 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010728 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010729 encryptionType;
10730 }
10731 else
10732 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010733 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010734 __func__, encryptionType);
10735 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
10736 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
10737 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
10738 }
10739
10740 return 0;
10741}
10742
10743
10744/*
10745 * FUNCTION: wlan_hdd_cfg80211_set_ie
10746 * This function is used to parse WPA/RSN IE's.
10747 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010748int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
10749 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070010750 size_t ie_len
10751 )
10752{
10753 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10754 u8 *genie = ie;
10755 v_U16_t remLen = ie_len;
10756#ifdef FEATURE_WLAN_WAPI
10757 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
10758 u16 *tmp;
10759 v_U16_t akmsuiteCount;
10760 int *akmlist;
10761#endif
10762 ENTER();
10763
10764 /* clear previous assocAddIE */
10765 pWextState->assocAddIE.length = 0;
10766 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010767 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010768
10769 while (remLen >= 2)
10770 {
10771 v_U16_t eLen = 0;
10772 v_U8_t elementId;
10773 elementId = *genie++;
10774 eLen = *genie++;
10775 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010776
Arif Hussain6d2a3322013-11-17 19:50:10 -080010777 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070010778 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010779
10780 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070010781 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010782 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010783 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 -070010784 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010785 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010786 "%s: Invalid WPA IE", __func__);
10787 return -EINVAL;
10788 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010789 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070010790 {
10791 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010792 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010793 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010794
Jeff Johnson295189b2012-06-20 16:38:30 -070010795 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10796 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010797 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
10798 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010799 VOS_ASSERT(0);
10800 return -ENOMEM;
10801 }
10802 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10803 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10804 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010805
Jeff Johnson295189b2012-06-20 16:38:30 -070010806 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
10807 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10808 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10809 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010810 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
10811 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010812 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
10813 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10814 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
10815 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
10816 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
10817 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010818 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053010819 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010820 {
10821 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010822 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010823 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010824
Jeff Johnson295189b2012-06-20 16:38:30 -070010825 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10826 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010827 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10828 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010829 VOS_ASSERT(0);
10830 return -ENOMEM;
10831 }
10832 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10833 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10834 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010835
Jeff Johnson295189b2012-06-20 16:38:30 -070010836 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10837 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10838 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010839#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010840 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
10841 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010842 /*Consider WFD IE, only for P2P Client */
10843 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10844 {
10845 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010846 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010847 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010848
Jeff Johnson295189b2012-06-20 16:38:30 -070010849 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10850 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010851 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10852 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010853 VOS_ASSERT(0);
10854 return -ENOMEM;
10855 }
10856 // WFD IE is saved to Additional IE ; it should be accumulated to handle
10857 // WPS IE + P2P IE + WFD IE
10858 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10859 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010860
Jeff Johnson295189b2012-06-20 16:38:30 -070010861 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10862 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10863 }
10864#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010865 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010866 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010867 HS20_OUI_TYPE_SIZE)) )
10868 {
10869 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010870 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010871 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010872
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010873 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10874 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010875 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10876 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010877 VOS_ASSERT(0);
10878 return -ENOMEM;
10879 }
10880 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10881 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010882
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010883 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10884 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10885 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010886 /* Appending OSEN Information Element in Assiciation Request */
10887 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
10888 OSEN_OUI_TYPE_SIZE)) )
10889 {
10890 v_U16_t curAddIELen = pWextState->assocAddIE.length;
10891 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
10892 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010893
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010894 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10895 {
10896 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10897 "Need bigger buffer space");
10898 VOS_ASSERT(0);
10899 return -ENOMEM;
10900 }
10901 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10902 pWextState->assocAddIE.length += eLen + 2;
10903
10904 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
10905 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10906 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10907 }
10908
10909 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070010910 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
10911
10912 /* populating as ADDIE in beacon frames */
10913 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10914 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
10915 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
10916 {
10917 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10918 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10919 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10920 {
10921 hddLog(LOGE,
10922 "Coldn't pass "
10923 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
10924 }
10925 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
10926 else
10927 hddLog(LOGE,
10928 "Could not pass on "
10929 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
10930
10931 /* IBSS mode doesn't contain params->proberesp_ies still
10932 beaconIE's need to be populated in probe response frames */
10933 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
10934 {
10935 u16 rem_probe_resp_ie_len = eLen + 2;
10936 u8 probe_rsp_ie_len[3] = {0};
10937 u8 counter = 0;
10938
10939 /* Check Probe Resp Length if it is greater then 255 then
10940 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
10941 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
10942 not able Store More then 255 bytes into One Variable */
10943
10944 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
10945 {
10946 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
10947 {
10948 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
10949 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
10950 }
10951 else
10952 {
10953 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
10954 rem_probe_resp_ie_len = 0;
10955 }
10956 }
10957
10958 rem_probe_resp_ie_len = 0;
10959
10960 if (probe_rsp_ie_len[0] > 0)
10961 {
10962 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10963 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
10964 (tANI_U8*)(genie - 2),
10965 probe_rsp_ie_len[0], NULL,
10966 eANI_BOOLEAN_FALSE)
10967 == eHAL_STATUS_FAILURE)
10968 {
10969 hddLog(LOGE,
10970 "Could not pass"
10971 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
10972 }
10973 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10974 }
10975
10976 if (probe_rsp_ie_len[1] > 0)
10977 {
10978 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10979 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
10980 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10981 probe_rsp_ie_len[1], NULL,
10982 eANI_BOOLEAN_FALSE)
10983 == eHAL_STATUS_FAILURE)
10984 {
10985 hddLog(LOGE,
10986 "Could not pass"
10987 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
10988 }
10989 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10990 }
10991
10992 if (probe_rsp_ie_len[2] > 0)
10993 {
10994 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10995 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
10996 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10997 probe_rsp_ie_len[2], NULL,
10998 eANI_BOOLEAN_FALSE)
10999 == eHAL_STATUS_FAILURE)
11000 {
11001 hddLog(LOGE,
11002 "Could not pass"
11003 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
11004 }
11005 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
11006 }
11007
11008 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11009 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
11010 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11011 {
11012 hddLog(LOGE,
11013 "Could not pass"
11014 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
11015 }
11016 }
11017 else
11018 {
11019 // Reset WNI_CFG_PROBE_RSP Flags
11020 wlan_hdd_reset_prob_rspies(pAdapter);
11021
11022 hddLog(VOS_TRACE_LEVEL_INFO,
11023 "%s: No Probe Response IE received in set beacon",
11024 __func__);
11025 }
11026 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011027 break;
11028 case DOT11F_EID_RSN:
11029 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
11030 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11031 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
11032 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
11033 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
11034 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011035 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
11036 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011037 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011038 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011039 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011040 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011041
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011042 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11043 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011044 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11045 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011046 VOS_ASSERT(0);
11047 return -ENOMEM;
11048 }
11049 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11050 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011051
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011052 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11053 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11054 break;
11055 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011056#ifdef FEATURE_WLAN_WAPI
11057 case WLAN_EID_WAPI:
11058 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011059 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011060 pAdapter->wapi_info.nWapiMode);
11061 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011062 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070011063 akmsuiteCount = WPA_GET_LE16(tmp);
11064 tmp = tmp + 1;
11065 akmlist = (int *)(tmp);
11066 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
11067 {
11068 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
11069 }
11070 else
11071 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011072 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070011073 VOS_ASSERT(0);
11074 return -EINVAL;
11075 }
11076
11077 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
11078 {
11079 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011080 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011081 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011082 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011083 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011084 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011085 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011086 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011087 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
11088 }
11089 break;
11090#endif
11091 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011092 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011093 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011094 /* when Unknown IE is received we should break and continue
11095 * to the next IE in the buffer instead we were returning
11096 * so changing this to break */
11097 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011098 }
11099 genie += eLen;
11100 remLen -= eLen;
11101 }
11102 EXIT();
11103 return 0;
11104}
11105
11106/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053011107 * FUNCTION: hdd_isWPAIEPresent
11108 * Parse the received IE to find the WPA IE
11109 *
11110 */
11111static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
11112{
11113 v_U8_t eLen = 0;
11114 v_U16_t remLen = ie_len;
11115 v_U8_t elementId = 0;
11116
11117 while (remLen >= 2)
11118 {
11119 elementId = *ie++;
11120 eLen = *ie++;
11121 remLen -= 2;
11122 if (eLen > remLen)
11123 {
11124 hddLog(VOS_TRACE_LEVEL_ERROR,
11125 "%s: IE length is wrong %d", __func__, eLen);
11126 return FALSE;
11127 }
11128 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
11129 {
11130 /* OUI - 0x00 0X50 0XF2
11131 WPA Information Element - 0x01
11132 WPA version - 0x01*/
11133 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
11134 return TRUE;
11135 }
11136 ie += eLen;
11137 remLen -= eLen;
11138 }
11139 return FALSE;
11140}
11141
11142/*
Jeff Johnson295189b2012-06-20 16:38:30 -070011143 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011144 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011145 * parameters during connect operation.
11146 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011147int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011148 struct cfg80211_connect_params *req
11149 )
11150{
11151 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011152 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011153 ENTER();
11154
11155 /*set wpa version*/
11156 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
11157
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011158 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011159 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053011160 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011161 {
11162 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11163 }
11164 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
11165 {
11166 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11167 }
11168 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011169
11170 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011171 pWextState->wpaVersion);
11172
11173 /*set authentication type*/
11174 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
11175
11176 if (0 > status)
11177 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011178 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011179 "%s: failed to set authentication type ", __func__);
11180 return status;
11181 }
11182
11183 /*set key mgmt type*/
11184 if (req->crypto.n_akm_suites)
11185 {
11186 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
11187 if (0 > status)
11188 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011189 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070011190 __func__);
11191 return status;
11192 }
11193 }
11194
11195 /*set pairwise cipher type*/
11196 if (req->crypto.n_ciphers_pairwise)
11197 {
11198 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
11199 req->crypto.ciphers_pairwise[0], true);
11200 if (0 > status)
11201 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011202 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011203 "%s: failed to set unicast cipher type", __func__);
11204 return status;
11205 }
11206 }
11207 else
11208 {
11209 /*Reset previous cipher suite to none*/
11210 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
11211 if (0 > status)
11212 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011213 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011214 "%s: failed to set unicast cipher type", __func__);
11215 return status;
11216 }
11217 }
11218
11219 /*set group cipher type*/
11220 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
11221 false);
11222
11223 if (0 > status)
11224 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011225 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070011226 __func__);
11227 return status;
11228 }
11229
Chet Lanctot186b5732013-03-18 10:26:30 -070011230#ifdef WLAN_FEATURE_11W
11231 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
11232#endif
11233
Jeff Johnson295189b2012-06-20 16:38:30 -070011234 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
11235 if (req->ie_len)
11236 {
11237 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
11238 if ( 0 > status)
11239 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011240 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011241 __func__);
11242 return status;
11243 }
11244 }
11245
11246 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011247 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011248 {
11249 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
11250 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
11251 )
11252 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011253 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070011254 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
11255 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011256 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011257 __func__);
11258 return -EOPNOTSUPP;
11259 }
11260 else
11261 {
11262 u8 key_len = req->key_len;
11263 u8 key_idx = req->key_idx;
11264
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011265 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011266 && (CSR_MAX_NUM_KEY > key_idx)
11267 )
11268 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011269 hddLog(VOS_TRACE_LEVEL_INFO,
11270 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011271 __func__, key_idx, key_len);
11272 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011273 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011274 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011275 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011276 (u8)key_len;
11277 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
11278 }
11279 }
11280 }
11281 }
11282
11283 return status;
11284}
11285
11286/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011287 * FUNCTION: wlan_hdd_try_disconnect
11288 * This function is used to disconnect from previous
11289 * connection
11290 */
11291static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
11292{
11293 long ret = 0;
11294 hdd_station_ctx_t *pHddStaCtx;
11295 eMib_dot11DesiredBssType connectedBssType;
11296
11297 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11298
11299 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
11300
11301 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
11302 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
11303 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
11304 {
11305 /* Issue disconnect to CSR */
11306 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11307 if( eHAL_STATUS_SUCCESS ==
11308 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11309 pAdapter->sessionId,
11310 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11311 {
11312 ret = wait_for_completion_interruptible_timeout(
11313 &pAdapter->disconnect_comp_var,
11314 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11315 if (0 >= ret)
11316 {
11317 hddLog(LOGE, FL("Failed to receive disconnect event"));
11318 return -EALREADY;
11319 }
11320 }
11321 }
11322 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
11323 {
11324 ret = wait_for_completion_interruptible_timeout(
11325 &pAdapter->disconnect_comp_var,
11326 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11327 if (0 >= ret)
11328 {
11329 hddLog(LOGE, FL("Failed to receive disconnect event"));
11330 return -EALREADY;
11331 }
11332 }
11333
11334 return 0;
11335}
11336
11337/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053011338 * FUNCTION: __wlan_hdd_cfg80211_connect
11339 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011340 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011341static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011342 struct net_device *ndev,
11343 struct cfg80211_connect_params *req
11344 )
11345{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011346 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011347 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011348 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053011349 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011350
11351 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011352
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011353 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11354 TRACE_CODE_HDD_CFG80211_CONNECT,
11355 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011356 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011357 "%s: device_mode = %s (%d)", __func__,
11358 hdd_device_modetoString(pAdapter->device_mode),
11359 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011360
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011361 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011362 if (!pHddCtx)
11363 {
11364 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11365 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011366 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011367 }
11368
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011369 status = wlan_hdd_validate_context(pHddCtx);
11370
11371 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011372 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11374 "%s: HDD context is not valid", __func__);
11375 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011376 }
11377
Agarwal Ashish51325b52014-06-16 16:50:49 +053011378 if (vos_max_concurrent_connections_reached()) {
11379 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11380 return -ECONNREFUSED;
11381 }
11382
Jeff Johnson295189b2012-06-20 16:38:30 -070011383#ifdef WLAN_BTAMP_FEATURE
11384 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011385 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070011386 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011387 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011388 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011389 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070011390 }
11391#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011392
11393 //If Device Mode is Station Concurrent Sessions Exit BMps
11394 //P2P Mode will be taken care in Open/close adapter
11395 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011396 (vos_concurrent_open_sessions_running())) {
11397 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
11398 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011399 }
11400
11401 /*Try disconnecting if already in connected state*/
11402 status = wlan_hdd_try_disconnect(pAdapter);
11403 if ( 0 > status)
11404 {
11405 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11406 " connection"));
11407 return -EALREADY;
11408 }
11409
Jeff Johnson295189b2012-06-20 16:38:30 -070011410 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011411 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070011412
11413 if ( 0 > status)
11414 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011415 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070011416 __func__);
11417 return status;
11418 }
Mohit Khanna765234a2012-09-11 15:08:35 -070011419 if ( req->channel )
11420 {
11421 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
11422 req->ssid_len, req->bssid,
11423 req->channel->hw_value);
11424 }
11425 else
11426 {
11427 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011428 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070011429 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011430
11431 if (0 > status)
11432 {
11433 //ReEnable BMPS if disabled
11434 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
11435 (NULL != pHddCtx))
11436 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011437 if (pHddCtx->hdd_wlan_suspended)
11438 {
11439 hdd_set_pwrparams(pHddCtx);
11440 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011441 //ReEnable Bmps and Imps back
11442 hdd_enable_bmps_imps(pHddCtx);
11443 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011444 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011445 return status;
11446 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011447 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011448 EXIT();
11449 return status;
11450}
11451
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011452static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
11453 struct net_device *ndev,
11454 struct cfg80211_connect_params *req)
11455{
11456 int ret;
11457 vos_ssr_protect(__func__);
11458 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
11459 vos_ssr_unprotect(__func__);
11460
11461 return ret;
11462}
Jeff Johnson295189b2012-06-20 16:38:30 -070011463
11464/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011465 * FUNCTION: wlan_hdd_disconnect
11466 * This function is used to issue a disconnect request to SME
11467 */
11468int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
11469{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011470 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011471 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011472 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011473 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011474
11475 status = wlan_hdd_validate_context(pHddCtx);
11476
11477 if (0 != status)
11478 {
11479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11480 "%s: HDD context is not valid", __func__);
11481 return status;
11482 }
11483
11484 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011485
Agarwal Ashish47d18112014-08-04 19:55:07 +053011486 /* Need to apply spin lock before decreasing active sessions
11487 * as there can be chance for double decrement if context switch
11488 * Calls hdd_DisConnectHandler.
11489 */
11490
11491 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011492 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11493 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011494 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11495 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053011496 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
11497 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011498
Abhishek Singhf4669da2014-05-26 15:07:49 +053011499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053011500 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
11501
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011502 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011503
Mihir Shete182a0b22014-08-18 16:08:48 +053011504 /*
11505 * stop tx queues before deleting STA/BSS context from the firmware.
11506 * tx has to be disabled because the firmware can get busy dropping
11507 * the tx frames after BSS/STA has been deleted and will not send
11508 * back a response resulting in WDI timeout
11509 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053011510 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053011511 netif_tx_disable(pAdapter->dev);
11512 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011513
Mihir Shete182a0b22014-08-18 16:08:48 +053011514 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011515 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11516 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011517 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
11518 {
11519 hddLog(VOS_TRACE_LEVEL_INFO,
11520 FL("status = %d, already disconnected"),
11521 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011522
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011523 }
11524 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011525 {
11526 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011527 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011528 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011529 result = -EINVAL;
11530 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011531 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011532 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011533 &pAdapter->disconnect_comp_var,
11534 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011535 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011536 {
11537 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011538 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011539 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011540 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011541 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011542 {
11543 hddLog(VOS_TRACE_LEVEL_ERROR,
11544 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011545 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011546 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011547disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011548 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11549 FL("Set HDD connState to eConnectionState_NotConnected"));
11550 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
11551
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011552 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011553}
11554
11555
11556/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011557 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070011558 * This function is used to issue a disconnect request to SME
11559 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011560static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011561 struct net_device *dev,
11562 u16 reason
11563 )
11564{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011565 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011566 tCsrRoamProfile *pRoamProfile =
11567 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011568 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011569 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11570 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011571#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011572 tANI_U8 staIdx;
11573#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011574
Jeff Johnson295189b2012-06-20 16:38:30 -070011575 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011576
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011577 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11578 TRACE_CODE_HDD_CFG80211_DISCONNECT,
11579 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011580 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
11581 __func__, hdd_device_modetoString(pAdapter->device_mode),
11582 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011583
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011584 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
11585 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070011586
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011587 status = wlan_hdd_validate_context(pHddCtx);
11588
11589 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011590 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11592 "%s: HDD context is not valid", __func__);
11593 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011594 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011595
Jeff Johnson295189b2012-06-20 16:38:30 -070011596 if (NULL != pRoamProfile)
11597 {
11598 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011599 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
11600 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070011601 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011602 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070011603 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011604 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070011605 switch(reason)
11606 {
11607 case WLAN_REASON_MIC_FAILURE:
11608 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
11609 break;
11610
11611 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
11612 case WLAN_REASON_DISASSOC_AP_BUSY:
11613 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
11614 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
11615 break;
11616
11617 case WLAN_REASON_PREV_AUTH_NOT_VALID:
11618 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053011619 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070011620 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
11621 break;
11622
Jeff Johnson295189b2012-06-20 16:38:30 -070011623 default:
11624 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
11625 break;
11626 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011627 pScanInfo = &pHddCtx->scan_info;
11628 if (pScanInfo->mScanPending)
11629 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011630 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011631 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011632 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011633 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011634 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011635
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011636#ifdef FEATURE_WLAN_TDLS
11637 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011638 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011639 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011640 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
11641 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011642 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011643 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011644 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011645 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011646 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011647 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011648 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011649 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011650 pAdapter->sessionId,
11651 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011652 }
11653 }
11654#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011655 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011656 status = wlan_hdd_disconnect(pAdapter, reasonCode);
11657 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070011658 {
11659 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011660 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011661 __func__, (int)status );
11662 return -EINVAL;
11663 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011664 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011665 else
11666 {
11667 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
11668 "called while in %d state", __func__,
11669 pHddStaCtx->conn_info.connState);
11670 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011671 }
11672 else
11673 {
11674 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
11675 }
11676
11677 return status;
11678}
11679
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011680static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
11681 struct net_device *dev,
11682 u16 reason
11683 )
11684{
11685 int ret;
11686 vos_ssr_protect(__func__);
11687 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
11688 vos_ssr_unprotect(__func__);
11689
11690 return ret;
11691}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011692
Jeff Johnson295189b2012-06-20 16:38:30 -070011693/*
11694 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011695 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011696 * settings in IBSS mode.
11697 */
11698static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011699 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011700 struct cfg80211_ibss_params *params
11701 )
11702{
11703 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011704 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011705 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11706 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011707
Jeff Johnson295189b2012-06-20 16:38:30 -070011708 ENTER();
11709
11710 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070011711 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070011712
11713 if (params->ie_len && ( NULL != params->ie) )
11714 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011715 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11716 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011717 {
11718 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11719 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11720 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011721 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011722 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011723 tDot11fIEWPA dot11WPAIE;
11724 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011725 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011726
Wilson Yang00256342013-10-10 23:13:38 -070011727 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011728 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11729 params->ie_len, DOT11F_EID_WPA);
11730 if ( NULL != ie )
11731 {
11732 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11733 // Unpack the WPA IE
11734 //Skip past the EID byte and length byte - and four byte WiFi OUI
11735 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
11736 &ie[2+4],
11737 ie[1] - 4,
11738 &dot11WPAIE);
11739 /*Extract the multicast cipher, the encType for unicast
11740 cipher for wpa-none is none*/
11741 encryptionType =
11742 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
11743 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011744 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011745
Jeff Johnson295189b2012-06-20 16:38:30 -070011746 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
11747
11748 if (0 > status)
11749 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011750 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011751 __func__);
11752 return status;
11753 }
11754 }
11755
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011756 pWextState->roamProfile.AuthType.authType[0] =
11757 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011758 eCSR_AUTH_TYPE_OPEN_SYSTEM;
11759
11760 if (params->privacy)
11761 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011762 /* Security enabled IBSS, At this time there is no information available
11763 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070011764 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011765 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070011766 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011767 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070011768 *enable privacy bit in beacons */
11769
11770 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11771 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011772 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
11773 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070011774 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11775 pWextState->roamProfile.EncryptionType.numEntries = 1;
11776 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070011777 return status;
11778}
11779
11780/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011781 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011782 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011783 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011784static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011785 struct net_device *dev,
11786 struct cfg80211_ibss_params *params
11787 )
11788{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011789 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011790 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11791 tCsrRoamProfile *pRoamProfile;
11792 int status;
krunal sonie9002db2013-11-25 14:24:17 -080011793 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011794 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11795 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011796
11797 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011798
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011799 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11800 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
11801 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011802 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011803 "%s: device_mode = %s (%d)", __func__,
11804 hdd_device_modetoString(pAdapter->device_mode),
11805 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011806
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011807 status = wlan_hdd_validate_context(pHddCtx);
11808
11809 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011810 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011811 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11812 "%s: HDD context is not valid", __func__);
11813 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011814 }
11815
11816 if (NULL == pWextState)
11817 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011818 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011819 __func__);
11820 return -EIO;
11821 }
11822
Agarwal Ashish51325b52014-06-16 16:50:49 +053011823 if (vos_max_concurrent_connections_reached()) {
11824 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11825 return -ECONNREFUSED;
11826 }
11827
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011828 /*Try disconnecting if already in connected state*/
11829 status = wlan_hdd_try_disconnect(pAdapter);
11830 if ( 0 > status)
11831 {
11832 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11833 " IBSS connection"));
11834 return -EALREADY;
11835 }
11836
Jeff Johnson295189b2012-06-20 16:38:30 -070011837 pRoamProfile = &pWextState->roamProfile;
11838
11839 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
11840 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011841 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011842 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011843 return -EINVAL;
11844 }
11845
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011846 /* BSSID is provided by upper layers hence no need to AUTO generate */
11847 if (NULL != params->bssid) {
11848 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11849 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
11850 hddLog (VOS_TRACE_LEVEL_ERROR,
11851 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11852 return -EIO;
11853 }
11854 }
krunal sonie9002db2013-11-25 14:24:17 -080011855 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
11856 {
11857 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11858 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
11859 {
11860 hddLog (VOS_TRACE_LEVEL_ERROR,
11861 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11862 return -EIO;
11863 }
11864 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
11865 if (!params->bssid)
11866 {
11867 hddLog (VOS_TRACE_LEVEL_ERROR,
11868 "%s:Failed memory allocation", __func__);
11869 return -EIO;
11870 }
11871 vos_mem_copy((v_U8_t *)params->bssid,
11872 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
11873 VOS_MAC_ADDR_SIZE);
11874 alloc_bssid = VOS_TRUE;
11875 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011876
Jeff Johnson295189b2012-06-20 16:38:30 -070011877 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070011878 if (NULL !=
11879#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11880 params->chandef.chan)
11881#else
11882 params->channel)
11883#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011884 {
11885 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011886 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
11887 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
11888 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
11889 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011890
11891 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011892 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070011893 ieee80211_frequency_to_channel(
11894#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11895 params->chandef.chan->center_freq);
11896#else
11897 params->channel->center_freq);
11898#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011899
11900 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
11901 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070011902 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011903 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
11904 __func__);
11905 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070011906 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011907
11908 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011909 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011910 if (channelNum == validChan[indx])
11911 {
11912 break;
11913 }
11914 }
11915 if (indx >= numChans)
11916 {
11917 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011918 __func__, channelNum);
11919 return -EINVAL;
11920 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011921 /* Set the Operational Channel */
11922 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
11923 channelNum);
11924 pRoamProfile->ChannelInfo.numOfChannels = 1;
11925 pHddStaCtx->conn_info.operationChannel = channelNum;
11926 pRoamProfile->ChannelInfo.ChannelList =
11927 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070011928 }
11929
11930 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011931 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070011932 if (status < 0)
11933 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011934 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070011935 __func__);
11936 return status;
11937 }
11938
11939 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011940 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011941 params->ssid_len, params->bssid,
11942 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011943
11944 if (0 > status)
11945 {
11946 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
11947 return status;
11948 }
11949
krunal sonie9002db2013-11-25 14:24:17 -080011950 if (NULL != params->bssid &&
11951 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
11952 alloc_bssid == VOS_TRUE)
11953 {
11954 vos_mem_free(params->bssid);
11955 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011956 return 0;
11957}
11958
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011959static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
11960 struct net_device *dev,
11961 struct cfg80211_ibss_params *params
11962 )
11963{
11964 int ret = 0;
11965
11966 vos_ssr_protect(__func__);
11967 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
11968 vos_ssr_unprotect(__func__);
11969
11970 return ret;
11971}
11972
Jeff Johnson295189b2012-06-20 16:38:30 -070011973/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011974 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011975 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011976 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011977static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011978 struct net_device *dev
11979 )
11980{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011981 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011982 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11983 tCsrRoamProfile *pRoamProfile;
11984 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011985 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011986
11987 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011988
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011989 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11990 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
11991 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011992 status = wlan_hdd_validate_context(pHddCtx);
11993
11994 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011995 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11997 "%s: HDD context is not valid", __func__);
11998 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011999 }
12000
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012001 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
12002 hdd_device_modetoString(pAdapter->device_mode),
12003 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012004 if (NULL == pWextState)
12005 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012006 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012007 __func__);
12008 return -EIO;
12009 }
12010
12011 pRoamProfile = &pWextState->roamProfile;
12012
12013 /* Issue disconnect only if interface type is set to IBSS */
12014 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
12015 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012016 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070012017 __func__);
12018 return -EINVAL;
12019 }
12020
12021 /* Issue Disconnect request */
12022 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12023 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12024 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
12025
12026 return 0;
12027}
12028
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012029static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
12030 struct net_device *dev
12031 )
12032{
12033 int ret = 0;
12034
12035 vos_ssr_protect(__func__);
12036 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
12037 vos_ssr_unprotect(__func__);
12038
12039 return ret;
12040}
12041
Jeff Johnson295189b2012-06-20 16:38:30 -070012042/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012043 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070012044 * This function is used to set the phy parameters
12045 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
12046 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012047static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012048 u32 changed)
12049{
12050 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
12051 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012052 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012053
12054 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012055 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12056 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
12057 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012058 status = wlan_hdd_validate_context(pHddCtx);
12059
12060 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012061 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12063 "%s: HDD context is not valid", __func__);
12064 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012065 }
12066
Jeff Johnson295189b2012-06-20 16:38:30 -070012067 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
12068 {
12069 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
12070 WNI_CFG_RTS_THRESHOLD_STAMAX :
12071 wiphy->rts_threshold;
12072
12073 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012074 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070012075 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012076 hddLog(VOS_TRACE_LEVEL_ERROR,
12077 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012078 __func__, rts_threshold);
12079 return -EINVAL;
12080 }
12081
12082 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
12083 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012084 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012085 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012086 hddLog(VOS_TRACE_LEVEL_ERROR,
12087 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012088 __func__, rts_threshold);
12089 return -EIO;
12090 }
12091
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012092 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012093 rts_threshold);
12094 }
12095
12096 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
12097 {
12098 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
12099 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
12100 wiphy->frag_threshold;
12101
12102 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012103 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012104 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012105 hddLog(VOS_TRACE_LEVEL_ERROR,
12106 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012107 frag_threshold);
12108 return -EINVAL;
12109 }
12110
12111 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
12112 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012113 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012114 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012115 hddLog(VOS_TRACE_LEVEL_ERROR,
12116 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012117 __func__, frag_threshold);
12118 return -EIO;
12119 }
12120
12121 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
12122 frag_threshold);
12123 }
12124
12125 if ((changed & WIPHY_PARAM_RETRY_SHORT)
12126 || (changed & WIPHY_PARAM_RETRY_LONG))
12127 {
12128 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
12129 wiphy->retry_short :
12130 wiphy->retry_long;
12131
12132 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
12133 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
12134 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012135 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012136 __func__, retry_value);
12137 return -EINVAL;
12138 }
12139
12140 if (changed & WIPHY_PARAM_RETRY_SHORT)
12141 {
12142 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
12143 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012144 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012145 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012146 hddLog(VOS_TRACE_LEVEL_ERROR,
12147 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012148 __func__, retry_value);
12149 return -EIO;
12150 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012151 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012152 __func__, retry_value);
12153 }
12154 else if (changed & WIPHY_PARAM_RETRY_SHORT)
12155 {
12156 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
12157 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012158 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012159 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012160 hddLog(VOS_TRACE_LEVEL_ERROR,
12161 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012162 __func__, retry_value);
12163 return -EIO;
12164 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012165 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012166 __func__, retry_value);
12167 }
12168 }
12169
12170 return 0;
12171}
12172
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012173static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
12174 u32 changed)
12175{
12176 int ret;
12177
12178 vos_ssr_protect(__func__);
12179 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
12180 vos_ssr_unprotect(__func__);
12181
12182 return ret;
12183}
12184
Jeff Johnson295189b2012-06-20 16:38:30 -070012185/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012186 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012187 * This function is used to set the txpower
12188 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012189static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012190#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12191 struct wireless_dev *wdev,
12192#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012193#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012194 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012195#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012196 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012197#endif
12198 int dbm)
12199{
12200 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012201 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012202 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12203 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012204 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012205
12206 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012207 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12208 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
12209 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012210 status = wlan_hdd_validate_context(pHddCtx);
12211
12212 if (0 != status)
12213 {
12214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12215 "%s: HDD context is not valid", __func__);
12216 return status;
12217 }
12218
12219 hHal = pHddCtx->hHal;
12220
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012221 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
12222 dbm, ccmCfgSetCallback,
12223 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012224 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012225 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012226 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
12227 return -EIO;
12228 }
12229
12230 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
12231 dbm);
12232
12233 switch(type)
12234 {
12235 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
12236 /* Fall through */
12237 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
12238 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
12239 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012240 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
12241 __func__);
12242 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012243 }
12244 break;
12245 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012246 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012247 __func__);
12248 return -EOPNOTSUPP;
12249 break;
12250 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012251 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
12252 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070012253 return -EIO;
12254 }
12255
12256 return 0;
12257}
12258
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012259static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
12260#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12261 struct wireless_dev *wdev,
12262#endif
12263#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12264 enum tx_power_setting type,
12265#else
12266 enum nl80211_tx_power_setting type,
12267#endif
12268 int dbm)
12269{
12270 int ret;
12271 vos_ssr_protect(__func__);
12272 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
12273#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12274 wdev,
12275#endif
12276#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12277 type,
12278#else
12279 type,
12280#endif
12281 dbm);
12282 vos_ssr_unprotect(__func__);
12283
12284 return ret;
12285}
12286
Jeff Johnson295189b2012-06-20 16:38:30 -070012287/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012288 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012289 * This function is used to read the txpower
12290 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012291static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012292#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12293 struct wireless_dev *wdev,
12294#endif
12295 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070012296{
12297
12298 hdd_adapter_t *pAdapter;
12299 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012300 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012301
Jeff Johnsone7245742012-09-05 17:12:55 -070012302 ENTER();
12303
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012304 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012305
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012306 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012307 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012308 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12309 "%s: HDD context is not valid", __func__);
12310 *dbm = 0;
12311 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012312 }
12313
Jeff Johnson295189b2012-06-20 16:38:30 -070012314 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
12315 if (NULL == pAdapter)
12316 {
12317 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
12318 return -ENOENT;
12319 }
12320
12321 wlan_hdd_get_classAstats(pAdapter);
12322 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
12323
Jeff Johnsone7245742012-09-05 17:12:55 -070012324 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012325 return 0;
12326}
12327
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012328static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
12329#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12330 struct wireless_dev *wdev,
12331#endif
12332 int *dbm)
12333{
12334 int ret;
12335
12336 vos_ssr_protect(__func__);
12337 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
12338#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12339 wdev,
12340#endif
12341 dbm);
12342 vos_ssr_unprotect(__func__);
12343
12344 return ret;
12345}
12346
12347
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012348static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070012349 u8* mac, struct station_info *sinfo)
12350{
12351 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12352 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12353 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053012354 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070012355
12356 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
12357 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012358
12359 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
12360 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
12361 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
12362 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
12363 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
12364 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
12365 tANI_U16 maxRate = 0;
12366 tANI_U16 myRate;
12367 tANI_U16 currentRate = 0;
12368 tANI_U8 maxSpeedMCS = 0;
12369 tANI_U8 maxMCSIdx = 0;
12370 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053012371 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012372 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012373 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012374
Leo Chang6f8870f2013-03-26 18:11:36 -070012375#ifdef WLAN_FEATURE_11AC
12376 tANI_U32 vht_mcs_map;
12377 eDataRate11ACMaxMcs vhtMaxMcs;
12378#endif /* WLAN_FEATURE_11AC */
12379
Jeff Johnsone7245742012-09-05 17:12:55 -070012380 ENTER();
12381
Jeff Johnson295189b2012-06-20 16:38:30 -070012382 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
12383 (0 == ssidlen))
12384 {
12385 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
12386 " Invalid ssidlen, %d", __func__, ssidlen);
12387 /*To keep GUI happy*/
12388 return 0;
12389 }
12390
Mukul Sharma811205f2014-07-09 21:07:30 +053012391 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
12392 {
12393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12394 "%s: Roaming in progress, so unable to proceed this request", __func__);
12395 return 0;
12396 }
12397
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012398 status = wlan_hdd_validate_context(pHddCtx);
12399
12400 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012401 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12403 "%s: HDD context is not valid", __func__);
12404 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012405 }
12406
Jeff Johnson295189b2012-06-20 16:38:30 -070012407
Kiet Lam3b17fc82013-09-27 05:24:08 +053012408 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
12409 sinfo->filled |= STATION_INFO_SIGNAL;
12410
c_hpothu09f19542014-05-30 21:53:31 +053012411 wlan_hdd_get_station_stats(pAdapter);
12412 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
12413
12414 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053012415 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
12416 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053012417 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053012418 {
12419 rate_flags = pAdapter->maxRateFlags;
12420 }
c_hpothu44ff4e02014-05-08 00:13:57 +053012421
Jeff Johnson295189b2012-06-20 16:38:30 -070012422 //convert to the UI units of 100kbps
12423 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
12424
12425#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070012426 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 -070012427 sinfo->signal,
12428 pCfg->reportMaxLinkSpeed,
12429 myRate,
12430 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012431 (int) pCfg->linkSpeedRssiMid,
12432 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070012433 (int) rate_flags,
12434 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012435#endif //LINKSPEED_DEBUG_ENABLED
12436
12437 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
12438 {
12439 // we do not want to necessarily report the current speed
12440 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
12441 {
12442 // report the max possible speed
12443 rssidx = 0;
12444 }
12445 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
12446 {
12447 // report the max possible speed with RSSI scaling
12448 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
12449 {
12450 // report the max possible speed
12451 rssidx = 0;
12452 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012453 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070012454 {
12455 // report middle speed
12456 rssidx = 1;
12457 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012458 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
12459 {
12460 // report middle speed
12461 rssidx = 2;
12462 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012463 else
12464 {
12465 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012466 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070012467 }
12468 }
12469 else
12470 {
12471 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
12472 hddLog(VOS_TRACE_LEVEL_ERROR,
12473 "%s: Invalid value for reportMaxLinkSpeed: %u",
12474 __func__, pCfg->reportMaxLinkSpeed);
12475 rssidx = 0;
12476 }
12477
12478 maxRate = 0;
12479
12480 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012481 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
12482 OperationalRates, &ORLeng))
12483 {
12484 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12485 /*To keep GUI happy*/
12486 return 0;
12487 }
12488
Jeff Johnson295189b2012-06-20 16:38:30 -070012489 for (i = 0; i < ORLeng; i++)
12490 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012491 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012492 {
12493 /* Validate Rate Set */
12494 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
12495 {
12496 currentRate = supported_data_rate[j].supported_rate[rssidx];
12497 break;
12498 }
12499 }
12500 /* Update MAX rate */
12501 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12502 }
12503
12504 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012505 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
12506 ExtendedRates, &ERLeng))
12507 {
12508 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12509 /*To keep GUI happy*/
12510 return 0;
12511 }
12512
Jeff Johnson295189b2012-06-20 16:38:30 -070012513 for (i = 0; i < ERLeng; i++)
12514 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012515 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012516 {
12517 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
12518 {
12519 currentRate = supported_data_rate[j].supported_rate[rssidx];
12520 break;
12521 }
12522 }
12523 /* Update MAX rate */
12524 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12525 }
c_hpothu79aab322014-07-14 21:11:01 +053012526
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012527 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053012528 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012529 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053012530 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070012531 {
c_hpothu79aab322014-07-14 21:11:01 +053012532 if (rate_flags & eHAL_TX_RATE_VHT80)
12533 mode = 2;
12534 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
12535 mode = 1;
12536 else
12537 mode = 0;
12538
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012539 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
12540 MCSRates, &MCSLeng))
12541 {
12542 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12543 /*To keep GUI happy*/
12544 return 0;
12545 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012546 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070012547#ifdef WLAN_FEATURE_11AC
12548 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012549 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070012550 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012551 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012552 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070012553 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070012554 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012555 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070012556 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012557 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070012558 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012559 maxMCSIdx = 7;
12560 }
12561 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
12562 {
12563 maxMCSIdx = 8;
12564 }
12565 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
12566 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012567 //VHT20 is supporting 0~8
12568 if (rate_flags & eHAL_TX_RATE_VHT20)
12569 maxMCSIdx = 8;
12570 else
12571 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070012572 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012573
c_hpothu79aab322014-07-14 21:11:01 +053012574 if (0 != rssidx)/*check for scaled */
12575 {
12576 //get middle rate MCS index if rssi=1/2
12577 for (i=0; i <= maxMCSIdx; i++)
12578 {
12579 if (sinfo->signal <= rssiMcsTbl[mode][i])
12580 {
12581 maxMCSIdx = i;
12582 break;
12583 }
12584 }
12585 }
12586
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012587 if (rate_flags & eHAL_TX_RATE_VHT80)
12588 {
12589 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
12590 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
12591 }
12592 else if (rate_flags & eHAL_TX_RATE_VHT40)
12593 {
12594 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
12595 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
12596 }
12597 else if (rate_flags & eHAL_TX_RATE_VHT20)
12598 {
12599 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
12600 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
12601 }
12602
Leo Chang6f8870f2013-03-26 18:11:36 -070012603 maxSpeedMCS = 1;
12604 if (currentRate > maxRate)
12605 {
12606 maxRate = currentRate;
12607 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012608
Leo Chang6f8870f2013-03-26 18:11:36 -070012609 }
12610 else
12611#endif /* WLAN_FEATURE_11AC */
12612 {
12613 if (rate_flags & eHAL_TX_RATE_HT40)
12614 {
12615 rateFlag |= 1;
12616 }
12617 if (rate_flags & eHAL_TX_RATE_SGI)
12618 {
12619 rateFlag |= 2;
12620 }
12621
Girish Gowli01abcee2014-07-31 20:18:55 +053012622 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053012623 if (rssidx == 1 || rssidx == 2)
12624 {
12625 //get middle rate MCS index if rssi=1/2
12626 for (i=0; i <= 7; i++)
12627 {
12628 if (sinfo->signal <= rssiMcsTbl[mode][i])
12629 {
12630 temp = i+1;
12631 break;
12632 }
12633 }
12634 }
c_hpothu79aab322014-07-14 21:11:01 +053012635
12636 for (i = 0; i < MCSLeng; i++)
12637 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012638 for (j = 0; j < temp; j++)
12639 {
12640 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
12641 {
12642 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
12643 break;
12644 }
12645 }
12646 if ((j < temp) && (currentRate > maxRate))
12647 {
12648 maxRate = currentRate;
12649 maxSpeedMCS = 1;
12650 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
12651 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012652 }
12653 }
12654 }
12655
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012656 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
12657 {
12658 maxRate = myRate;
12659 maxSpeedMCS = 1;
12660 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12661 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012662 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053012663 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070012664 {
12665 maxRate = myRate;
12666 if (rate_flags & eHAL_TX_RATE_LEGACY)
12667 {
12668 maxSpeedMCS = 0;
12669 }
12670 else
12671 {
12672 maxSpeedMCS = 1;
12673 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12674 }
12675 }
12676
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012677 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070012678 {
12679 sinfo->txrate.legacy = maxRate;
12680#ifdef LINKSPEED_DEBUG_ENABLED
12681 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
12682#endif //LINKSPEED_DEBUG_ENABLED
12683 }
12684 else
12685 {
12686 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070012687#ifdef WLAN_FEATURE_11AC
12688 sinfo->txrate.nss = 1;
12689 if (rate_flags & eHAL_TX_RATE_VHT80)
12690 {
12691 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012692 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070012693 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012694 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070012695 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012696 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12697 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12698 }
12699 else if (rate_flags & eHAL_TX_RATE_VHT20)
12700 {
12701 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12702 }
12703#endif /* WLAN_FEATURE_11AC */
12704 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
12705 {
12706 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12707 if (rate_flags & eHAL_TX_RATE_HT40)
12708 {
12709 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12710 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012711 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012712 if (rate_flags & eHAL_TX_RATE_SGI)
12713 {
12714 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12715 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012716
Jeff Johnson295189b2012-06-20 16:38:30 -070012717#ifdef LINKSPEED_DEBUG_ENABLED
12718 pr_info("Reporting MCS rate %d flags %x\n",
12719 sinfo->txrate.mcs,
12720 sinfo->txrate.flags );
12721#endif //LINKSPEED_DEBUG_ENABLED
12722 }
12723 }
12724 else
12725 {
12726 // report current rate instead of max rate
12727
12728 if (rate_flags & eHAL_TX_RATE_LEGACY)
12729 {
12730 //provide to the UI in units of 100kbps
12731 sinfo->txrate.legacy = myRate;
12732#ifdef LINKSPEED_DEBUG_ENABLED
12733 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
12734#endif //LINKSPEED_DEBUG_ENABLED
12735 }
12736 else
12737 {
12738 //must be MCS
12739 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070012740#ifdef WLAN_FEATURE_11AC
12741 sinfo->txrate.nss = 1;
12742 if (rate_flags & eHAL_TX_RATE_VHT80)
12743 {
12744 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12745 }
12746 else
12747#endif /* WLAN_FEATURE_11AC */
12748 {
12749 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12750 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012751 if (rate_flags & eHAL_TX_RATE_SGI)
12752 {
12753 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12754 }
12755 if (rate_flags & eHAL_TX_RATE_HT40)
12756 {
12757 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12758 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012759#ifdef WLAN_FEATURE_11AC
12760 else if (rate_flags & eHAL_TX_RATE_VHT80)
12761 {
12762 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
12763 }
12764#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070012765#ifdef LINKSPEED_DEBUG_ENABLED
12766 pr_info("Reporting actual MCS rate %d flags %x\n",
12767 sinfo->txrate.mcs,
12768 sinfo->txrate.flags );
12769#endif //LINKSPEED_DEBUG_ENABLED
12770 }
12771 }
12772 sinfo->filled |= STATION_INFO_TX_BITRATE;
12773
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012774 sinfo->tx_packets =
12775 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
12776 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
12777 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
12778 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
12779
12780 sinfo->tx_retries =
12781 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
12782 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
12783 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
12784 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
12785
12786 sinfo->tx_failed =
12787 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
12788 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
12789 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
12790 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
12791
12792 sinfo->filled |=
12793 STATION_INFO_TX_PACKETS |
12794 STATION_INFO_TX_RETRIES |
12795 STATION_INFO_TX_FAILED;
12796
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012797 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12798 TRACE_CODE_HDD_CFG80211_GET_STA,
12799 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012800 EXIT();
12801 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012802}
12803
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012804static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
12805 u8* mac, struct station_info *sinfo)
12806{
12807 int ret;
12808
12809 vos_ssr_protect(__func__);
12810 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
12811 vos_ssr_unprotect(__func__);
12812
12813 return ret;
12814}
12815
12816static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070012817 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070012818{
12819 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012820 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012821 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012822 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012823
Jeff Johnsone7245742012-09-05 17:12:55 -070012824 ENTER();
12825
Jeff Johnson295189b2012-06-20 16:38:30 -070012826 if (NULL == pAdapter)
12827 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012828 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012829 return -ENODEV;
12830 }
12831
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012832 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12833 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
12834 pAdapter->sessionId, timeout));
12835
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012836 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012837 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012838
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012839 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012840 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12842 "%s: HDD context is not valid", __func__);
12843 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012844 }
12845
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012846 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
12847 (TRUE == pHddCtx->hdd_wlan_suspended) &&
12848 (pHddCtx->cfg_ini->fhostArpOffload) &&
12849 (eConnectionState_Associated ==
12850 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12851 {
Amar Singhald53568e2013-09-26 11:03:45 -070012852
12853 hddLog(VOS_TRACE_LEVEL_INFO,
12854 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053012855 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012856 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12857 {
12858 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012859 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012860 __func__, vos_status);
12861 }
12862 }
12863
Jeff Johnson295189b2012-06-20 16:38:30 -070012864 /**The get power cmd from the supplicant gets updated by the nl only
12865 *on successful execution of the function call
12866 *we are oppositely mapped w.r.t mode in the driver
12867 **/
12868 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
12869
Jeff Johnsone7245742012-09-05 17:12:55 -070012870 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012871 if (VOS_STATUS_E_FAILURE == vos_status)
12872 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12874 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012875 return -EINVAL;
12876 }
12877 return 0;
12878}
12879
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012880static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
12881 struct net_device *dev, bool mode, int timeout)
12882{
12883 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012884
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012885 vos_ssr_protect(__func__);
12886 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
12887 vos_ssr_unprotect(__func__);
12888
12889 return ret;
12890}
Jeff Johnson295189b2012-06-20 16:38:30 -070012891#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012892static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
12893 struct net_device *netdev,
12894 u8 key_index)
12895{
12896 ENTER();
12897 return 0;
12898}
12899
Jeff Johnson295189b2012-06-20 16:38:30 -070012900static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012901 struct net_device *netdev,
12902 u8 key_index)
12903{
12904 int ret;
12905 vos_ssr_protect(__func__);
12906 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
12907 vos_ssr_unprotect(__func__);
12908 return ret;
12909}
12910#endif //LINUX_VERSION_CODE
12911
12912#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
12913static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
12914 struct net_device *dev,
12915 struct ieee80211_txq_params *params)
12916{
12917 ENTER();
12918 return 0;
12919}
12920#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12921static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
12922 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070012923{
Jeff Johnsone7245742012-09-05 17:12:55 -070012924 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012925 return 0;
12926}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012927#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070012928
12929#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
12930static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012931 struct net_device *dev,
12932 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070012933{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012934 int ret;
12935
12936 vos_ssr_protect(__func__);
12937 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
12938 vos_ssr_unprotect(__func__);
12939 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012940}
12941#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12942static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12943 struct ieee80211_txq_params *params)
12944{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012945 int ret;
12946
12947 vos_ssr_protect(__func__);
12948 ret = __wlan_hdd_set_txq_params(wiphy, params);
12949 vos_ssr_unprotect(__func__);
12950 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012951}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012952#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012953
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012954static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012955 struct net_device *dev,
12956 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070012957{
12958 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012959 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012960 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012961 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012962 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012963 v_CONTEXT_t pVosContext = NULL;
12964 ptSapContext pSapCtx = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070012965 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012966
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012967 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070012968 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012969 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012970 return -EINVAL;
12971 }
12972
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012973 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12974 TRACE_CODE_HDD_CFG80211_DEL_STA,
12975 pAdapter->sessionId, pAdapter->device_mode));
12976
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012977 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12978 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012979
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012980 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012981 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012982 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12983 "%s: HDD context is not valid", __func__);
12984 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012985 }
12986
Jeff Johnson295189b2012-06-20 16:38:30 -070012987 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012988 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012989 )
12990 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012991 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12992 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12993 if(pSapCtx == NULL){
12994 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12995 FL("psapCtx is NULL"));
12996 return -ENOENT;
12997 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012998 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070012999 {
13000 v_U16_t i;
13001 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13002 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013003 if ((pSapCtx->aStaInfo[i].isUsed) &&
13004 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070013005 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013006 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013007 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013008 ETHER_ADDR_LEN);
13009
Jeff Johnson295189b2012-06-20 16:38:30 -070013010 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013011 "%s: Delete STA with MAC::"
13012 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013013 __func__,
13014 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
13015 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013016 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013017 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013018 }
13019 }
13020 }
13021 else
13022 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013023
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013024 vos_status = hdd_softap_GetStaId(pAdapter,
13025 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013026 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13027 {
13028 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013029 "%s: Skip this DEL STA as this is not used::"
13030 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013031 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013032 return -ENOENT;
13033 }
13034
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013035 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013036 {
13037 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013038 "%s: Skip this DEL STA as deauth is in progress::"
13039 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013040 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013041 return -ENOENT;
13042 }
13043
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013044 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013045
Jeff Johnson295189b2012-06-20 16:38:30 -070013046 hddLog(VOS_TRACE_LEVEL_INFO,
13047 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013048 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013049 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013050 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013051
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013052 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013053 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13054 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013055 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013056 hddLog(VOS_TRACE_LEVEL_INFO,
13057 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013058 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013059 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013060 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013061 return -ENOENT;
13062 }
13063
Jeff Johnson295189b2012-06-20 16:38:30 -070013064 }
13065 }
13066
13067 EXIT();
13068
13069 return 0;
13070}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013071
13072#ifdef CFG80211_DEL_STA_V2
13073static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13074 struct net_device *dev,
13075 struct station_del_parameters *param)
13076#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013077static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13078 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013079#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013080{
13081 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013082 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070013083
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013084 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013085
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013086#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013087 if (NULL == param) {
13088 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013089 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013090 return -EINVAL;
13091 }
13092
13093 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
13094 param->subtype, &delStaParams);
13095
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013096#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053013097 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013098 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013099#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013100 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
13101
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013102 vos_ssr_unprotect(__func__);
13103
13104 return ret;
13105}
13106
13107static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013108 struct net_device *dev, u8 *mac, struct station_parameters *params)
13109{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013110 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013111 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013112#ifdef FEATURE_WLAN_TDLS
13113 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013114 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013115
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013116 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13117 TRACE_CODE_HDD_CFG80211_ADD_STA,
13118 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013119 mask = params->sta_flags_mask;
13120
13121 set = params->sta_flags_set;
13122
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013123#ifdef WLAN_FEATURE_TDLS_DEBUG
13124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13125 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
13126 __func__, mask, set, MAC_ADDR_ARRAY(mac));
13127#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013128
13129 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13130 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013131 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013132 }
13133 }
13134#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013135 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013136}
13137
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013138static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
13139 struct net_device *dev, u8 *mac, struct station_parameters *params)
13140{
13141 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013142
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013143 vos_ssr_protect(__func__);
13144 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
13145 vos_ssr_unprotect(__func__);
13146
13147 return ret;
13148}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013149#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070013150
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013151static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070013152 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013153{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013154 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13155 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013156 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013157 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013158 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013159 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070013160
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013161 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013162 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013163 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013164 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013165 return -EINVAL;
13166 }
13167
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013168 if (!pmksa) {
13169 hddLog(LOGE, FL("pmksa is NULL"));
13170 return -EINVAL;
13171 }
13172
13173 if (!pmksa->bssid || !pmksa->pmkid) {
13174 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
13175 pmksa->bssid, pmksa->pmkid);
13176 return -EINVAL;
13177 }
13178
13179 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
13180 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13181
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013182 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13183 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013184
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013185 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013186 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13188 "%s: HDD context is not valid", __func__);
13189 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013190 }
13191
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013192 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013193 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13194
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013195 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
13196 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013197
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013198 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013199 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013200 &pmk_id, 1, FALSE);
13201
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013202 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13203 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
13204 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013205
13206 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013207}
13208
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013209static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
13210 struct cfg80211_pmksa *pmksa)
13211{
13212 int ret;
13213
13214 vos_ssr_protect(__func__);
13215 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
13216 vos_ssr_unprotect(__func__);
13217
13218 return ret;
13219}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013220
Wilson Yang6507c4e2013-10-01 20:11:19 -070013221
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013222static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070013223 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013224{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013225 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13226 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013227 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013228 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013229
Wilson Yang6507c4e2013-10-01 20:11:19 -070013230 /* Validate pAdapter */
13231 if (NULL == pAdapter)
13232 {
13233 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
13234 return -EINVAL;
13235 }
13236
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013237 if (!pmksa) {
13238 hddLog(LOGE, FL("pmksa is NULL"));
13239 return -EINVAL;
13240 }
13241
13242 if (!pmksa->bssid) {
13243 hddLog(LOGE, FL("pmksa->bssid is NULL"));
13244 return -EINVAL;
13245 }
13246
Kiet Lam98c46a12014-10-31 15:34:57 -070013247 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
13248 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13249
Wilson Yang6507c4e2013-10-01 20:11:19 -070013250 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13251 status = wlan_hdd_validate_context(pHddCtx);
13252
13253 if (0 != status)
13254 {
13255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13256 "%s: HDD context is not valid", __func__);
13257 return status;
13258 }
13259
13260 /*Retrieve halHandle*/
13261 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13262
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013263 /* Delete the PMKID CSR cache */
13264 if (eHAL_STATUS_SUCCESS !=
13265 sme_RoamDelPMKIDfromCache(halHandle,
13266 pAdapter->sessionId, pmksa->bssid, FALSE)) {
13267 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
13268 MAC_ADDR_ARRAY(pmksa->bssid));
13269 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013270 }
13271
Wilson Yangef657d32014-01-15 19:19:23 -080013272 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013273}
13274
Wilson Yang6507c4e2013-10-01 20:11:19 -070013275
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013276static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
13277 struct cfg80211_pmksa *pmksa)
13278{
13279 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013280
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013281 vos_ssr_protect(__func__);
13282 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
13283 vos_ssr_unprotect(__func__);
13284
13285 return ret;
13286
13287}
13288
13289static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013290{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013291 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13292 tHalHandle halHandle;
13293 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013294 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013295
13296 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
13297
13298 /* Validate pAdapter */
13299 if (NULL == pAdapter)
13300 {
13301 hddLog(VOS_TRACE_LEVEL_ERROR,
13302 "%s: Invalid Adapter" ,__func__);
13303 return -EINVAL;
13304 }
13305
13306 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13307 status = wlan_hdd_validate_context(pHddCtx);
13308
13309 if (0 != status)
13310 {
13311 hddLog(VOS_TRACE_LEVEL_ERROR,
13312 "%s: HDD context is not valid", __func__);
13313 return status;
13314 }
13315
13316 /*Retrieve halHandle*/
13317 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13318
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013319 /* Flush the PMKID cache in CSR */
13320 if (eHAL_STATUS_SUCCESS !=
13321 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
13322 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
13323 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013324 }
13325
Wilson Yangef657d32014-01-15 19:19:23 -080013326 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013327}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013328
13329static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
13330{
13331 int ret;
13332
13333 vos_ssr_protect(__func__);
13334 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
13335 vos_ssr_unprotect(__func__);
13336
13337 return ret;
13338}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013339#endif
13340
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013341#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013342static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13343 struct net_device *dev,
13344 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013345{
13346 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13347 hdd_station_ctx_t *pHddStaCtx;
13348
13349 if (NULL == pAdapter)
13350 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013351 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013352 return -ENODEV;
13353 }
13354
13355 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13356
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013357 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13358 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
13359 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013360 // Added for debug on reception of Re-assoc Req.
13361 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
13362 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013363 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013364 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080013365 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013366 }
13367
13368#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080013369 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013370 ftie->ie_len);
13371#endif
13372
13373 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013374 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13375 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013376 ftie->ie_len);
13377 return 0;
13378}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013379
13380static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13381 struct net_device *dev,
13382 struct cfg80211_update_ft_ies_params *ftie)
13383{
13384 int ret;
13385
13386 vos_ssr_protect(__func__);
13387 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
13388 vos_ssr_unprotect(__func__);
13389
13390 return ret;
13391}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013392#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013393
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013394#ifdef FEATURE_WLAN_SCAN_PNO
13395
13396void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
13397 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
13398{
13399 int ret;
13400 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
13401 hdd_context_t *pHddCtx;
13402
Nirav Shah80830bf2013-12-31 16:35:12 +053013403 ENTER();
13404
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013405 if (NULL == pAdapter)
13406 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013407 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013408 "%s: HDD adapter is Null", __func__);
13409 return ;
13410 }
13411
13412 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13413 if (NULL == pHddCtx)
13414 {
13415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13416 "%s: HDD context is Null!!!", __func__);
13417 return ;
13418 }
13419
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013420 spin_lock(&pHddCtx->schedScan_lock);
13421 if (TRUE == pHddCtx->isWiphySuspended)
13422 {
13423 pHddCtx->isSchedScanUpdatePending = TRUE;
13424 spin_unlock(&pHddCtx->schedScan_lock);
13425 hddLog(VOS_TRACE_LEVEL_INFO,
13426 "%s: Update cfg80211 scan database after it resume", __func__);
13427 return ;
13428 }
13429 spin_unlock(&pHddCtx->schedScan_lock);
13430
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013431 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
13432
13433 if (0 > ret)
13434 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
13435
13436 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13438 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013439}
13440
13441/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013442 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013443 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013444 */
13445static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
13446{
13447 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13448 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013449 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013450 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13451 int status = 0;
13452 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13453
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013454 /* The current firmware design does not allow PNO during any
13455 * active sessions. Hence, determine the active sessions
13456 * and return a failure.
13457 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013458 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
13459 {
13460 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013461 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013462
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013463 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
13464 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
13465 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
13466 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
13467 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053013468 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013469 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013470 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013471 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013472 }
13473 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13474 pAdapterNode = pNext;
13475 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013476 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013477}
13478
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013479void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
13480{
13481 hdd_adapter_t *pAdapter = callbackContext;
13482 hdd_context_t *pHddCtx;
13483
13484 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
13485 {
13486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13487 FL("Invalid adapter or adapter has invalid magic"));
13488 return;
13489 }
13490
13491 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13492 if (0 != wlan_hdd_validate_context(pHddCtx))
13493 {
13494 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13495 FL("HDD context is not valid"));
13496 return;
13497 }
13498
c_hpothub53c45d2014-08-18 16:53:14 +053013499 if (VOS_STATUS_SUCCESS != status)
13500 {
13501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013502 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053013503 pHddCtx->isPnoEnable = FALSE;
13504 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013505
13506 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
13507 complete(&pAdapter->pno_comp_var);
13508}
13509
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013510/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013511 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
13512 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013513 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013514static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013515 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13516{
13517 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13518 tpSirPNOScanReq pPnoRequest = NULL;
13519 hdd_context_t *pHddCtx;
13520 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013521 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053013522 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
13523 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013524 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13525 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013526 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013527 hdd_config_t *pConfig = NULL;
13528 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013529
13530 if (NULL == pAdapter)
13531 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013533 "%s: HDD adapter is Null", __func__);
13534 return -ENODEV;
13535 }
13536
13537 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013538 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013539
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013540 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013541 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013542 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13543 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013544 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013545 }
13546
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013547 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013548 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13549 if (NULL == hHal)
13550 {
13551 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13552 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013553 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013554 }
Sushant Kaushik2fe89932014-09-03 10:58:09 +053013555 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013556 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053013557 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013558 {
13559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13560 "%s: aborting the existing scan is unsuccessfull", __func__);
13561 return -EBUSY;
13562 }
13563
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013564 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013565 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013567 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013568 return -EBUSY;
13569 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013570
c_hpothu37f21312014-04-09 21:49:54 +053013571 if (TRUE == pHddCtx->isPnoEnable)
13572 {
13573 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13574 FL("already PNO is enabled"));
13575 return -EBUSY;
13576 }
c_hpothu225aa7c2014-10-22 17:45:13 +053013577
13578 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
13579 {
13580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13581 "%s: abort ROC failed ", __func__);
13582 return -EBUSY;
13583 }
13584
c_hpothu37f21312014-04-09 21:49:54 +053013585 pHddCtx->isPnoEnable = TRUE;
13586
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013587 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13588 if (NULL == pPnoRequest)
13589 {
13590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13591 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053013592 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013593 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013594 }
13595
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053013596 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013597 pPnoRequest->enable = 1; /*Enable PNO */
13598 pPnoRequest->ucNetworksCount = request->n_match_sets;
13599
13600 if (( !pPnoRequest->ucNetworksCount ) ||
13601 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
13602 {
13603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013604 "%s: Network input is not correct %d Max Network supported is %d",
13605 __func__, pPnoRequest->ucNetworksCount,
13606 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013607 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013608 goto error;
13609 }
13610
13611 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
13612 {
13613 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013614 "%s: Incorrect number of channels %d",
13615 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013616 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013617 goto error;
13618 }
13619
13620 /* Framework provides one set of channels(all)
13621 * common for all saved profile */
13622 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13623 channels_allowed, &num_channels_allowed))
13624 {
13625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13626 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013627 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013628 goto error;
13629 }
13630 /* Checking each channel against allowed channel list */
13631 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053013632 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013633 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013634 char chList [(request->n_channels*5)+1];
13635 int len;
13636 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013637 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013638 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013639 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013640 if (request->channels[i]->hw_value == channels_allowed[indx])
13641 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013642 if ((!pConfig->enableDFSPnoChnlScan) &&
13643 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
13644 {
13645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13646 "%s : Dropping DFS channel : %d",
13647 __func__,channels_allowed[indx]);
13648 num_ignore_dfs_ch++;
13649 break;
13650 }
13651
Nirav Shah80830bf2013-12-31 16:35:12 +053013652 valid_ch[num_ch++] = request->channels[i]->hw_value;
13653 len += snprintf(chList+len, 5, "%d ",
13654 request->channels[i]->hw_value);
13655 break ;
13656 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013657 }
13658 }
Nirav Shah80830bf2013-12-31 16:35:12 +053013659 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013660
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013661 /*If all channels are DFS and dropped, then ignore the PNO request*/
13662 if (num_ignore_dfs_ch == request->n_channels)
13663 {
13664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13665 "%s : All requested channels are DFS channels", __func__);
13666 ret = -EINVAL;
13667 goto error;
13668 }
13669 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013670 /* Filling per profile params */
13671 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
13672 {
13673 pPnoRequest->aNetworks[i].ssId.length =
13674 request->match_sets[i].ssid.ssid_len;
13675
13676 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
13677 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
13678 {
13679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013680 "%s: SSID Len %d is not correct for network %d",
13681 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013682 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013683 goto error;
13684 }
13685
13686 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
13687 request->match_sets[i].ssid.ssid,
13688 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13690 "%s: SSID of network %d is %s ", __func__,
13691 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013692 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
13693 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
13694 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
13695
13696 /*Copying list of valid channel into request */
13697 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
13698 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
13699
13700 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
13701 }
13702
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013703 for (i = 0; i < request->n_ssids; i++)
13704 {
13705 j = 0;
13706 while (j < pPnoRequest->ucNetworksCount)
13707 {
13708 if ((pPnoRequest->aNetworks[j].ssId.length ==
13709 request->ssids[i].ssid_len) &&
13710 (0 == memcmp(pPnoRequest->aNetworks[j].ssId.ssId,
13711 request->ssids[i].ssid,
13712 pPnoRequest->aNetworks[j].ssId.length)))
13713 {
13714 pPnoRequest->aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
13715 break;
13716 }
13717 j++;
13718 }
13719 }
13720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13721 "Number of hidden networks being Configured = %d",
13722 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080013724 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013725 if ((0 < request->ie_len) && (NULL != request->ie))
13726 {
13727 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
13728 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
13729 pPnoRequest->us24GProbeTemplateLen);
13730
13731 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
13732 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
13733 pPnoRequest->us5GProbeTemplateLen);
13734 }
13735
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053013736 /* Driver gets only one time interval which is hardcoded in
13737 * supplicant for 10000ms. Taking power consumption into account 6 timers
13738 * will be used, Timervalue is increased exponentially i.e 10,20,40,
13739 * 80,160,320 secs. And number of scan cycle for each timer
13740 * is configurable through INI param gPNOScanTimerRepeatValue.
13741 * If it is set to 0 only one timer will be used and PNO scan cycle
13742 * will be repeated after each interval specified by supplicant
13743 * till PNO is disabled.
13744 */
13745 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
13746 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
13747 else
13748 pPnoRequest->scanTimers.ucScanTimersCount =
13749 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
13750
13751 tempInterval = (request->interval)/1000;
13752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13753 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
13754 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
13755 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
13756 {
13757 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
13758 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
13759 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
13760 tempInterval *= 2;
13761 }
13762 //Repeat last timer until pno disabled.
13763 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
13764
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053013765 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013766
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013767 INIT_COMPLETION(pAdapter->pno_comp_var);
13768 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
13769 pPnoRequest->callbackContext = pAdapter;
13770 pAdapter->pno_req_status = 0;
13771
Nirav Shah80830bf2013-12-31 16:35:12 +053013772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13773 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
13774 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
13775 pPnoRequest->scanTimers.ucScanTimersCount);
13776
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013777 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
13778 pPnoRequest, pAdapter->sessionId,
13779 hdd_cfg80211_sched_scan_done_callback, pAdapter);
13780 if (eHAL_STATUS_SUCCESS != status)
13781 {
13782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013783 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013784 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013785 goto error;
13786 }
13787
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013788 ret = wait_for_completion_timeout(
13789 &pAdapter->pno_comp_var,
13790 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
13791 if (0 >= ret)
13792 {
13793 // Did not receive the response for PNO enable in time.
13794 // Assuming the PNO enable was success.
13795 // Returning error from here, because we timeout, results
13796 // in side effect of Wifi (Wifi Setting) not to work.
13797 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13798 FL("Timed out waiting for PNO to be Enabled"));
13799 ret = 0;
13800 goto error;
13801 }
13802
c_hpothu3c986b22014-07-09 14:45:09 +053013803 vos_mem_free(pPnoRequest);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013804 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053013805 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013806
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013807error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13809 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013810 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053013811 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013812 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013813}
13814
13815/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013816 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
13817 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013818 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013819static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
13820 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13821{
13822 int ret;
13823
13824 vos_ssr_protect(__func__);
13825 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
13826 vos_ssr_unprotect(__func__);
13827
13828 return ret;
13829}
13830
13831/*
13832 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
13833 * Function to disable PNO
13834 */
13835static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013836 struct net_device *dev)
13837{
13838 eHalStatus status = eHAL_STATUS_FAILURE;
13839 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13840 hdd_context_t *pHddCtx;
13841 tHalHandle hHal;
13842 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013843 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013844
13845 ENTER();
13846
13847 if (NULL == pAdapter)
13848 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013850 "%s: HDD adapter is Null", __func__);
13851 return -ENODEV;
13852 }
13853
13854 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013855
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013856 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013857 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013859 "%s: HDD context is Null", __func__);
13860 return -ENODEV;
13861 }
13862
13863 /* The return 0 is intentional when isLogpInProgress and
13864 * isLoadUnloadInProgress. We did observe a crash due to a return of
13865 * failure in sched_scan_stop , especially for a case where the unload
13866 * of the happens at the same time. The function __cfg80211_stop_sched_scan
13867 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
13868 * success. If it returns a failure , then its next invocation due to the
13869 * clean up of the second interface will have the dev pointer corresponding
13870 * to the first one leading to a crash.
13871 */
13872 if (pHddCtx->isLogpInProgress)
13873 {
13874 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13875 "%s: LOGP in Progress. Ignore!!!", __func__);
13876 return ret;
13877 }
13878
Mihir Shete18156292014-03-11 15:38:30 +053013879 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013880 {
13881 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13882 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13883 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013884 }
13885
13886 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13887 if (NULL == hHal)
13888 {
13889 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13890 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013891 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013892 }
13893
13894 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13895 if (NULL == pPnoRequest)
13896 {
13897 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13898 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013899 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013900 }
13901
13902 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
13903 pPnoRequest->enable = 0; /* Disable PNO */
13904 pPnoRequest->ucNetworksCount = 0;
13905
13906 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
13907 pAdapter->sessionId,
13908 NULL, pAdapter);
13909 if (eHAL_STATUS_SUCCESS != status)
13910 {
13911 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13912 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013913 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013914 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013915 }
c_hpothu37f21312014-04-09 21:49:54 +053013916 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013917
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013918error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013919 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013920 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013921 vos_mem_free(pPnoRequest);
13922
13923 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013924 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013925}
13926
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013927/*
13928 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
13929 * NL interface to disable PNO
13930 */
13931static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
13932 struct net_device *dev)
13933{
13934 int ret;
13935
13936 vos_ssr_protect(__func__);
13937 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
13938 vos_ssr_unprotect(__func__);
13939
13940 return ret;
13941}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013942#endif /*FEATURE_WLAN_SCAN_PNO*/
13943
13944
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013945#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013946#if TDLS_MGMT_VERSION2
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013947static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013948 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013949 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
13950#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013951static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013952 u8 *peer, u8 action_code, u8 dialog_token,
13953 u16 status_code, const u8 *buf, size_t len)
13954#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013955{
13956
13957 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13958 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013959 u8 peerMac[6];
13960 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070013961 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080013962 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070013963 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013964#if !(TDLS_MGMT_VERSION2)
13965 u32 peer_capability = 0;
13966#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013967 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013968
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013969 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13970 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
13971 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013972 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013973 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013974 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013975 "Invalid arguments");
13976 return -EINVAL;
13977 }
13978
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013979 if (pHddCtx->isLogpInProgress)
13980 {
13981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13982 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053013983 wlan_hdd_tdls_set_link_status(pAdapter,
13984 peer,
13985 eTDLS_LINK_IDLE,
13986 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013987 return -EBUSY;
13988 }
13989
Hoonki Lee27511902013-03-14 18:19:06 -070013990 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013991 {
Hoonki Lee27511902013-03-14 18:19:06 -070013992 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13993 "%s: TDLS mode is disabled OR not enabled in FW."
13994 MAC_ADDRESS_STR " action %d declined.",
13995 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013996 return -ENOTSUPP;
13997 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013998
Hoonki Lee27511902013-03-14 18:19:06 -070013999 /* other than teardown frame, other mgmt frames are not sent if disabled */
14000 if (SIR_MAC_TDLS_TEARDOWN != action_code)
14001 {
14002 /* if tdls_mode is disabled to respond to peer's request */
14003 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
14004 {
14005 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
14006 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014007 " TDLS mode is disabled. action %d declined.",
14008 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070014009
14010 return -ENOTSUPP;
14011 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014012
14013 if (vos_max_concurrent_connections_reached())
14014 {
14015 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14016 return -EINVAL;
14017 }
Hoonki Lee27511902013-03-14 18:19:06 -070014018 }
14019
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014020 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
14021 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014022 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014023 {
14024 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014025 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014026 " TDLS setup is ongoing. action %d declined.",
14027 __func__, MAC_ADDR_ARRAY(peer), action_code);
14028 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014029 }
14030 }
14031
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014032 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
14033 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080014034 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014035 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14036 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014037 {
14038 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
14039 we return error code at 'add_station()'. Hence we have this
14040 check again in addtion to add_station().
14041 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014042 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014043 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14045 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014046 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
14047 __func__, MAC_ADDR_ARRAY(peer), action_code,
14048 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053014049 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080014050 }
14051 else
14052 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014053 /* maximum reached. tweak to send error code to peer and return
14054 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014055 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14057 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014058 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
14059 __func__, MAC_ADDR_ARRAY(peer), status_code,
14060 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070014061 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014062 /* fall through to send setup resp with failure status
14063 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014064 }
14065 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014066 else
14067 {
14068 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014069 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014070 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014071 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014072 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014073 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
14074 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014075 return -EPERM;
14076 }
14077 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014078 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014079 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014080
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014081#ifdef WLAN_FEATURE_TDLS_DEBUG
14082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014083 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014084 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
14085 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014086#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014087
Hoonki Leea34dd892013-02-05 22:56:02 -080014088 /*Except teardown responder will not be used so just make 0*/
14089 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014090 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080014091 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014092
14093 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014094 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014095
14096 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
14097 responder = pTdlsPeer->is_responder;
14098 else
Hoonki Leea34dd892013-02-05 22:56:02 -080014099 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014101 "%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 -070014102 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
14103 dialog_token, status_code, len);
14104 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080014105 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014106 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014107
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014108 /* For explicit trigger of DIS_REQ come out of BMPS for
14109 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070014110 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014111 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
14112 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070014113 {
14114 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
14115 {
14116 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014117 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070014118 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
14119 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014120 if (SIR_MAC_TDLS_DIS_REQ != action_code)
14121 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070014122 }
14123
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014124 /* make sure doesn't call send_mgmt() while it is pending */
14125 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
14126 {
14127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014128 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014129 __func__, MAC_ADDR_ARRAY(peer), action_code);
14130 return -EBUSY;
14131 }
14132
14133 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014134 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
14135
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014136 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053014137 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014138
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014139 if (VOS_STATUS_SUCCESS != status)
14140 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14142 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014143 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -070014144 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053014145 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014146 }
14147
Hoonki Leed37cbb32013-04-20 00:31:14 -070014148 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
14149 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
14150
14151 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014152 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070014153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014154 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070014155 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014156 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080014157
14158 if (pHddCtx->isLogpInProgress)
14159 {
14160 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14161 "%s: LOGP in Progress. Ignore!!!", __func__);
14162 return -EAGAIN;
14163 }
14164
Hoonki Leed37cbb32013-04-20 00:31:14 -070014165 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053014166 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014167 }
14168
Gopichand Nakkala05922802013-03-14 12:23:19 -070014169 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070014170 {
14171 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -070014172 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070014173 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014174
Hoonki Leea34dd892013-02-05 22:56:02 -080014175 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
14176 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014177 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080014178 }
14179 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
14180 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014181 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080014182 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014183
14184 return 0;
14185}
14186
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014187#if TDLS_MGMT_VERSION2
14188static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14189 u8 *peer, u8 action_code, u8 dialog_token,
14190 u16 status_code, u32 peer_capability,
14191 const u8 *buf, size_t len)
14192#else
14193static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14194 u8 *peer, u8 action_code, u8 dialog_token,
14195 u16 status_code, const u8 *buf, size_t len)
14196#endif
14197{
14198 int ret;
14199
14200 vos_ssr_protect(__func__);
14201#if TDLS_MGMT_VERSION2
14202 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14203 status_code, peer_capability, buf, len);
14204#else
14205 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14206 status_code, buf, len);
14207#endif
14208 vos_ssr_unprotect(__func__);
14209
14210 return ret;
14211}
Atul Mittal115287b2014-07-08 13:26:33 +053014212
14213int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
14214 u8 *peer,
14215 cfg80211_exttdls_callback callback)
14216{
14217
14218 hddTdlsPeer_t *pTdlsPeer;
14219 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14220 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14221 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
14222 __func__, MAC_ADDR_ARRAY(peer));
14223
14224 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14225 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14226
14227 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14228 " %s TDLS External control and Implicit Trigger not enabled ",
14229 __func__);
14230 return -ENOTSUPP;
14231 }
14232
14233 /* To cater the requirement of establishing the TDLS link
14234 * irrespective of the data traffic , get an entry of TDLS peer.
14235 */
14236 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
14237 if (pTdlsPeer == NULL) {
14238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14239 "%s: peer " MAC_ADDRESS_STR " not existing",
14240 __func__, MAC_ADDR_ARRAY(peer));
14241 return -EINVAL;
14242 }
14243
14244 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
14245
14246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14247 " %s TDLS Add Force Peer Failed",
14248 __func__);
14249 return -EINVAL;
14250 }
14251 /*EXT TDLS*/
14252
14253 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
14254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14255 " %s TDLS set callback Failed",
14256 __func__);
14257 return -EINVAL;
14258 }
14259
14260 return(0);
14261
14262}
14263
14264int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
14265{
14266
14267 hddTdlsPeer_t *pTdlsPeer;
14268 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14269 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14270 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
14271 __func__, MAC_ADDR_ARRAY(peer));
14272
14273 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14274 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14275
14276 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14277 " %s TDLS External control and Implicit Trigger not enabled ",
14278 __func__);
14279 return -ENOTSUPP;
14280 }
14281
14282
14283 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
14284
14285 if ( NULL == pTdlsPeer ) {
14286 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
14287 " peer not exsting",
14288 __func__, MAC_ADDR_ARRAY(peer));
14289 return -EINVAL;
14290 }
14291 else {
14292 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
14293 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
14294 }
14295
14296 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
14297 return -EINVAL;
14298
14299 /*EXT TDLS*/
14300
14301 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
14302
14303 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14304 " %s TDLS set callback Failed",
14305 __func__);
14306 return -EINVAL;
14307 }
14308 return(0);
14309
14310}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014311static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014312 u8 *peer, enum nl80211_tdls_operation oper)
14313{
14314 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14315 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014316 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014317 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014318
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014319 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14320 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
14321 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014322 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014323 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014325 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014326 return -EINVAL;
14327 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014328
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014329 status = wlan_hdd_validate_context(pHddCtx);
14330
14331 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014332 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014333 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14334 "%s: HDD context is not valid", __func__);
14335 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014336 }
14337
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014338
14339 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014340 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014341 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014342 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014343 "TDLS Disabled in INI OR not enabled in FW. "
14344 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014345 return -ENOTSUPP;
14346 }
14347
14348 switch (oper) {
14349 case NL80211_TDLS_ENABLE_LINK:
14350 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014351 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014352 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014353 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053014354 WLAN_STADescType staDesc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014355
Sunil Dutt41de4e22013-11-14 18:09:02 +053014356 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053014357 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053014358 if ( NULL == pTdlsPeer ) {
14359 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
14360 " (oper %d) not exsting. ignored",
14361 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
14362 return -EINVAL;
14363 }
14364
14365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14366 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
14367 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
14368 "NL80211_TDLS_ENABLE_LINK");
14369
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070014370 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
14371 {
14372 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
14373 MAC_ADDRESS_STR " failed",
14374 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
14375 return -EINVAL;
14376 }
14377
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014378 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014379 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014380 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053014381
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014382 if (0 != wlan_hdd_tdls_get_link_establish_params(
14383 pAdapter, peer,&tdlsLinkEstablishParams)) {
14384 return -EINVAL;
14385 }
14386 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014387
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014388 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
14389 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
14390 /* Send TDLS peer UAPSD capabilities to the firmware and
14391 * register with the TL on after the response for this operation
14392 * is received .
14393 */
14394 ret = wait_for_completion_interruptible_timeout(
14395 &pAdapter->tdls_link_establish_req_comp,
14396 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
14397 if (ret <= 0)
14398 {
14399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14400 "%s: Link Establish Request Faled Status %ld",
14401 __func__, ret);
14402 return -EINVAL;
14403 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014404 }
Atul Mittal115287b2014-07-08 13:26:33 +053014405 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
14406 eTDLS_LINK_CONNECTED,
14407 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053014408 staDesc.ucSTAId = pTdlsPeer->staId;
14409 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
14410 WLANTL_UpdateTdlsSTAClient(pHddCtx->pvosContext,
14411 &staDesc);
14412
14413
Gopichand Nakkala471708b2013-06-04 20:03:01 +053014414 /* Mark TDLS client Authenticated .*/
14415 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
14416 pTdlsPeer->staId,
14417 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014418 if (VOS_STATUS_SUCCESS == status)
14419 {
Hoonki Lee14621352013-04-16 17:51:19 -070014420 if (pTdlsPeer->is_responder == 0)
14421 {
14422 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
14423
14424 wlan_hdd_tdls_timer_restart(pAdapter,
14425 &pTdlsPeer->initiatorWaitTimeoutTimer,
14426 WAIT_TIME_TDLS_INITIATOR);
14427 /* suspend initiator TX until it receives direct packet from the
14428 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
14429 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
14430 &staId, NULL);
14431 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014432 wlan_hdd_tdls_increment_peer_count(pAdapter);
14433 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014434 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014435
14436 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053014437 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
14438 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014439 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053014440 int ac;
14441 uint8 ucAc[4] = { WLANTL_AC_VO,
14442 WLANTL_AC_VI,
14443 WLANTL_AC_BK,
14444 WLANTL_AC_BE };
14445 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
14446 for(ac=0; ac < 4; ac++)
14447 {
14448 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
14449 pTdlsPeer->staId, ucAc[ac],
14450 tlTid[ac], tlTid[ac], 0, 0,
14451 WLANTL_BI_DIR );
14452 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014453 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014454 }
14455
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014456 }
14457 break;
14458 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080014459 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053014460 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
14461
14462 if ( NULL == pTdlsPeer ) {
14463 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
14464 " (oper %d) not exsting. ignored",
14465 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
14466 return -EINVAL;
14467 }
14468
14469 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14470 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
14471 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
14472 "NL80211_TDLS_DISABLE_LINK");
14473
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014474 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080014475 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014476 long status;
14477
Atul Mittal271a7652014-09-12 13:18:22 +053014478
14479 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
14480 eTDLS_LINK_TEARING,
14481 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
14482 eTDLS_LINK_UNSPECIFIED:
14483 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014484 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
14485
Lee Hoonkic1262f22013-01-24 21:59:00 -080014486 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
14487 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014488
14489 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
14490 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053014491 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053014492 eTDLS_LINK_IDLE,
14493 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014494 if (status <= 0)
14495 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14497 "%s: Del station failed status %ld",
14498 __func__, status);
14499 return -EPERM;
14500 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014501 }
14502 else
14503 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014504 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14505 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080014506 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014507 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014508 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014509 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053014510 {
Atul Mittal115287b2014-07-08 13:26:33 +053014511 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053014512
Atul Mittal115287b2014-07-08 13:26:33 +053014513 if (0 != status)
14514 {
14515 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14516 "%s: Error in TDLS Teardown", __func__);
14517 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053014518 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053014519 break;
14520 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014521 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053014522 {
Atul Mittal115287b2014-07-08 13:26:33 +053014523 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
14524 peer,
14525 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053014526
Atul Mittal115287b2014-07-08 13:26:33 +053014527 if (0 != status)
14528 {
14529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14530 "%s: Error in TDLS Setup", __func__);
14531 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053014532 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053014533 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053014534 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014535 case NL80211_TDLS_DISCOVERY_REQ:
14536 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14538 "%s: We don't support in-driver setup/teardown/discovery "
14539 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014540 return -ENOTSUPP;
14541 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14543 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014544 return -ENOTSUPP;
14545 }
14546 return 0;
14547}
Chilam NG571c65a2013-01-19 12:27:36 +053014548
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014549static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
14550 u8 *peer, enum nl80211_tdls_operation oper)
14551{
14552 int ret;
14553
14554 vos_ssr_protect(__func__);
14555 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
14556 vos_ssr_unprotect(__func__);
14557
14558 return ret;
14559}
14560
Chilam NG571c65a2013-01-19 12:27:36 +053014561int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
14562 struct net_device *dev, u8 *peer)
14563{
Arif Hussaina7c8e412013-11-20 11:06:42 -080014564 hddLog(VOS_TRACE_LEVEL_INFO,
14565 "tdls send discover req: "MAC_ADDRESS_STR,
14566 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053014567
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014568#if TDLS_MGMT_VERSION2
14569 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14570 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
14571#else
Chilam NG571c65a2013-01-19 12:27:36 +053014572 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14573 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014574#endif
Chilam NG571c65a2013-01-19 12:27:36 +053014575}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014576#endif
14577
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014578#ifdef WLAN_FEATURE_GTK_OFFLOAD
14579/*
14580 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
14581 * Callback rountine called upon receiving response for
14582 * get offload info
14583 */
14584void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
14585 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
14586{
14587
14588 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014589 tANI_U8 tempReplayCounter[8];
14590 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014591
14592 ENTER();
14593
14594 if (NULL == pAdapter)
14595 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014596 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014597 "%s: HDD adapter is Null", __func__);
14598 return ;
14599 }
14600
14601 if (NULL == pGtkOffloadGetInfoRsp)
14602 {
14603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14604 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
14605 return ;
14606 }
14607
14608 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
14609 {
14610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14611 "%s: wlan Failed to get replay counter value",
14612 __func__);
14613 return ;
14614 }
14615
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014616 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14617 /* Update replay counter */
14618 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
14619 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14620
14621 {
14622 /* changing from little to big endian since supplicant
14623 * works on big endian format
14624 */
14625 int i;
14626 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14627
14628 for (i = 0; i < 8; i++)
14629 {
14630 tempReplayCounter[7-i] = (tANI_U8)p[i];
14631 }
14632 }
14633
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014634 /* Update replay counter to NL */
14635 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014636 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014637}
14638
14639/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014640 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014641 * This function is used to offload GTK rekeying job to the firmware.
14642 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014643int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014644 struct cfg80211_gtk_rekey_data *data)
14645{
14646 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14647 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14648 hdd_station_ctx_t *pHddStaCtx;
14649 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014650 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014651 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014652 eHalStatus status = eHAL_STATUS_FAILURE;
14653
14654 ENTER();
14655
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014656
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014657 if (NULL == pAdapter)
14658 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014660 "%s: HDD adapter is Null", __func__);
14661 return -ENODEV;
14662 }
14663
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014664 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14665 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
14666 pAdapter->sessionId, pAdapter->device_mode));
14667
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014668 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014669
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014670 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014671 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014672 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14673 "%s: HDD context is not valid", __func__);
14674 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014675 }
14676
14677 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14678 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14679 if (NULL == hHal)
14680 {
14681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14682 "%s: HAL context is Null!!!", __func__);
14683 return -EAGAIN;
14684 }
14685
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014686 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
14687 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
14688 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
14689 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014690 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014691 {
14692 /* changing from big to little endian since driver
14693 * works on little endian format
14694 */
14695 tANI_U8 *p =
14696 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
14697 int i;
14698
14699 for (i = 0; i < 8; i++)
14700 {
14701 p[7-i] = data->replay_ctr[i];
14702 }
14703 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014704
14705 if (TRUE == pHddCtx->hdd_wlan_suspended)
14706 {
14707 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014708 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
14709 sizeof (tSirGtkOffloadParams));
14710 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014711 pAdapter->sessionId);
14712
14713 if (eHAL_STATUS_SUCCESS != status)
14714 {
14715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14716 "%s: sme_SetGTKOffload failed, returned %d",
14717 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053014718
14719 /* Need to clear any trace of key value in the memory.
14720 * Thus zero out the memory even though it is local
14721 * variable.
14722 */
14723 vos_mem_zero(&hddGtkOffloadReqParams,
14724 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014725 return status;
14726 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14728 "%s: sme_SetGTKOffload successfull", __func__);
14729 }
14730 else
14731 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14733 "%s: wlan not suspended GTKOffload request is stored",
14734 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014735 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014736
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053014737 /* Need to clear any trace of key value in the memory.
14738 * Thus zero out the memory even though it is local
14739 * variable.
14740 */
14741 vos_mem_zero(&hddGtkOffloadReqParams,
14742 sizeof(hddGtkOffloadReqParams));
14743
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014744 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014745}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014746
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014747int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
14748 struct cfg80211_gtk_rekey_data *data)
14749{
14750 int ret;
14751
14752 vos_ssr_protect(__func__);
14753 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
14754 vos_ssr_unprotect(__func__);
14755
14756 return ret;
14757}
14758#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014759/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014760 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014761 * This function is used to set access control policy
14762 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014763static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
14764 struct net_device *dev,
14765 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014766{
14767 int i;
14768 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14769 hdd_hostapd_state_t *pHostapdState;
14770 tsap_Config_t *pConfig;
14771 v_CONTEXT_t pVosContext = NULL;
14772 hdd_context_t *pHddCtx;
14773 int status;
14774
14775 ENTER();
14776
14777 if (NULL == pAdapter)
14778 {
14779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14780 "%s: HDD adapter is Null", __func__);
14781 return -ENODEV;
14782 }
14783
14784 if (NULL == params)
14785 {
14786 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14787 "%s: params is Null", __func__);
14788 return -EINVAL;
14789 }
14790
14791 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14792 status = wlan_hdd_validate_context(pHddCtx);
14793
14794 if (0 != status)
14795 {
14796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14797 "%s: HDD context is not valid", __func__);
14798 return status;
14799 }
14800
14801 pVosContext = pHddCtx->pvosContext;
14802 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
14803
14804 if (NULL == pHostapdState)
14805 {
14806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14807 "%s: pHostapdState is Null", __func__);
14808 return -EINVAL;
14809 }
14810
14811 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
14812 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
14813
14814 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
14815 {
14816 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
14817
14818 /* default value */
14819 pConfig->num_accept_mac = 0;
14820 pConfig->num_deny_mac = 0;
14821
14822 /**
14823 * access control policy
14824 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
14825 * listed in hostapd.deny file.
14826 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
14827 * listed in hostapd.accept file.
14828 */
14829 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
14830 {
14831 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
14832 }
14833 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
14834 {
14835 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
14836 }
14837 else
14838 {
14839 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14840 "%s:Acl Policy : %d is not supported",
14841 __func__, params->acl_policy);
14842 return -ENOTSUPP;
14843 }
14844
14845 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
14846 {
14847 pConfig->num_accept_mac = params->n_acl_entries;
14848 for (i = 0; i < params->n_acl_entries; i++)
14849 {
14850 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14851 "** Add ACL MAC entry %i in WhiletList :"
14852 MAC_ADDRESS_STR, i,
14853 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14854
14855 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
14856 sizeof(qcmacaddr));
14857 }
14858 }
14859 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
14860 {
14861 pConfig->num_deny_mac = params->n_acl_entries;
14862 for (i = 0; i < params->n_acl_entries; i++)
14863 {
14864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14865 "** Add ACL MAC entry %i in BlackList :"
14866 MAC_ADDRESS_STR, i,
14867 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14868
14869 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
14870 sizeof(qcmacaddr));
14871 }
14872 }
14873
14874 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
14875 {
14876 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14877 "%s: SAP Set Mac Acl fail", __func__);
14878 return -EINVAL;
14879 }
14880 }
14881 else
14882 {
14883 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014884 "%s: Invalid device_mode = %s (%d)",
14885 __func__, hdd_device_modetoString(pAdapter->device_mode),
14886 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014887 return -EINVAL;
14888 }
14889
14890 return 0;
14891}
14892
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014893static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
14894 struct net_device *dev,
14895 const struct cfg80211_acl_data *params)
14896{
14897 int ret;
14898 vos_ssr_protect(__func__);
14899 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
14900 vos_ssr_unprotect(__func__);
14901
14902 return ret;
14903}
14904
Leo Chang9056f462013-08-01 19:21:11 -070014905#ifdef WLAN_NL80211_TESTMODE
14906#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070014907void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070014908(
14909 void *pAdapter,
14910 void *indCont
14911)
14912{
Leo Changd9df8aa2013-09-26 13:32:26 -070014913 tSirLPHBInd *lphbInd;
14914 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053014915 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070014916
14917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014918 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070014919
c_hpothu73f35e62014-04-18 13:40:08 +053014920 if (pAdapter == NULL)
14921 {
14922 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14923 "%s: pAdapter is NULL\n",__func__);
14924 return;
14925 }
14926
Leo Chang9056f462013-08-01 19:21:11 -070014927 if (NULL == indCont)
14928 {
14929 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014930 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070014931 return;
14932 }
14933
c_hpothu73f35e62014-04-18 13:40:08 +053014934 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070014935 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070014936 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053014937 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070014938 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070014939 GFP_ATOMIC);
14940 if (!skb)
14941 {
14942 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14943 "LPHB timeout, NL buffer alloc fail");
14944 return;
14945 }
14946
Leo Changac3ba772013-10-07 09:47:04 -070014947 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070014948 {
14949 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14950 "WLAN_HDD_TM_ATTR_CMD put fail");
14951 goto nla_put_failure;
14952 }
Leo Changac3ba772013-10-07 09:47:04 -070014953 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070014954 {
14955 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14956 "WLAN_HDD_TM_ATTR_TYPE put fail");
14957 goto nla_put_failure;
14958 }
Leo Changac3ba772013-10-07 09:47:04 -070014959 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070014960 sizeof(tSirLPHBInd), lphbInd))
14961 {
14962 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14963 "WLAN_HDD_TM_ATTR_DATA put fail");
14964 goto nla_put_failure;
14965 }
Leo Chang9056f462013-08-01 19:21:11 -070014966 cfg80211_testmode_event(skb, GFP_ATOMIC);
14967 return;
14968
14969nla_put_failure:
14970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14971 "NLA Put fail");
14972 kfree_skb(skb);
14973
14974 return;
14975}
14976#endif /* FEATURE_WLAN_LPHB */
14977
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014978static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070014979{
14980 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
14981 int err = 0;
14982#ifdef FEATURE_WLAN_LPHB
14983 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070014984 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -070014985#endif /* FEATURE_WLAN_LPHB */
14986
14987 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
14988 if (err)
14989 {
14990 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14991 "%s Testmode INV ATTR", __func__);
14992 return err;
14993 }
14994
14995 if (!tb[WLAN_HDD_TM_ATTR_CMD])
14996 {
14997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14998 "%s Testmode INV CMD", __func__);
14999 return -EINVAL;
15000 }
15001
15002 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
15003 {
15004#ifdef FEATURE_WLAN_LPHB
15005 /* Low Power Heartbeat configuration request */
15006 case WLAN_HDD_TM_CMD_WLAN_HB:
15007 {
15008 int buf_len;
15009 void *buf;
15010 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080015011 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070015012
15013 if (!tb[WLAN_HDD_TM_ATTR_DATA])
15014 {
15015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15016 "%s Testmode INV DATA", __func__);
15017 return -EINVAL;
15018 }
15019
15020 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
15021 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080015022
15023 hb_params_temp =(tSirLPHBReq *)buf;
15024 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
15025 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
15026 return -EINVAL;
15027
Leo Chang9056f462013-08-01 19:21:11 -070015028 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
15029 if (NULL == hb_params)
15030 {
15031 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15032 "%s Request Buffer Alloc Fail", __func__);
15033 return -EINVAL;
15034 }
15035
15036 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070015037 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
15038 hb_params,
15039 wlan_hdd_cfg80211_lphb_ind_handler);
15040 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070015041 {
Leo Changd9df8aa2013-09-26 13:32:26 -070015042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15043 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070015044 vos_mem_free(hb_params);
15045 }
Leo Chang9056f462013-08-01 19:21:11 -070015046 return 0;
15047 }
15048#endif /* FEATURE_WLAN_LPHB */
15049 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015050 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15051 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070015052 return -EOPNOTSUPP;
15053 }
15054
15055 return err;
15056}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015057
15058static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
15059{
15060 int ret;
15061
15062 vos_ssr_protect(__func__);
15063 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
15064 vos_ssr_unprotect(__func__);
15065
15066 return ret;
15067}
Leo Chang9056f462013-08-01 19:21:11 -070015068#endif /* CONFIG_NL80211_TESTMODE */
15069
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015070static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015071 struct net_device *dev,
15072 int idx, struct survey_info *survey)
15073{
15074 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15075 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053015076 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015077 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053015078 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015079 v_S7_t snr,rssi;
15080 int status, i, j, filled = 0;
15081
15082 ENTER();
15083
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015084 if (NULL == pAdapter)
15085 {
15086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15087 "%s: HDD adapter is Null", __func__);
15088 return -ENODEV;
15089 }
15090
15091 if (NULL == wiphy)
15092 {
15093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15094 "%s: wiphy is Null", __func__);
15095 return -ENODEV;
15096 }
15097
15098 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15099 status = wlan_hdd_validate_context(pHddCtx);
15100
15101 if (0 != status)
15102 {
15103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15104 "%s: HDD context is not valid", __func__);
15105 return status;
15106 }
15107
Mihir Sheted9072e02013-08-21 17:02:29 +053015108 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15109
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015110 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053015111 0 != pAdapter->survey_idx ||
15112 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015113 {
15114 /* The survey dump ops when implemented completely is expected to
15115 * return a survey of all channels and the ops is called by the
15116 * kernel with incremental values of the argument 'idx' till it
15117 * returns -ENONET. But we can only support the survey for the
15118 * operating channel for now. survey_idx is used to track
15119 * that the ops is called only once and then return -ENONET for
15120 * the next iteration
15121 */
15122 pAdapter->survey_idx = 0;
15123 return -ENONET;
15124 }
15125
15126 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15127
15128 wlan_hdd_get_snr(pAdapter, &snr);
15129 wlan_hdd_get_rssi(pAdapter, &rssi);
15130
15131 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
15132 hdd_wlan_get_freq(channel, &freq);
15133
15134
15135 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
15136 {
15137 if (NULL == wiphy->bands[i])
15138 {
15139 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
15140 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
15141 continue;
15142 }
15143
15144 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
15145 {
15146 struct ieee80211_supported_band *band = wiphy->bands[i];
15147
15148 if (band->channels[j].center_freq == (v_U16_t)freq)
15149 {
15150 survey->channel = &band->channels[j];
15151 /* The Rx BDs contain SNR values in dB for the received frames
15152 * while the supplicant expects noise. So we calculate and
15153 * return the value of noise (dBm)
15154 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
15155 */
15156 survey->noise = rssi - snr;
15157 survey->filled = SURVEY_INFO_NOISE_DBM;
15158 filled = 1;
15159 }
15160 }
15161 }
15162
15163 if (filled)
15164 pAdapter->survey_idx = 1;
15165 else
15166 {
15167 pAdapter->survey_idx = 0;
15168 return -ENONET;
15169 }
15170
15171 return 0;
15172}
15173
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015174static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
15175 struct net_device *dev,
15176 int idx, struct survey_info *survey)
15177{
15178 int ret;
15179
15180 vos_ssr_protect(__func__);
15181 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
15182 vos_ssr_unprotect(__func__);
15183
15184 return ret;
15185}
15186
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015187/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015188 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015189 * this is called when cfg80211 driver resume
15190 * driver updates latest sched_scan scan result(if any) to cfg80211 database
15191 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015192int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015193{
15194 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15195 hdd_adapter_t *pAdapter;
15196 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15197 VOS_STATUS status = VOS_STATUS_SUCCESS;
15198
15199 ENTER();
15200
15201 if ( NULL == pHddCtx )
15202 {
15203 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15204 "%s: HddCtx validation failed", __func__);
15205 return 0;
15206 }
15207
15208 if (pHddCtx->isLogpInProgress)
15209 {
15210 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15211 "%s: LOGP in Progress. Ignore!!!", __func__);
15212 return 0;
15213 }
15214
Mihir Shete18156292014-03-11 15:38:30 +053015215 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015216 {
15217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15218 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15219 return 0;
15220 }
15221
15222 spin_lock(&pHddCtx->schedScan_lock);
15223 pHddCtx->isWiphySuspended = FALSE;
15224 if (TRUE != pHddCtx->isSchedScanUpdatePending)
15225 {
15226 spin_unlock(&pHddCtx->schedScan_lock);
15227 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15228 "%s: Return resume is not due to PNO indication", __func__);
15229 return 0;
15230 }
15231 // Reset flag to avoid updatating cfg80211 data old results again
15232 pHddCtx->isSchedScanUpdatePending = FALSE;
15233 spin_unlock(&pHddCtx->schedScan_lock);
15234
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015235
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015236 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15237
15238 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15239 {
15240 pAdapter = pAdapterNode->pAdapter;
15241 if ( (NULL != pAdapter) &&
15242 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
15243 {
15244 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015245 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15247 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015248 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015249 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015250 {
15251 /* Acquire wakelock to handle the case where APP's tries to
15252 * suspend immediately after updating the scan results. Whis
15253 * results in app's is in suspended state and not able to
15254 * process the connect request to AP
15255 */
15256 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015257 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015258 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015259
15260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15261 "%s : cfg80211 scan result database updated", __func__);
15262
15263 return 0;
15264
15265 }
15266 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15267 pAdapterNode = pNext;
15268 }
15269
15270 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15271 "%s: Failed to find Adapter", __func__);
15272 return 0;
15273}
15274
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015275int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
15276{
15277 int ret;
15278
15279 vos_ssr_protect(__func__);
15280 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
15281 vos_ssr_unprotect(__func__);
15282
15283 return ret;
15284}
15285
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015286/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015287 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015288 * this is called when cfg80211 driver suspends
15289 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015290int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015291 struct cfg80211_wowlan *wow)
15292{
15293 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15294
15295 ENTER();
15296 if (NULL == pHddCtx)
15297 {
15298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15299 "%s: HddCtx validation failed", __func__);
15300 return 0;
15301 }
15302
15303 pHddCtx->isWiphySuspended = TRUE;
15304
15305 EXIT();
15306
15307 return 0;
15308}
15309
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015310int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
15311 struct cfg80211_wowlan *wow)
15312{
15313 int ret;
15314
15315 vos_ssr_protect(__func__);
15316 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
15317 vos_ssr_unprotect(__func__);
15318
15319 return ret;
15320}
Jeff Johnson295189b2012-06-20 16:38:30 -070015321/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015322static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070015323{
15324 .add_virtual_intf = wlan_hdd_add_virtual_intf,
15325 .del_virtual_intf = wlan_hdd_del_virtual_intf,
15326 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
15327 .change_station = wlan_hdd_change_station,
15328#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
15329 .add_beacon = wlan_hdd_cfg80211_add_beacon,
15330 .del_beacon = wlan_hdd_cfg80211_del_beacon,
15331 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015332#else
15333 .start_ap = wlan_hdd_cfg80211_start_ap,
15334 .change_beacon = wlan_hdd_cfg80211_change_beacon,
15335 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070015336#endif
15337 .change_bss = wlan_hdd_cfg80211_change_bss,
15338 .add_key = wlan_hdd_cfg80211_add_key,
15339 .get_key = wlan_hdd_cfg80211_get_key,
15340 .del_key = wlan_hdd_cfg80211_del_key,
15341 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015342#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070015343 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015344#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015345 .scan = wlan_hdd_cfg80211_scan,
15346 .connect = wlan_hdd_cfg80211_connect,
15347 .disconnect = wlan_hdd_cfg80211_disconnect,
15348 .join_ibss = wlan_hdd_cfg80211_join_ibss,
15349 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
15350 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
15351 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
15352 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070015353 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
15354 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053015355 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070015356#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15357 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
15358 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
15359 .set_txq_params = wlan_hdd_set_txq_params,
15360#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015361 .get_station = wlan_hdd_cfg80211_get_station,
15362 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
15363 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015364 .add_station = wlan_hdd_cfg80211_add_station,
15365#ifdef FEATURE_WLAN_LFR
15366 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
15367 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
15368 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
15369#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015370#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
15371 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
15372#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015373#ifdef FEATURE_WLAN_TDLS
15374 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
15375 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
15376#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015377#ifdef WLAN_FEATURE_GTK_OFFLOAD
15378 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
15379#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015380#ifdef FEATURE_WLAN_SCAN_PNO
15381 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
15382 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
15383#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015384 .resume = wlan_hdd_cfg80211_resume_wlan,
15385 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015386 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070015387#ifdef WLAN_NL80211_TESTMODE
15388 .testmode_cmd = wlan_hdd_cfg80211_testmode,
15389#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015390 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070015391};
15392