blob: 42177dcf711f7399d90a0fc9d86dfdfe581f5d63 [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;
838
Sunil Duttc69bccb2014-05-26 21:30:20 +0530839 if (FALSE == put_wifi_interface_info(
840 &pWifiIfaceStat->info,
841 vendor_event))
842 {
843 hddLog(VOS_TRACE_LEVEL_ERROR,
844 FL("QCA_WLAN_VENDOR_ATTR put fail") );
845 return FALSE;
846
847 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530848 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
849 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
850 if (NULL == pWifiIfaceStatTL)
851 {
852 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
853 return FALSE;
854 }
855
856
857 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
858 {
859 if (VOS_STATUS_SUCCESS ==
860 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
861 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
862 {
863 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
864 * obtained from TL structure
865 */
866
867 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
868 pWifiIfaceStatTL->mgmtRx;
869 pWifiIfaceStat->mgmtActionRx = pWifiIfaceStatTL->mgmtActionRx;
870 pWifiIfaceStat->mgmtActionTx = pWifiIfaceStatTL->mgmtActionTx;
871 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
872
873 vos_mem_copy(
874 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_VO],
875 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO],
876 sizeof(WLANTL_AccessCategoryStatsType));
877
878 vos_mem_copy(
879 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_VI],
880 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI],
881 sizeof(WLANTL_AccessCategoryStatsType));
882
883 vos_mem_copy(
884 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_BE],
885 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE],
886 sizeof(WLANTL_AccessCategoryStatsType));
887
888 vos_mem_copy(
889 (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_BK],
890 (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK],
891 sizeof(WLANTL_AccessCategoryStatsType));
892 }
893 else
894 {
895 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
896 }
897
898 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMpdu =
899 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_VO];
900 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMpdu =
901 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_VI];
902 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMpdu =
903 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_BE];
904 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMpdu =
905 pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_BK];
906
907 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
908 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
909 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
910 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
911 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
912 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
913 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
914 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
915 }
916 else
917 {
918 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
919 }
920
921
Sunil Duttc69bccb2014-05-26 21:30:20 +0530922
923 if (nla_put_u32(vendor_event,
924 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
925 pWifiIfaceStat->beaconRx) ||
926 nla_put_u32(vendor_event,
927 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
928 pWifiIfaceStat->mgmtRx) ||
929 nla_put_u32(vendor_event,
930 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
931 pWifiIfaceStat->mgmtActionRx) ||
932 nla_put_u32(vendor_event,
933 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
934 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530935 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530936 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
937 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530938 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530939 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
940 pWifiIfaceStat->rssiData) ||
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_ACK,
943 pWifiIfaceStat->rssiAck))
944 {
945 hddLog(VOS_TRACE_LEVEL_ERROR,
946 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530947 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530948 return FALSE;
949 }
950
951 wmmInfo = nla_nest_start(vendor_event,
952 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
953 for (i = 0; i < WIFI_AC_MAX; i++)
954 {
955 struct nlattr *wmmStats;
956 wmmStats = nla_nest_start(vendor_event, i);
957 if (FALSE == put_wifi_wmm_ac_stat(
958 &pWifiIfaceStat->AccessclassStats[i],
959 vendor_event))
960 {
961 hddLog(VOS_TRACE_LEVEL_ERROR,
962 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530963 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530964 return FALSE;
965 }
966
967 nla_nest_end(vendor_event, wmmStats);
968 }
969 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +0530970 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530971 return TRUE;
972}
973
974static tSirWifiInterfaceMode
975 hdd_map_device_to_ll_iface_mode ( int deviceMode )
976{
977 switch (deviceMode)
978 {
979 case WLAN_HDD_INFRA_STATION:
980 return WIFI_INTERFACE_STA;
981 case WLAN_HDD_SOFTAP:
982 return WIFI_INTERFACE_SOFTAP;
983 case WLAN_HDD_P2P_CLIENT:
984 return WIFI_INTERFACE_P2P_CLIENT;
985 case WLAN_HDD_P2P_GO:
986 return WIFI_INTERFACE_P2P_GO;
987 case WLAN_HDD_IBSS:
988 return WIFI_INTERFACE_IBSS;
989 default:
Dino Myclec8f3f332014-07-21 16:48:27 +0530990 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530991 }
992}
993
994static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
995 tpSirWifiInterfaceInfo pInfo)
996{
997 v_U8_t *staMac = NULL;
998 hdd_station_ctx_t *pHddStaCtx;
999 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1000 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1001
1002 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1003
1004 vos_mem_copy(pInfo->macAddr,
1005 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1006
1007 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1008 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1009 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1010 {
1011 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1012 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1013 {
1014 pInfo->state = WIFI_DISCONNECTED;
1015 }
1016 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1017 {
1018 hddLog(VOS_TRACE_LEVEL_ERROR,
1019 "%s: Session ID %d, Connection is in progress", __func__,
1020 pAdapter->sessionId);
1021 pInfo->state = WIFI_ASSOCIATING;
1022 }
1023 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1024 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1025 {
1026 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1027 hddLog(VOS_TRACE_LEVEL_ERROR,
1028 "%s: client " MAC_ADDRESS_STR
1029 " is in the middle of WPS/EAPOL exchange.", __func__,
1030 MAC_ADDR_ARRAY(staMac));
1031 pInfo->state = WIFI_AUTHENTICATING;
1032 }
1033 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1034 {
1035 pInfo->state = WIFI_ASSOCIATED;
1036 vos_mem_copy(pInfo->bssid,
1037 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1038 vos_mem_copy(pInfo->ssid,
1039 pHddStaCtx->conn_info.SSID.SSID.ssId,
1040 pHddStaCtx->conn_info.SSID.SSID.length);
1041 //NULL Terminate the string.
1042 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1043 }
1044 }
1045 vos_mem_copy(pInfo->countryStr,
1046 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1047
1048 vos_mem_copy(pInfo->apCountryStr,
1049 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1050
1051 return TRUE;
1052}
1053
1054/*
1055 * hdd_link_layer_process_peer_stats () - This function is called after
1056 * receiving Link Layer Peer statistics from FW.This function converts
1057 * the firmware data to the NL data and sends the same to the kernel/upper
1058 * layers.
1059 */
1060static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1061 v_VOID_t *pData)
1062{
1063 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1064 tpSirWifiRateStat pWifiRateStat;
1065 tpSirWifiPeerStat pWifiPeerStat;
1066 tpSirWifiPeerInfo pWifiPeerInfo;
1067 struct nlattr *peerInfo;
1068 struct sk_buff *vendor_event;
1069 int status, i;
1070
1071 status = wlan_hdd_validate_context(pHddCtx);
1072 if (0 != status)
1073 {
1074 hddLog(VOS_TRACE_LEVEL_ERROR,
1075 FL("HDD context is not valid") );
1076 return;
1077 }
1078
1079 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1080
1081 hddLog(VOS_TRACE_LEVEL_INFO,
1082 "LL_STATS_PEER_ALL : numPeers %u",
1083 pWifiPeerStat->numPeers);
1084 {
1085 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1086 {
1087 pWifiPeerInfo = (tpSirWifiPeerInfo)
1088 ((uint8 *)pWifiPeerStat->peerInfo +
1089 ( i * sizeof(tSirWifiPeerInfo)));
1090
Dasari Srinivas1be0c4e2014-10-19 13:03:41 +05301091 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) {
1092 pWifiPeerInfo->type = WIFI_PEER_AP;
1093 }
1094 if (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) {
1095 pWifiPeerInfo->type = WIFI_PEER_P2P_GO;
1096 }
1097
Sunil Duttc69bccb2014-05-26 21:30:20 +05301098 hddLog(VOS_TRACE_LEVEL_INFO,
1099 " %d) LL_STATS Channel Stats "
1100 " Peer Type %u "
1101 " peerMacAddress %pM "
1102 " capabilities 0x%x "
1103 " numRate %u ",
1104 i,
1105 pWifiPeerInfo->type,
1106 pWifiPeerInfo->peerMacAddress,
1107 pWifiPeerInfo->capabilities,
1108 pWifiPeerInfo->numRate);
1109 {
1110 int j;
1111 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1112 {
1113 pWifiRateStat = (tpSirWifiRateStat)
1114 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1115 ( j * sizeof(tSirWifiRateStat)));
1116
1117 hddLog(VOS_TRACE_LEVEL_INFO,
1118 " peer Rate Stats "
1119 " preamble %u "
1120 " nss %u "
1121 " bw %u "
1122 " rateMcsIdx %u "
1123 " reserved %u "
1124 " bitrate %u "
1125 " txMpdu %u "
1126 " rxMpdu %u "
1127 " mpduLost %u "
1128 " retries %u "
1129 " retriesShort %u "
1130 " retriesLong %u",
1131 pWifiRateStat->rate.preamble,
1132 pWifiRateStat->rate.nss,
1133 pWifiRateStat->rate.bw,
1134 pWifiRateStat->rate.rateMcsIdx,
1135 pWifiRateStat->rate.reserved,
1136 pWifiRateStat->rate.bitrate,
1137 pWifiRateStat->txMpdu,
1138 pWifiRateStat->rxMpdu,
1139 pWifiRateStat->mpduLost,
1140 pWifiRateStat->retries,
1141 pWifiRateStat->retriesShort,
1142 pWifiRateStat->retriesLong);
1143 }
1144 }
1145 }
1146 }
1147
1148 /*
1149 * Allocate a size of 4096 for the peer stats comprising
1150 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1151 * sizeof (tSirWifiRateStat).Each field is put with an
1152 * NL attribute.The size of 4096 is considered assuming
1153 * that number of rates shall not exceed beyond 50 with
1154 * the sizeof (tSirWifiRateStat) being 32.
1155 */
1156 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1157 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1158 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1159 GFP_KERNEL);
1160 if (!vendor_event)
1161 {
1162 hddLog(VOS_TRACE_LEVEL_ERROR,
1163 "%s: cfg80211_vendor_event_alloc failed",
1164 __func__);
1165 return;
1166 }
1167 if (nla_put_u32(vendor_event,
1168 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1169 pWifiPeerStat->numPeers))
1170 {
1171 hddLog(VOS_TRACE_LEVEL_ERROR,
1172 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1173 kfree_skb(vendor_event);
1174 return;
1175 }
1176
1177 peerInfo = nla_nest_start(vendor_event,
1178 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
1179
1180 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1181 pWifiPeerStat->peerInfo);
1182
1183 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1184 {
1185 struct nlattr *peers = nla_nest_start(vendor_event, i);
1186 int numRate = pWifiPeerInfo->numRate;
1187
1188 if (FALSE == put_wifi_peer_info(
1189 pWifiPeerInfo, vendor_event))
1190 {
1191 hddLog(VOS_TRACE_LEVEL_ERROR,
1192 "%s: put_wifi_peer_info put fail", __func__);
1193 kfree_skb(vendor_event);
1194 return;
1195 }
1196
1197 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1198 pWifiPeerStat->peerInfo +
1199 (i * sizeof(tSirWifiPeerInfo)) +
1200 (numRate * sizeof (tSirWifiRateStat)));
1201 nla_nest_end(vendor_event, peers);
1202 }
1203 nla_nest_end(vendor_event, peerInfo);
1204 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1205}
1206
1207/*
1208 * hdd_link_layer_process_iface_stats () - This function is called after
1209 * receiving Link Layer Interface statistics from FW.This function converts
1210 * the firmware data to the NL data and sends the same to the kernel/upper
1211 * layers.
1212 */
1213static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1214 v_VOID_t *pData)
1215{
1216 tpSirWifiIfaceStat pWifiIfaceStat;
1217 struct sk_buff *vendor_event;
1218 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1219 int status;
1220
1221 status = wlan_hdd_validate_context(pHddCtx);
1222 if (0 != status)
1223 {
1224 hddLog(VOS_TRACE_LEVEL_ERROR,
1225 FL("HDD context is not valid") );
1226 return;
1227 }
1228 /*
1229 * Allocate a size of 4096 for the interface stats comprising
1230 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1231 * assuming that all these fit with in the limit.Please take
1232 * a call on the limit based on the data requirements on
1233 * interface statistics.
1234 */
1235 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1236 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1237 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1238 GFP_KERNEL);
1239 if (!vendor_event)
1240 {
1241 hddLog(VOS_TRACE_LEVEL_ERROR,
1242 FL("cfg80211_vendor_event_alloc failed") );
1243 return;
1244 }
1245
1246 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1247
Dino Mycle3b9536d2014-07-09 22:05:24 +05301248
1249 if (FALSE == hdd_get_interface_info( pAdapter,
1250 &pWifiIfaceStat->info))
1251 {
1252 hddLog(VOS_TRACE_LEVEL_ERROR,
1253 FL("hdd_get_interface_info get fail") );
1254 kfree_skb(vendor_event);
1255 return;
1256 }
1257
1258 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1259 vendor_event))
1260 {
1261 hddLog(VOS_TRACE_LEVEL_ERROR,
1262 FL("put_wifi_iface_stats fail") );
1263 kfree_skb(vendor_event);
1264 return;
1265 }
1266
Sunil Duttc69bccb2014-05-26 21:30:20 +05301267 hddLog(VOS_TRACE_LEVEL_INFO,
1268 "WMI_LINK_STATS_IFACE Data");
1269
1270 hddLog(VOS_TRACE_LEVEL_INFO,
1271 "LL_STATS_IFACE: "
1272 " Mode %u "
1273 " MAC %pM "
1274 " State %u "
1275 " Roaming %u "
1276 " capabilities 0x%x "
1277 " SSID %s "
1278 " BSSID %pM",
1279 pWifiIfaceStat->info.mode,
1280 pWifiIfaceStat->info.macAddr,
1281 pWifiIfaceStat->info.state,
1282 pWifiIfaceStat->info.roaming,
1283 pWifiIfaceStat->info.capabilities,
1284 pWifiIfaceStat->info.ssid,
1285 pWifiIfaceStat->info.bssid);
1286
1287 hddLog(VOS_TRACE_LEVEL_INFO,
1288 " AP country str: %c%c%c",
1289 pWifiIfaceStat->info.apCountryStr[0],
1290 pWifiIfaceStat->info.apCountryStr[1],
1291 pWifiIfaceStat->info.apCountryStr[2]);
1292
1293
1294 hddLog(VOS_TRACE_LEVEL_INFO,
1295 " Country Str Association: %c%c%c",
1296 pWifiIfaceStat->info.countryStr[0],
1297 pWifiIfaceStat->info.countryStr[1],
1298 pWifiIfaceStat->info.countryStr[2]);
1299
1300 hddLog(VOS_TRACE_LEVEL_INFO,
1301 " beaconRx %u "
1302 " mgmtRx %u "
1303 " mgmtActionRx %u "
1304 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301305 " rssiMgmt %d "
1306 " rssiData %d "
1307 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301308 pWifiIfaceStat->beaconRx,
1309 pWifiIfaceStat->mgmtRx,
1310 pWifiIfaceStat->mgmtActionRx,
1311 pWifiIfaceStat->mgmtActionTx,
1312 pWifiIfaceStat->rssiMgmt,
1313 pWifiIfaceStat->rssiData,
1314 pWifiIfaceStat->rssiAck );
1315
1316
1317 {
1318 int i;
1319 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1320 {
1321 hddLog(VOS_TRACE_LEVEL_INFO,
1322
1323 " %d) LL_STATS IFACE: "
1324 " ac: %u txMpdu: %u "
1325 " rxMpdu: %u txMcast: %u "
1326 " rxMcast: %u rxAmpdu: %u "
1327 " txAmpdu: %u mpduLost: %u "
1328 " retries: %u retriesShort: %u "
1329 " retriesLong: %u contentionTimeMin: %u "
1330 " contentionTimeMax: %u contentionTimeAvg: %u "
1331 " contentionNumSamples: %u",
1332 i,
1333 pWifiIfaceStat->AccessclassStats[i].ac,
1334 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1335 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1336 pWifiIfaceStat->AccessclassStats[i].txMcast,
1337 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1338 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1339 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1340 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1341 pWifiIfaceStat->AccessclassStats[i].retries,
1342 pWifiIfaceStat->
1343 AccessclassStats[i].retriesShort,
1344 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1345 pWifiIfaceStat->
1346 AccessclassStats[i].contentionTimeMin,
1347 pWifiIfaceStat->
1348 AccessclassStats[i].contentionTimeMax,
1349 pWifiIfaceStat->
1350 AccessclassStats[i].contentionTimeAvg,
1351 pWifiIfaceStat->
1352 AccessclassStats[i].contentionNumSamples);
1353
1354 }
1355 }
1356
Sunil Duttc69bccb2014-05-26 21:30:20 +05301357 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1358}
1359
1360/*
1361 * hdd_link_layer_process_radio_stats () - This function is called after
1362 * receiving Link Layer Radio statistics from FW.This function converts
1363 * the firmware data to the NL data and sends the same to the kernel/upper
1364 * layers.
1365 */
1366static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1367 v_VOID_t *pData)
1368{
1369 int status, i;
1370 tpSirWifiRadioStat pWifiRadioStat;
1371 tpSirWifiChannelStats pWifiChannelStats;
1372 struct sk_buff *vendor_event;
1373 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1374 struct nlattr *chList;
1375
1376 status = wlan_hdd_validate_context(pHddCtx);
1377 if (0 != status)
1378 {
1379 hddLog(VOS_TRACE_LEVEL_ERROR,
1380 FL("HDD context is not valid") );
1381 return;
1382 }
1383 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1384
1385 hddLog(VOS_TRACE_LEVEL_INFO,
1386 "LL_STATS_RADIO"
1387 " radio is %d onTime is %u "
1388 " txTime is %u rxTime is %u "
1389 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301390 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301391 " onTimePnoScan is %u onTimeHs20 is %u "
1392 " numChannels is %u",
1393 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1394 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1395 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301396 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301397 pWifiRadioStat->onTimeRoamScan,
1398 pWifiRadioStat->onTimePnoScan,
1399 pWifiRadioStat->onTimeHs20,
1400 pWifiRadioStat->numChannels);
1401 /*
1402 * Allocate a size of 4096 for the Radio stats comprising
1403 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1404 * (tSirWifiChannelStats).Each channel data is put with an
1405 * NL attribute.The size of 4096 is considered assuming that
1406 * number of channels shall not exceed beyond 60 with the
1407 * sizeof (tSirWifiChannelStats) being 24 bytes.
1408 */
1409
1410 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1411 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1412 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1413 GFP_KERNEL);
1414
1415 if (!vendor_event)
1416 {
1417 hddLog(VOS_TRACE_LEVEL_ERROR,
1418 FL("cfg80211_vendor_event_alloc failed") );
1419 return;
1420 }
1421
1422 if (nla_put_u32(vendor_event,
1423 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1424 pWifiRadioStat->radio) ||
1425 nla_put_u32(vendor_event,
1426 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1427 pWifiRadioStat->onTime) ||
1428 nla_put_u32(vendor_event,
1429 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1430 pWifiRadioStat->txTime) ||
1431 nla_put_u32(vendor_event,
1432 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1433 pWifiRadioStat->rxTime) ||
1434 nla_put_u32(vendor_event,
1435 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1436 pWifiRadioStat->onTimeScan) ||
1437 nla_put_u32(vendor_event,
1438 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1439 pWifiRadioStat->onTimeNbd) ||
1440 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301441 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1442 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301443 nla_put_u32(vendor_event,
1444 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1445 pWifiRadioStat->onTimeRoamScan) ||
1446 nla_put_u32(vendor_event,
1447 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1448 pWifiRadioStat->onTimePnoScan) ||
1449 nla_put_u32(vendor_event,
1450 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1451 pWifiRadioStat->onTimeHs20) ||
1452 nla_put_u32(vendor_event,
1453 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1454 pWifiRadioStat->numChannels))
1455 {
1456 hddLog(VOS_TRACE_LEVEL_ERROR,
1457 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1458 kfree_skb(vendor_event);
1459 return ;
1460 }
1461
1462 chList = nla_nest_start(vendor_event,
1463 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
1464 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1465 {
1466 struct nlattr *chInfo;
1467
1468 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1469 pWifiRadioStat->channels +
1470 (i * sizeof(tSirWifiChannelStats)));
1471
1472 hddLog(VOS_TRACE_LEVEL_INFO,
1473 " %d) Channel Info"
1474 " width is %u "
1475 " CenterFreq %u "
1476 " CenterFreq0 %u "
1477 " CenterFreq1 %u "
1478 " onTime %u "
1479 " ccaBusyTime %u",
1480 i,
1481 pWifiChannelStats->channel.width,
1482 pWifiChannelStats->channel.centerFreq,
1483 pWifiChannelStats->channel.centerFreq0,
1484 pWifiChannelStats->channel.centerFreq1,
1485 pWifiChannelStats->onTime,
1486 pWifiChannelStats->ccaBusyTime);
1487
1488
1489 chInfo = nla_nest_start(vendor_event, i);
1490
1491 if (nla_put_u32(vendor_event,
1492 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1493 pWifiChannelStats->channel.width) ||
1494 nla_put_u32(vendor_event,
1495 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1496 pWifiChannelStats->channel.centerFreq) ||
1497 nla_put_u32(vendor_event,
1498 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1499 pWifiChannelStats->channel.centerFreq0) ||
1500 nla_put_u32(vendor_event,
1501 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1502 pWifiChannelStats->channel.centerFreq1) ||
1503 nla_put_u32(vendor_event,
1504 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1505 pWifiChannelStats->onTime) ||
1506 nla_put_u32(vendor_event,
1507 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1508 pWifiChannelStats->ccaBusyTime))
1509 {
1510 hddLog(VOS_TRACE_LEVEL_ERROR,
1511 FL("cfg80211_vendor_event_alloc failed") );
1512 kfree_skb(vendor_event);
1513 return ;
1514 }
1515 nla_nest_end(vendor_event, chInfo);
1516 }
1517 nla_nest_end(vendor_event, chList);
1518
1519 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1520 return;
1521}
1522
1523/*
1524 * hdd_link_layer_stats_ind_callback () - This function is called after
1525 * receiving Link Layer indications from FW.This callback converts the firmware
1526 * data to the NL data and send the same to the kernel/upper layers.
1527 */
1528static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1529 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301530 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301531{
Dino Mycled3d50022014-07-07 12:58:25 +05301532 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1533 hdd_adapter_t *pAdapter = NULL;
1534 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301535 int status;
1536
1537 status = wlan_hdd_validate_context(pHddCtx);
1538
1539 if (0 != status)
1540 {
1541 hddLog(VOS_TRACE_LEVEL_ERROR,
1542 FL("HDD context is not valid"));
1543 return;
1544 }
1545
Dino Mycled3d50022014-07-07 12:58:25 +05301546
1547
1548 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1549 if (NULL == pAdapter)
1550 {
1551 hddLog(VOS_TRACE_LEVEL_ERROR,
1552 FL(" MAC address %pM does not exist with host"),
1553 macAddr);
1554 return;
1555 }
1556
Sunil Duttc69bccb2014-05-26 21:30:20 +05301557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301558 "%s: Interface: %s LLStats indType: %d", __func__,
1559 pAdapter->dev->name, indType);
1560
Sunil Duttc69bccb2014-05-26 21:30:20 +05301561 switch (indType)
1562 {
1563 case SIR_HAL_LL_STATS_RESULTS_RSP:
1564 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301565 hddLog(VOS_TRACE_LEVEL_INFO,
1566 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1567 hddLog(VOS_TRACE_LEVEL_INFO,
1568 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1569 linkLayerStatsResults->paramId);
1570 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301571 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1572 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301573 hddLog(VOS_TRACE_LEVEL_INFO,
1574 "LL_STATS RESULTS RESPONSE respId = %u",
1575 linkLayerStatsResults->respId);
1576 hddLog(VOS_TRACE_LEVEL_INFO,
1577 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1578 linkLayerStatsResults->moreResultToFollow);
1579 hddLog(VOS_TRACE_LEVEL_INFO,
1580 "LL_STATS RESULTS RESPONSE result = %p",
1581 linkLayerStatsResults->result);
1582 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1583 {
1584 hdd_link_layer_process_radio_stats(pAdapter,
1585 (v_VOID_t *)linkLayerStatsResults->result);
1586 }
1587 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1588 {
1589 hdd_link_layer_process_iface_stats(pAdapter,
1590 (v_VOID_t *)linkLayerStatsResults->result);
1591 }
1592 else if ( linkLayerStatsResults->paramId &
1593 WMI_LINK_STATS_ALL_PEER )
1594 {
1595 hdd_link_layer_process_peer_stats(pAdapter,
1596 (v_VOID_t *)linkLayerStatsResults->result);
1597 } /* WMI_LINK_STATS_ALL_PEER */
1598 else
1599 {
1600 hddLog(VOS_TRACE_LEVEL_ERROR,
1601 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1602 }
1603
1604 break;
1605 }
1606 default:
1607 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1608 break;
1609 }
1610 return;
1611}
1612
1613const struct
1614nla_policy
1615qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1616{
1617 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1618 { .type = NLA_U32 },
1619 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1620 { .type = NLA_U32 },
1621};
1622
1623static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1624 struct wireless_dev *wdev,
1625 void *data,
1626 int data_len)
1627{
1628 int status;
1629 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301630 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301631 struct net_device *dev = wdev->netdev;
1632 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1633 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1634
1635 status = wlan_hdd_validate_context(pHddCtx);
1636 if (0 != status)
1637 {
1638 hddLog(VOS_TRACE_LEVEL_ERROR,
1639 FL("HDD context is not valid"));
1640 return -EINVAL;
1641 }
1642
1643 if (NULL == pAdapter)
1644 {
1645 hddLog(VOS_TRACE_LEVEL_ERROR,
1646 FL("HDD adapter is Null"));
1647 return -ENODEV;
1648 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301649 /* check the LLStats Capability */
1650 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1651 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1652 {
1653 hddLog(VOS_TRACE_LEVEL_ERROR,
1654 FL("Link Layer Statistics not supported by Firmware"));
1655 return -EINVAL;
1656 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301657
1658 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1659 (struct nlattr *)data,
1660 data_len, qca_wlan_vendor_ll_set_policy))
1661 {
1662 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1663 return -EINVAL;
1664 }
1665 if (!tb_vendor
1666 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1667 {
1668 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1669 return -EINVAL;
1670 }
1671 if (!tb_vendor[
1672 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1673 {
1674 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1675 return -EINVAL;
1676 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301677 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301678 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301679
Dino Mycledf0a5d92014-07-04 09:41:55 +05301680 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301681 nla_get_u32(
1682 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1683
Dino Mycledf0a5d92014-07-04 09:41:55 +05301684 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301685 nla_get_u32(
1686 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1687
Dino Mycled3d50022014-07-07 12:58:25 +05301688 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1689 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301690
1691
1692 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301693 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301694 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301695 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301696 hddLog(VOS_TRACE_LEVEL_INFO,
1697 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301698 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301699 hddLog(VOS_TRACE_LEVEL_INFO,
1700 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301701 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301702
1703 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1704 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301705 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301706 {
1707 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1708 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301709 return -EINVAL;
1710
1711 }
1712 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301713 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301714 {
1715 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1716 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301717 return -EINVAL;
1718 }
1719
1720 pAdapter->isLinkLayerStatsSet = 1;
1721
1722 return 0;
1723}
1724
1725const struct
1726nla_policy
1727qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1728{
1729 /* Unsigned 32bit value provided by the caller issuing the GET stats
1730 * command. When reporting
1731 * the stats results, the driver uses the same value to indicate
1732 * which GET request the results
1733 * correspond to.
1734 */
1735 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1736
1737 /* Unsigned 32bit value . bit mask to identify what statistics are
1738 requested for retrieval */
1739 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1740};
1741
1742static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1743 struct wireless_dev *wdev,
1744 void *data,
1745 int data_len)
1746{
1747 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1748 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301749 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301750 struct net_device *dev = wdev->netdev;
1751 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1752 int status;
1753
1754 status = wlan_hdd_validate_context(pHddCtx);
1755 if (0 != status)
1756 {
1757 hddLog(VOS_TRACE_LEVEL_ERROR,
1758 FL("HDD context is not valid"));
1759 return -EINVAL ;
1760 }
1761
1762 if (NULL == pAdapter)
1763 {
1764 hddLog(VOS_TRACE_LEVEL_FATAL,
1765 "%s: HDD adapter is Null", __func__);
1766 return -ENODEV;
1767 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301768 /* check the LLStats Capability */
1769 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1770 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1771 {
1772 hddLog(VOS_TRACE_LEVEL_ERROR,
1773 FL("Link Layer Statistics not supported by Firmware"));
1774 return -EINVAL;
1775 }
1776
Sunil Duttc69bccb2014-05-26 21:30:20 +05301777
1778 if (!pAdapter->isLinkLayerStatsSet)
1779 {
1780 hddLog(VOS_TRACE_LEVEL_FATAL,
1781 "%s: isLinkLayerStatsSet : %d",
1782 __func__, pAdapter->isLinkLayerStatsSet);
1783 return -EINVAL;
1784 }
1785
1786 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1787 (struct nlattr *)data,
1788 data_len, qca_wlan_vendor_ll_get_policy))
1789 {
1790 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1791 return -EINVAL;
1792 }
1793
1794 if (!tb_vendor
1795 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1796 {
1797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1798 return -EINVAL;
1799 }
1800
1801 if (!tb_vendor
1802 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1803 {
1804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1805 return -EINVAL;
1806 }
1807
Sunil Duttc69bccb2014-05-26 21:30:20 +05301808
Dino Mycledf0a5d92014-07-04 09:41:55 +05301809 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301810 nla_get_u32( tb_vendor[
1811 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301812 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301813 nla_get_u32( tb_vendor[
1814 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1815
Dino Mycled3d50022014-07-07 12:58:25 +05301816 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1817 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301818
1819 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301820 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301821 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301822 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301823 hddLog(VOS_TRACE_LEVEL_INFO,
1824 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301825 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301826
1827 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301828 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301829 {
1830 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1831 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301832 return -EINVAL;
1833 }
1834 return 0;
1835}
1836
1837const struct
1838nla_policy
1839qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1840{
1841 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1842 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1843 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1844 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1845};
1846
1847static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1848 struct wireless_dev *wdev,
1849 void *data,
1850 int data_len)
1851{
1852 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1853 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301854 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301855 struct net_device *dev = wdev->netdev;
1856 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1857 u32 statsClearReqMask;
1858 u8 stopReq;
1859 int status;
1860
1861 status = wlan_hdd_validate_context(pHddCtx);
1862 if (0 != status)
1863 {
1864 hddLog(VOS_TRACE_LEVEL_ERROR,
1865 FL("HDD context is not valid"));
1866 return -EINVAL;
1867 }
1868
1869 if (NULL == pAdapter)
1870 {
1871 hddLog(VOS_TRACE_LEVEL_FATAL,
1872 "%s: HDD adapter is Null", __func__);
1873 return -ENODEV;
1874 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301875 /* check the LLStats Capability */
1876 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1877 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1878 {
1879 hddLog(VOS_TRACE_LEVEL_ERROR,
1880 FL("Enable LLStats Capability"));
1881 return -EINVAL;
1882 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301883
1884 if (!pAdapter->isLinkLayerStatsSet)
1885 {
1886 hddLog(VOS_TRACE_LEVEL_FATAL,
1887 "%s: isLinkLayerStatsSet : %d",
1888 __func__, pAdapter->isLinkLayerStatsSet);
1889 return -EINVAL;
1890 }
1891
1892 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1893 (struct nlattr *)data,
1894 data_len, qca_wlan_vendor_ll_clr_policy))
1895 {
1896 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1897 return -EINVAL;
1898 }
1899
1900 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
1901
1902 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
1903 {
1904 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
1905 return -EINVAL;
1906
1907 }
1908
Sunil Duttc69bccb2014-05-26 21:30:20 +05301909
Dino Mycledf0a5d92014-07-04 09:41:55 +05301910 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301911 nla_get_u32(
1912 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
1913
Dino Mycledf0a5d92014-07-04 09:41:55 +05301914 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301915 nla_get_u8(
1916 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
1917
1918 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301919 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301920
Dino Mycled3d50022014-07-07 12:58:25 +05301921 vos_mem_copy(linkLayerStatsClearReq.macAddr,
1922 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301923
1924 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301925 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301926 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301927 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301928 hddLog(VOS_TRACE_LEVEL_INFO,
1929 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301930 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301931 hddLog(VOS_TRACE_LEVEL_INFO,
1932 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301933 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301934
1935 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301936 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301937 {
1938 struct sk_buff *temp_skbuff;
1939 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
1940 2 * sizeof(u32) +
1941 NLMSG_HDRLEN);
1942
1943 if (temp_skbuff != NULL)
1944 {
1945
1946 if (nla_put_u32(temp_skbuff,
1947 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
1948 statsClearReqMask) ||
1949 nla_put_u32(temp_skbuff,
1950 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
1951 stopReq))
1952 {
1953 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
1954 kfree_skb(temp_skbuff);
1955 return -EINVAL;
1956 }
1957 /* If the ask is to stop the stats collection as part of clear
1958 * (stopReq = 1) , ensure that no further requests of get
1959 * go to the firmware by having isLinkLayerStatsSet set to 0.
1960 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301961 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05301962 * case the firmware is just asked to clear the statistics.
1963 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05301964 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301965 pAdapter->isLinkLayerStatsSet = 0;
1966 return cfg80211_vendor_cmd_reply(temp_skbuff);
1967 }
1968 return -ENOMEM;
1969 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301970 return -EINVAL;
1971}
1972#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
1973
Dino Mycle6fb96c12014-06-10 11:52:40 +05301974#ifdef WLAN_FEATURE_EXTSCAN
1975static const struct nla_policy
1976wlan_hdd_extscan_config_policy
1977 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
1978{
1979 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
1980 { .type = NLA_U32 },
1981 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
1982 { .type = NLA_U32 },
1983 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
1984 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
1985 { .type = NLA_U32 },
1986 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
1987 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
1988
1989 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
1990 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
1991 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
1992 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
1993 { .type = NLA_U8 },
1994 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
1995 { .type = NLA_U32 },
1996 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
1997 { .type = NLA_U32 },
1998 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
1999 { .type = NLA_U32 },
2000 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
2001 { .type = NLA_U8 },
2002 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2003 { .type = NLA_U8 },
2004 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2005 { .type = NLA_U8 },
2006
2007 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2008 { .type = NLA_U32 },
2009 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2010 { .type = NLA_UNSPEC },
2011 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2012 { .type = NLA_S32 },
2013 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2014 { .type = NLA_S32 },
2015 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2016 { .type = NLA_U32 },
2017 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2018 { .type = NLA_U32 },
2019 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2020 { .type = NLA_U32 },
2021 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2022 = { .type = NLA_U32 },
2023 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2024 { .type = NLA_U32 },
2025 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2026 NLA_U32 },
2027};
2028
2029static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
2030{
2031 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2032 struct sk_buff *skb = NULL;
2033 tpSirEXTScanCapabilitiesEvent pData =
2034 (tpSirEXTScanCapabilitiesEvent) pMsg;
2035
2036 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2037 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2038 "or pData(%p) is null"), pData);
2039 return;
2040 }
2041
2042 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2043 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2044 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
2045 GFP_KERNEL);
2046
2047 if (!skb) {
2048 hddLog(VOS_TRACE_LEVEL_ERROR,
2049 FL("cfg80211_vendor_event_alloc failed"));
2050 return;
2051 }
2052
2053 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2054 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
2055 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
2056 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
2057 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
2058 pData->maxRssiSampleSize);
2059 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
2060 pData->maxScanReportingThreshold);
2061 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
2062 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
2063 pData->maxSignificantWifiChangeAPs);
2064 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
2065 pData->maxBsidHistoryEntries);
2066
2067 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2068 pData->requestId) ||
2069 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
2070 nla_put_u32(skb,
2071 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
2072 pData->scanCacheSize) ||
2073 nla_put_u32(skb,
2074 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
2075 pData->scanBuckets) ||
2076 nla_put_u32(skb,
2077 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
2078 pData->maxApPerScan) ||
2079 nla_put_u32(skb,
2080 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
2081 pData->maxRssiSampleSize) ||
2082 nla_put_u32(skb,
2083 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
2084 pData->maxScanReportingThreshold) ||
2085 nla_put_u32(skb,
2086 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
2087 pData->maxHotlistAPs) ||
2088 nla_put_u32(skb,
2089 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
2090 pData->maxSignificantWifiChangeAPs) ||
2091 nla_put_u32(skb,
2092 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2093 pData->maxBsidHistoryEntries)) {
2094 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2095 goto nla_put_failure;
2096 }
2097
2098 cfg80211_vendor_event(skb, GFP_KERNEL);
2099 return;
2100
2101nla_put_failure:
2102 kfree_skb(skb);
2103 return;
2104}
2105
2106
2107static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2108{
2109 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2110 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2111 struct sk_buff *skb = NULL;
2112 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2113
2114
2115 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2116 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2117 "or pData(%p) is null"), pData);
2118 return;
2119 }
2120
2121 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2122 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2123 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2124 GFP_KERNEL);
2125
2126 if (!skb) {
2127 hddLog(VOS_TRACE_LEVEL_ERROR,
2128 FL("cfg80211_vendor_event_alloc failed"));
2129 return;
2130 }
2131 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2132 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2133 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2134
2135 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2136 pData->requestId) ||
2137 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2139 goto nla_put_failure;
2140 }
2141
2142 /*
2143 * Store the Request ID for comparing with the requestID obtained
2144 * in other requests.HDD shall return a failure is the extscan_stop
2145 * request is issued with a different requestId as that of the
2146 * extscan_start request. Also, This requestId shall be used while
2147 * indicating the full scan results to the upper layers.
2148 * The requestId is stored with the assumption that the firmware
2149 * shall return the ext scan start request's requestId in ext scan
2150 * start response.
2151 */
2152 if (pData->status == 0)
2153 pMac->sme.extScanStartReqId = pData->requestId;
2154
2155
2156 cfg80211_vendor_event(skb, GFP_KERNEL);
2157 return;
2158
2159nla_put_failure:
2160 kfree_skb(skb);
2161 return;
2162}
2163
2164
2165static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2166{
2167 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2168 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2169 struct sk_buff *skb = NULL;
2170
2171 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2172 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2173 "or pData(%p) is null"), pData);
2174 return;
2175 }
2176
2177 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2178 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2179 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2180 GFP_KERNEL);
2181
2182 if (!skb) {
2183 hddLog(VOS_TRACE_LEVEL_ERROR,
2184 FL("cfg80211_vendor_event_alloc failed"));
2185 return;
2186 }
2187 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2188 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2189
2190 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2191 pData->requestId) ||
2192 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2193 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2194 goto nla_put_failure;
2195 }
2196
2197 cfg80211_vendor_event(skb, GFP_KERNEL);
2198 return;
2199
2200nla_put_failure:
2201 kfree_skb(skb);
2202 return;
2203}
2204
2205
2206static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2207 void *pMsg)
2208{
2209 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2210 struct sk_buff *skb = NULL;
2211 tpSirEXTScanSetBssidHotListRspParams pData =
2212 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2213
2214 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2215 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2216 "or pData(%p) is null"), pData);
2217 return;
2218 }
2219 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2220 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2221 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_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 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2232
2233 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2234 pData->requestId) ||
2235 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2237 goto nla_put_failure;
2238 }
2239
2240 cfg80211_vendor_event(skb, GFP_KERNEL);
2241 return;
2242
2243nla_put_failure:
2244 kfree_skb(skb);
2245 return;
2246}
2247
2248static void wlan_hdd_cfg80211_extscan_reset_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 tpSirEXTScanResetBssidHotlistRspParams pData =
2254 (tpSirEXTScanResetBssidHotlistRspParams) 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
2262 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2263 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2264 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2265 GFP_KERNEL);
2266
2267 if (!skb) {
2268 hddLog(VOS_TRACE_LEVEL_ERROR,
2269 FL("cfg80211_vendor_event_alloc failed"));
2270 return;
2271 }
2272 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2273 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2274
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
2290
2291static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2292 void *pMsg)
2293{
2294 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2295 struct sk_buff *skb = NULL;
2296 tpSirEXTScanSetSignificantChangeRspParams pData =
2297 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2298
2299 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2300 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2301 "or pData(%p) is null"), pData);
2302 return;
2303 }
2304
2305 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2306 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2307 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2308 GFP_KERNEL);
2309
2310 if (!skb) {
2311 hddLog(VOS_TRACE_LEVEL_ERROR,
2312 FL("cfg80211_vendor_event_alloc failed"));
2313 return;
2314 }
2315 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2316 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2317 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2318
2319 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2320 pData->requestId) ||
2321 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2322 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2323 goto nla_put_failure;
2324 }
2325
2326 cfg80211_vendor_event(skb, GFP_KERNEL);
2327 return;
2328
2329nla_put_failure:
2330 kfree_skb(skb);
2331 return;
2332}
2333
2334
2335static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2336 void *pMsg)
2337{
2338 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2339 struct sk_buff *skb = NULL;
2340 tpSirEXTScanResetSignificantChangeRspParams pData =
2341 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2342
2343 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2344 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2345 "or pData(%p) is null"), pData);
2346 return;
2347 }
2348
2349 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2350 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2351 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2352 GFP_KERNEL);
2353
2354 if (!skb) {
2355 hddLog(VOS_TRACE_LEVEL_ERROR,
2356 FL("cfg80211_vendor_event_alloc failed"));
2357 return;
2358 }
2359 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2360 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2361 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2362
2363 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2364 pData->requestId) ||
2365 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2366 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2367 goto nla_put_failure;
2368 }
2369
2370 cfg80211_vendor_event(skb, GFP_KERNEL);
2371 return;
2372
2373nla_put_failure:
2374 kfree_skb(skb);
2375 return;
2376}
2377
2378static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2379 void *pMsg)
2380{
2381 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2382 struct sk_buff *skb = NULL;
2383 tANI_U32 i = 0, j, resultsPerEvent;
2384 tANI_S32 totalResults;
2385 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2386 tpSirWifiScanResult pSirWifiScanResult;
2387
2388 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2389 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2390 "or pData(%p) is null"), pData);
2391 return;
2392 }
2393 totalResults = pData->numOfAps;
2394 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2395 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2396 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2397
2398 do{
2399 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2400 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2401 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2402
2403 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2404 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2405 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2406 GFP_KERNEL);
2407
2408 if (!skb) {
2409 hddLog(VOS_TRACE_LEVEL_ERROR,
2410 FL("cfg80211_vendor_event_alloc failed"));
2411 return;
2412 }
2413
2414 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2415
2416 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2417 pData->requestId) ||
2418 nla_put_u32(skb,
2419 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2420 resultsPerEvent)) {
2421 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2422 goto fail;
2423 }
2424 if (nla_put_u8(skb,
2425 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2426 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2427 {
2428 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2429 goto fail;
2430 }
2431
2432 if (resultsPerEvent) {
2433 struct nlattr *aps;
2434
2435 aps = nla_nest_start(skb,
2436 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2437 if (!aps)
2438 {
2439 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2440 goto fail;
2441 }
2442
2443 for (j = 0; j < resultsPerEvent; j++, i++) {
2444 struct nlattr *ap;
2445 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2446 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2447
2448 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2449 "Ssid (%s)"
2450 "Bssid: %pM "
2451 "Channel (%u)"
2452 "Rssi (%d)"
2453 "RTT (%u)"
2454 "RTT_SD (%u)",
2455 i,
2456 pSirWifiScanResult->ts,
2457 pSirWifiScanResult->ssid,
2458 pSirWifiScanResult->bssid,
2459 pSirWifiScanResult->channel,
2460 pSirWifiScanResult->rssi,
2461 pSirWifiScanResult->rtt,
2462 pSirWifiScanResult->rtt_sd);
2463
2464 ap = nla_nest_start(skb, j + 1);
2465 if (!ap)
2466 {
2467 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2468 goto fail;
2469 }
2470
2471 if (nla_put_u64(skb,
2472 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2473 pSirWifiScanResult->ts) )
2474 {
2475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2476 goto fail;
2477 }
2478 if (nla_put(skb,
2479 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2480 sizeof(pSirWifiScanResult->ssid),
2481 pSirWifiScanResult->ssid) )
2482 {
2483 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2484 goto fail;
2485 }
2486 if (nla_put(skb,
2487 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2488 sizeof(pSirWifiScanResult->bssid),
2489 pSirWifiScanResult->bssid) )
2490 {
2491 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2492 goto fail;
2493 }
2494 if (nla_put_u32(skb,
2495 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2496 pSirWifiScanResult->channel) )
2497 {
2498 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2499 goto fail;
2500 }
Dasari Srinivas90747d72014-10-08 12:16:15 +05302501 if (nla_put_s32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302502 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2503 pSirWifiScanResult->rssi) )
2504 {
2505 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2506 goto fail;
2507 }
2508 if (nla_put_u32(skb,
2509 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2510 pSirWifiScanResult->rtt) )
2511 {
2512 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2513 goto fail;
2514 }
2515 if (nla_put_u32(skb,
2516 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2517 pSirWifiScanResult->rtt_sd))
2518 {
2519 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2520 goto fail;
2521 }
2522
2523 nla_nest_end(skb, ap);
2524 }
2525 nla_nest_end(skb, aps);
2526
2527 }
2528 cfg80211_vendor_event(skb, GFP_KERNEL);
2529 } while (totalResults > 0);
2530
2531 return;
2532fail:
2533 kfree_skb(skb);
2534 return;
2535}
2536
2537static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2538 void *pMsg)
2539{
2540 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2541 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2542 struct sk_buff *skb = NULL;
2543 tANI_U32 i;
2544
2545 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2546 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2547 "or pData(%p) is null"), pData);
2548 return;
2549 }
2550
2551 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2552 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2553 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2554 GFP_KERNEL);
2555
2556 if (!skb) {
2557 hddLog(VOS_TRACE_LEVEL_ERROR,
2558 FL("cfg80211_vendor_event_alloc failed"));
2559 return;
2560 }
2561 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2562 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2563 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2564 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2565
2566 for (i = 0; i < pData->numOfAps; i++) {
2567 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2568 "Ssid (%s) "
2569 "Bssid (" MAC_ADDRESS_STR ") "
2570 "Channel (%u) "
2571 "Rssi (%d) "
2572 "RTT (%u) "
2573 "RTT_SD (%u) ",
2574 i,
2575 pData->ap[i].ts,
2576 pData->ap[i].ssid,
2577 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2578 pData->ap[i].channel,
2579 pData->ap[i].rssi,
2580 pData->ap[i].rtt,
2581 pData->ap[i].rtt_sd);
2582 }
2583
2584 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2585 pData->requestId) ||
2586 nla_put_u32(skb,
2587 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2588 pData->numOfAps)) {
2589 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2590 goto fail;
2591 }
2592 if (pData->numOfAps) {
2593 struct nlattr *aps;
2594
2595 aps = nla_nest_start(skb,
2596 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2597 if (!aps)
2598 goto fail;
2599
2600 for (i = 0; i < pData->numOfAps; i++) {
2601 struct nlattr *ap;
2602
2603 ap = nla_nest_start(skb, i + 1);
2604 if (!ap)
2605 goto fail;
2606
2607 if (nla_put_u64(skb,
2608 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2609 pData->ap[i].ts) ||
2610 nla_put(skb,
2611 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2612 sizeof(pData->ap[i].ssid),
2613 pData->ap[i].ssid) ||
2614 nla_put(skb,
2615 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2616 sizeof(pData->ap[i].bssid),
2617 pData->ap[i].bssid) ||
2618 nla_put_u32(skb,
2619 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2620 pData->ap[i].channel) ||
2621 nla_put_s32(skb,
2622 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2623 pData->ap[i].rssi) ||
2624 nla_put_u32(skb,
2625 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2626 pData->ap[i].rtt) ||
2627 nla_put_u32(skb,
2628 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2629 pData->ap[i].rtt_sd))
2630 goto fail;
2631
2632 nla_nest_end(skb, ap);
2633 }
2634 nla_nest_end(skb, aps);
2635
2636 if (nla_put_u8(skb,
2637 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2638 pData->moreData))
2639 goto fail;
2640 }
2641
2642 cfg80211_vendor_event(skb, GFP_KERNEL);
2643 return;
2644
2645fail:
2646 kfree_skb(skb);
2647 return;
2648
2649}
2650static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2651 void *pMsg)
2652{
2653 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2654 struct sk_buff *skb = NULL;
2655 tANI_U32 i, j;
2656 tpSirWifiSignificantChangeEvent pData =
2657 (tpSirWifiSignificantChangeEvent) pMsg;
2658
2659 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2660 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2661 "or pData(%p) is null"), pData);
2662 return;
2663 }
2664 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2665 EXTSCAN_EVENT_BUF_SIZE,
2666 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2667 GFP_KERNEL);
2668
2669 if (!skb) {
2670 hddLog(VOS_TRACE_LEVEL_ERROR,
2671 FL("cfg80211_vendor_event_alloc failed"));
2672 return;
2673 }
2674 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2675 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2676 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2677 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2678 pData->numSigRssiBss);
2679 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2680
2681 for (i = 0; i < pData->numSigRssiBss; i++) {
2682 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2683 " num RSSI %u ",
2684 i, pData->sigRssiResult[i].bssid,
2685 pData->sigRssiResult[i].channel,
2686 pData->sigRssiResult[i].numRssi);
2687
2688 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2689
2690 hddLog(VOS_TRACE_LEVEL_INFO,
2691 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05302692 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302693
2694 }
2695 }
2696
2697
2698 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2699 pData->requestId) ||
2700 nla_put_u32(skb,
2701 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2702 pData->numSigRssiBss)) {
2703 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2704 goto fail;
2705 }
2706
2707 if (pData->numSigRssiBss) {
2708 struct nlattr *aps;
2709 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2710 if (!aps)
2711 goto fail;
2712 for (i = 0; i < pData->numSigRssiBss; i++) {
2713 struct nlattr *ap;
2714
2715 ap = nla_nest_start(skb, i);
2716 if (!ap)
2717 goto fail;
2718 if (nla_put(skb,
2719 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2720 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2721 nla_put_u32(skb,
2722 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2723 pData->sigRssiResult[i].channel) ||
2724 nla_put_u32(skb,
2725 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2726 pData->sigRssiResult[i].numRssi) ||
2727 nla_put(skb,
2728 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2729 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2730 pData->sigRssiResult[i].rssi))
2731 goto fail;
2732 nla_nest_end(skb, ap);
2733 }
2734 nla_nest_end(skb, aps);
2735 if (nla_put_u8(skb,
2736 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2737 pData->moreData))
2738 goto fail;
2739 }
2740 cfg80211_vendor_event(skb, GFP_KERNEL);
2741 return;
2742fail:
2743 kfree_skb(skb);
2744 return;
2745}
2746
2747static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2748 void *pMsg)
2749{
2750 struct sk_buff *skb;
2751 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2752 tpSirWifiFullScanResultEvent pData =
2753 (tpSirWifiFullScanResultEvent) (pMsg);
2754
2755 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2757 "or pData(%p) is null"), pData);
2758 return;
2759 }
2760
2761 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2762 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2763 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2764 GFP_KERNEL);
2765
2766 if (!skb) {
2767 hddLog(VOS_TRACE_LEVEL_ERROR,
2768 FL("cfg80211_vendor_event_alloc failed"));
2769 return;
2770 }
2771
2772 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2773 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2774 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2775 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2776 "Ssid (%s)"
2777 "Bssid (" MAC_ADDRESS_STR ")"
2778 "Channel (%u)"
2779 "Rssi (%d)"
2780 "RTT (%u)"
2781 "RTT_SD (%u)"),
2782 pData->ap.ts,
2783 pData->ap.ssid,
2784 MAC_ADDR_ARRAY(pData->ap.bssid),
2785 pData->ap.channel,
2786 pData->ap.rssi,
2787 pData->ap.rtt,
2788 pData->ap.rtt_sd);
2789 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2790 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2791 pData->requestId) ||
2792 nla_put_u64(skb,
2793 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2794 pData->ap.ts) ||
2795 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2796 sizeof(pData->ap.ssid),
2797 pData->ap.ssid) ||
2798 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2799 WNI_CFG_BSSID_LEN,
2800 pData->ap.bssid) ||
2801 nla_put_u32(skb,
2802 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2803 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05302804 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302805 pData->ap.rssi) ||
2806 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2807 pData->ap.rtt) ||
2808 nla_put_u32(skb,
2809 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2810 pData->ap.rtt_sd) ||
2811 nla_put_u16(skb,
2812 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2813 pData->ap.beaconPeriod) ||
2814 nla_put_u16(skb,
2815 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2816 pData->ap.capability) ||
2817 nla_put_u32(skb,
2818 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2819 pData->ieLength))
2820 {
2821 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2822 goto nla_put_failure;
2823 }
2824 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2825 pData->ieLength,
2826 pData->ie))
2827 {
2828 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2829 goto nla_put_failure;
2830 }
2831
2832 cfg80211_vendor_event(skb, GFP_KERNEL);
2833 return;
2834
2835nla_put_failure:
2836 kfree_skb(skb);
2837 return;
2838}
2839
2840static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
2841 void *pMsg)
2842{
2843 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2844 struct sk_buff *skb = NULL;
2845 tpSirEXTScanResultsAvailableIndParams pData =
2846 (tpSirEXTScanResultsAvailableIndParams) pMsg;
2847
2848 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2849 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2850 "or pData(%p) is null"), pData);
2851 return;
2852 }
2853
2854 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2855 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2856 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
2857 GFP_KERNEL);
2858
2859 if (!skb) {
2860 hddLog(VOS_TRACE_LEVEL_ERROR,
2861 FL("cfg80211_vendor_event_alloc failed"));
2862 return;
2863 }
2864
2865 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2866 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2867 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
2868 pData->numResultsAvailable);
2869 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2870 pData->requestId) ||
2871 nla_put_u32(skb,
2872 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2873 pData->numResultsAvailable)) {
2874 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2875 goto nla_put_failure;
2876 }
2877
2878 cfg80211_vendor_event(skb, GFP_KERNEL);
2879 return;
2880
2881nla_put_failure:
2882 kfree_skb(skb);
2883 return;
2884}
2885
2886static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
2887{
2888 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2889 struct sk_buff *skb = NULL;
2890 tpSirEXTScanProgressIndParams pData =
2891 (tpSirEXTScanProgressIndParams) pMsg;
2892
2893 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2894 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2895 "or pData(%p) is null"), pData);
2896 return;
2897 }
2898
2899 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2900 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2901 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
2902 GFP_KERNEL);
2903
2904 if (!skb) {
2905 hddLog(VOS_TRACE_LEVEL_ERROR,
2906 FL("cfg80211_vendor_event_alloc failed"));
2907 return;
2908 }
2909 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2910 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
2911 pData->extScanEventType);
2912 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
2913 pData->status);
2914
2915 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
2916 pData->extScanEventType) ||
2917 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05302918 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2919 pData->requestId) ||
2920 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302921 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
2922 pData->status)) {
2923 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2924 goto nla_put_failure;
2925 }
2926
2927 cfg80211_vendor_event(skb, GFP_KERNEL);
2928 return;
2929
2930nla_put_failure:
2931 kfree_skb(skb);
2932 return;
2933}
2934
2935void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
2936 void *pMsg)
2937{
2938 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2939
2940 if (wlan_hdd_validate_context(pHddCtx)) {
Dasari Srinivasb46ed1d2014-10-08 13:03:08 +05302941 hddLog(VOS_TRACE_LEVEL_INFO, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302942 return;
2943 }
2944
2945 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
2946
2947
2948 switch(evType) {
2949 case SIR_HAL_EXTSCAN_START_RSP:
2950 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
2951 break;
2952
2953 case SIR_HAL_EXTSCAN_STOP_RSP:
2954 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
2955 break;
2956 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
2957 /* There is no need to send this response to upper layer
2958 Just log the message */
2959 hddLog(VOS_TRACE_LEVEL_INFO,
2960 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
2961 break;
2962 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
2963 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
2964 break;
2965
2966 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
2967 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
2968 break;
2969
2970 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
2971 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
2972 break;
2973
2974 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
2975 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
2976 break;
2977 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
2978 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
2979 break;
2980 case SIR_HAL_EXTSCAN_PROGRESS_IND:
2981 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
2982 break;
2983 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
2984 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
2985 break;
2986 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
2987 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
2988 break;
2989 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
2990 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
2991 break;
2992 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
2993 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
2994 break;
2995 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
2996 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
2997 break;
2998 default:
2999 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3000 break;
3001 }
3002}
3003
3004static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3005 struct wireless_dev *wdev,
3006 void *data, int dataLen)
3007{
Dino Myclee8843b32014-07-04 14:21:45 +05303008 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303009 struct net_device *dev = wdev->netdev;
3010 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3011 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3012 struct nlattr
3013 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3014 eHalStatus status;
3015
3016 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3017 status = wlan_hdd_validate_context(pHddCtx);
3018 if (0 != status)
3019 {
3020 hddLog(VOS_TRACE_LEVEL_ERROR,
3021 FL("HDD context is not valid"));
3022 return -EINVAL;
3023 }
Dino Myclee8843b32014-07-04 14:21:45 +05303024 /* check the EXTScan Capability */
3025 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3026 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3027 {
3028 hddLog(VOS_TRACE_LEVEL_ERROR,
3029 FL("EXTScan not enabled/supported by Firmware"));
3030 return -EINVAL;
3031 }
3032
Dino Mycle6fb96c12014-06-10 11:52:40 +05303033 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3034 data, dataLen,
3035 wlan_hdd_extscan_config_policy)) {
3036 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3037 return -EINVAL;
3038 }
3039
3040 /* Parse and fetch request Id */
3041 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3042 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3043 return -EINVAL;
3044 }
3045
Dino Mycle6fb96c12014-06-10 11:52:40 +05303046
Dino Myclee8843b32014-07-04 14:21:45 +05303047 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303048 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303049 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303050
Dino Myclee8843b32014-07-04 14:21:45 +05303051 reqMsg.sessionId = pAdapter->sessionId;
3052 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303053
Dino Myclee8843b32014-07-04 14:21:45 +05303054 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303055 if (!HAL_STATUS_SUCCESS(status)) {
3056 hddLog(VOS_TRACE_LEVEL_ERROR,
3057 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303058 return -EINVAL;
3059 }
3060
3061 return 0;
3062}
3063
3064
3065static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3066 struct wireless_dev *wdev,
3067 void *data, int dataLen)
3068{
Dino Myclee8843b32014-07-04 14:21:45 +05303069 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303070 struct net_device *dev = wdev->netdev;
3071 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3072 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3073 struct nlattr
3074 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3075 eHalStatus status;
3076
3077 status = wlan_hdd_validate_context(pHddCtx);
3078 if (0 != status)
3079 {
3080 hddLog(VOS_TRACE_LEVEL_ERROR,
3081 FL("HDD context is not valid"));
3082 return -EINVAL;
3083 }
Dino Myclee8843b32014-07-04 14:21:45 +05303084 /* check the EXTScan Capability */
3085 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3086 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3087 {
3088 hddLog(VOS_TRACE_LEVEL_ERROR,
3089 FL("EXTScan not enabled/supported by Firmware"));
3090 return -EINVAL;
3091 }
3092
Dino Mycle6fb96c12014-06-10 11:52:40 +05303093 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3094 data, dataLen,
3095 wlan_hdd_extscan_config_policy)) {
3096 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3097 return -EINVAL;
3098 }
3099 /* Parse and fetch request Id */
3100 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3102 return -EINVAL;
3103 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303104
Dino Myclee8843b32014-07-04 14:21:45 +05303105 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303106 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3107
Dino Myclee8843b32014-07-04 14:21:45 +05303108 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303109
Dino Myclee8843b32014-07-04 14:21:45 +05303110 reqMsg.sessionId = pAdapter->sessionId;
3111 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303112
3113 /* Parse and fetch flush parameter */
3114 if (!tb
3115 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3116 {
3117 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3118 goto failed;
3119 }
Dino Myclee8843b32014-07-04 14:21:45 +05303120 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303121 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3122
Dino Myclee8843b32014-07-04 14:21:45 +05303123 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303124
Dino Myclee8843b32014-07-04 14:21:45 +05303125 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303126 if (!HAL_STATUS_SUCCESS(status)) {
3127 hddLog(VOS_TRACE_LEVEL_ERROR,
3128 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303129 return -EINVAL;
3130 }
3131 return 0;
3132
3133failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303134 return -EINVAL;
3135}
3136
3137static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3138 struct wireless_dev *wdev,
3139 void *data, int dataLen)
3140{
3141 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3142 struct net_device *dev = wdev->netdev;
3143 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3144 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3145 struct nlattr
3146 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3147 struct nlattr
3148 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3149 struct nlattr *apTh;
3150 eHalStatus status;
3151 tANI_U8 i = 0;
3152 int rem;
3153
3154 status = wlan_hdd_validate_context(pHddCtx);
3155 if (0 != status)
3156 {
3157 hddLog(VOS_TRACE_LEVEL_ERROR,
3158 FL("HDD context is not valid"));
3159 return -EINVAL;
3160 }
Dino Myclee8843b32014-07-04 14:21:45 +05303161 /* check the EXTScan Capability */
3162 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3163 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3164 {
3165 hddLog(VOS_TRACE_LEVEL_ERROR,
3166 FL("EXTScan not enabled/supported by Firmware"));
3167 return -EINVAL;
3168 }
3169
Dino Mycle6fb96c12014-06-10 11:52:40 +05303170 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3171 data, dataLen,
3172 wlan_hdd_extscan_config_policy)) {
3173 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3174 return -EINVAL;
3175 }
3176
3177 /* Parse and fetch request Id */
3178 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3179 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3180 return -EINVAL;
3181 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303182 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3183 vos_mem_malloc(sizeof(*pReqMsg));
3184 if (!pReqMsg) {
3185 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3186 return -ENOMEM;
3187 }
3188
Dino Myclee8843b32014-07-04 14:21:45 +05303189
Dino Mycle6fb96c12014-06-10 11:52:40 +05303190 pReqMsg->requestId = nla_get_u32(
3191 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3192 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3193
3194 /* Parse and fetch number of APs */
3195 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3196 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3197 goto fail;
3198 }
3199
3200 pReqMsg->sessionId = pAdapter->sessionId;
3201 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3202
3203 pReqMsg->numAp = nla_get_u32(
3204 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3205 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3206
3207 nla_for_each_nested(apTh,
3208 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3209 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3210 nla_data(apTh), nla_len(apTh),
3211 NULL)) {
3212 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3213 goto fail;
3214 }
3215
3216 /* Parse and fetch MAC address */
3217 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3218 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3219 goto fail;
3220 }
3221 memcpy(pReqMsg->ap[i].bssid, nla_data(
3222 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3223 sizeof(tSirMacAddr));
3224 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3225
3226 /* Parse and fetch low RSSI */
3227 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3228 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3229 goto fail;
3230 }
3231 pReqMsg->ap[i].low = nla_get_s32(
3232 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3233 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3234
3235 /* Parse and fetch high RSSI */
3236 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3237 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3238 goto fail;
3239 }
3240 pReqMsg->ap[i].high = nla_get_s32(
3241 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3242 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3243 pReqMsg->ap[i].high);
3244
3245 /* Parse and fetch channel */
3246 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3247 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3248 goto fail;
3249 }
3250 pReqMsg->ap[i].channel = nla_get_u32(
3251 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3252 hddLog(VOS_TRACE_LEVEL_INFO,
3253 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3254 i++;
3255 }
3256 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3257 if (!HAL_STATUS_SUCCESS(status)) {
3258 hddLog(VOS_TRACE_LEVEL_ERROR,
3259 FL("sme_SetBssHotlist failed(err=%d)"), status);
3260 vos_mem_free(pReqMsg);
3261 return -EINVAL;
3262 }
3263
Dino Myclee8843b32014-07-04 14:21:45 +05303264 vos_mem_free(pReqMsg);
3265
Dino Mycle6fb96c12014-06-10 11:52:40 +05303266 return 0;
3267
3268fail:
3269 vos_mem_free(pReqMsg);
3270 return -EINVAL;
3271}
3272
3273static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3274 struct wireless_dev *wdev,
3275 void *data, int dataLen)
3276{
3277 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3278 struct net_device *dev = wdev->netdev;
3279 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3280 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3281 struct nlattr
3282 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3283 struct nlattr
3284 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3285 struct nlattr *apTh;
3286 eHalStatus status;
3287 int i = 0;
3288 int rem;
3289
3290 status = wlan_hdd_validate_context(pHddCtx);
3291 if (0 != status)
3292 {
3293 hddLog(VOS_TRACE_LEVEL_ERROR,
3294 FL("HDD context is not valid"));
3295 return -EINVAL;
3296 }
Dino Myclee8843b32014-07-04 14:21:45 +05303297 /* check the EXTScan Capability */
3298 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3299 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3300 {
3301 hddLog(VOS_TRACE_LEVEL_ERROR,
3302 FL("EXTScan not enabled/supported by Firmware"));
3303 return -EINVAL;
3304 }
3305
Dino Mycle6fb96c12014-06-10 11:52:40 +05303306 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3307 data, dataLen,
3308 wlan_hdd_extscan_config_policy)) {
3309 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3310 return -EINVAL;
3311 }
3312
3313 /* Parse and fetch request Id */
3314 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3315 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3316 return -EINVAL;
3317 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303318 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303319 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303320 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303321 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3322 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303323 }
3324
Dino Myclee8843b32014-07-04 14:21:45 +05303325
3326
Dino Mycle6fb96c12014-06-10 11:52:40 +05303327 pReqMsg->requestId = nla_get_u32(
3328 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3329 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3330
3331 /* Parse and fetch RSSI sample size */
3332 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3333 {
3334 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3335 goto fail;
3336 }
3337 pReqMsg->rssiSampleSize = nla_get_u32(
3338 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3339 hddLog(VOS_TRACE_LEVEL_INFO,
3340 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3341
3342 /* Parse and fetch lost AP sample size */
3343 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3344 {
3345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3346 goto fail;
3347 }
3348 pReqMsg->lostApSampleSize = nla_get_u32(
3349 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3350 hddLog(VOS_TRACE_LEVEL_INFO,
3351 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3352 /* Parse and fetch minimum Breaching */
3353 if (!tb
3354 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3355 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3356 goto fail;
3357 }
3358 pReqMsg->minBreaching = nla_get_u32(
3359 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3360 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3361
3362 /* Parse and fetch number of APs */
3363 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3364 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3365 goto fail;
3366 }
3367 pReqMsg->numAp = nla_get_u32(
3368 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3369 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3370
3371 pReqMsg->sessionId = pAdapter->sessionId;
3372 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3373
3374 nla_for_each_nested(apTh,
3375 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3376 if(nla_parse(tb2,
3377 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3378 nla_data(apTh), nla_len(apTh),
3379 NULL)) {
3380 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3381 goto fail;
3382 }
3383
3384 /* Parse and fetch MAC address */
3385 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3386 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3387 goto fail;
3388 }
3389 memcpy(pReqMsg->ap[i].bssid, nla_data(
3390 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3391 sizeof(tSirMacAddr));
3392
3393 /* Parse and fetch low RSSI */
3394 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3396 goto fail;
3397 }
3398 pReqMsg->ap[i].low = nla_get_s32(
3399 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3400 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3401
3402 /* Parse and fetch high RSSI */
3403 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3404 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3405 goto fail;
3406 }
3407 pReqMsg->ap[i].high = nla_get_s32(
3408 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3409 hddLog(VOS_TRACE_LEVEL_INFO,
3410 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3411
3412 /* Parse and fetch channel */
3413 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3414 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3415 goto fail;
3416 }
3417 pReqMsg->ap[i].channel = nla_get_u32(
3418 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3419 hddLog(VOS_TRACE_LEVEL_INFO,
3420 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3421 i++;
3422 }
3423
3424 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3425 if (!HAL_STATUS_SUCCESS(status)) {
3426 hddLog(VOS_TRACE_LEVEL_ERROR,
3427 FL("sme_SetSignificantChange failed(err=%d)"), status);
3428 vos_mem_free(pReqMsg);
3429 return -EINVAL;
3430 }
Dino Myclee8843b32014-07-04 14:21:45 +05303431 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303432 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3433 return 0;
3434
3435fail:
3436 vos_mem_free(pReqMsg);
3437 return -EINVAL;
3438}
3439
3440static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3441 struct wireless_dev *wdev,
3442 void *data, int dataLen)
3443{
3444 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3445 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3446 tANI_U8 numChannels = 0;
3447 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3448 tANI_U32 requestId;
3449 tWifiBand wifiBand;
3450 eHalStatus status;
3451 struct sk_buff *replySkb;
3452 tANI_U8 i;
3453
3454 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3455 status = wlan_hdd_validate_context(pHddCtx);
3456 if (0 != status)
3457 {
3458 hddLog(VOS_TRACE_LEVEL_ERROR,
3459 FL("HDD context is not valid"));
3460 return -EINVAL;
3461 }
Dino Myclee8843b32014-07-04 14:21:45 +05303462 /* check the EXTScan Capability */
3463 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3464 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3465 {
3466 hddLog(VOS_TRACE_LEVEL_ERROR,
3467 FL("EXTScan not enabled/supported by Firmware"));
3468 return -EINVAL;
3469 }
3470
Dino Mycle6fb96c12014-06-10 11:52:40 +05303471 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3472 data, dataLen,
3473 wlan_hdd_extscan_config_policy)) {
3474 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3475 return -EINVAL;
3476 }
3477
3478 /* Parse and fetch request Id */
3479 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3480 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3481 return -EINVAL;
3482 }
3483 requestId = nla_get_u32(
3484 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3485 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3486
3487 /* Parse and fetch wifi band */
3488 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3489 {
3490 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3491 return -EINVAL;
3492 }
3493 wifiBand = nla_get_u32(
3494 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3495 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3496
3497 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3498 wifiBand, ChannelList,
3499 &numChannels);
3500 if (eHAL_STATUS_SUCCESS != status) {
3501 hddLog(VOS_TRACE_LEVEL_ERROR,
3502 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3503 return -EINVAL;
3504 }
3505 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3506 for (i = 0; i < numChannels; i++)
3507 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3508
3509 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3510 sizeof(u32) * numChannels +
3511 NLMSG_HDRLEN);
3512
3513 if (!replySkb) {
3514 hddLog(VOS_TRACE_LEVEL_ERROR,
3515 FL("valid channels: buffer alloc fail"));
3516 return -EINVAL;
3517 }
3518 if (nla_put_u32(replySkb,
3519 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3520 numChannels) ||
3521 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3522 sizeof(u32) * numChannels, ChannelList)) {
3523
3524 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3525 kfree_skb(replySkb);
3526 return -EINVAL;
3527 }
3528
3529 return cfg80211_vendor_cmd_reply(replySkb);
3530}
3531
3532static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3533 struct wireless_dev *wdev,
3534 void *data, int dataLen)
3535{
Dino Myclee8843b32014-07-04 14:21:45 +05303536 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303537 struct net_device *dev = wdev->netdev;
3538 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3539 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3540 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3541 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3542 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3543 struct nlattr *buckets;
3544 struct nlattr *channels;
3545 int rem1;
3546 int rem2;
3547 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303548 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303549
3550 status = wlan_hdd_validate_context(pHddCtx);
3551 if (0 != status)
3552 {
3553 hddLog(VOS_TRACE_LEVEL_ERROR,
3554 FL("HDD context is not valid"));
3555 return -EINVAL;
3556 }
Dino Myclee8843b32014-07-04 14:21:45 +05303557 /* check the EXTScan Capability */
3558 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3559 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3560 {
3561 hddLog(VOS_TRACE_LEVEL_ERROR,
3562 FL("EXTScan not enabled/supported by Firmware"));
3563 return -EINVAL;
3564 }
3565
Dino Mycle6fb96c12014-06-10 11:52:40 +05303566 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3567 data, dataLen,
3568 wlan_hdd_extscan_config_policy)) {
3569 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3570 return -EINVAL;
3571 }
3572
3573 /* Parse and fetch request Id */
3574 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3575 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3576 return -EINVAL;
3577 }
3578
Dino Myclee8843b32014-07-04 14:21:45 +05303579 pReqMsg = (tpSirEXTScanStartReqParams)
3580 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303581 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303582 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3583 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303584 }
3585
3586 pReqMsg->requestId = nla_get_u32(
3587 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3588 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3589
3590 pReqMsg->sessionId = pAdapter->sessionId;
3591 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3592
3593 /* Parse and fetch base period */
3594 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3595 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3596 goto fail;
3597 }
3598 pReqMsg->basePeriod = nla_get_u32(
3599 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3600 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3601 pReqMsg->basePeriod);
3602
3603 /* Parse and fetch max AP per scan */
3604 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3605 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3606 goto fail;
3607 }
3608 pReqMsg->maxAPperScan = nla_get_u32(
3609 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3610 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3611 pReqMsg->maxAPperScan);
3612
3613 /* Parse and fetch report threshold */
3614 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3615 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3616 goto fail;
3617 }
3618 pReqMsg->reportThreshold = nla_get_u8(
3619 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3620 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3621 pReqMsg->reportThreshold);
3622
3623 /* Parse and fetch number of buckets */
3624 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3625 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3626 goto fail;
3627 }
3628 pReqMsg->numBuckets = nla_get_u8(
3629 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3630 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3631 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3632 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3633 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3634 }
3635 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3636 pReqMsg->numBuckets);
3637 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3638 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3639 goto fail;
3640 }
3641
3642 nla_for_each_nested(buckets,
3643 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3644 if(nla_parse(bucket,
3645 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3646 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3647 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3648 goto fail;
3649 }
3650
3651 /* Parse and fetch bucket spec */
3652 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3654 goto fail;
3655 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303656
3657 pReqMsg->buckets[index].bucket = nla_get_u8(
3658 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3659
3660 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
3661 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303662
3663 /* Parse and fetch wifi band */
3664 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3665 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3666 goto fail;
3667 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303668 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303669 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3670 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303671 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303672
3673 /* Parse and fetch period */
3674 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3675 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3676 goto fail;
3677 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303678 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303679 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3680 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303681 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303682
3683 /* Parse and fetch report events */
3684 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3686 goto fail;
3687 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303688 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303689 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3690 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303691 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303692
3693 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303694 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
3695 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303696 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3697 goto fail;
3698 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303699 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303700 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3701 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303702 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303703
3704 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3705 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3706 goto fail;
3707 }
3708
3709 j = 0;
3710 nla_for_each_nested(channels,
3711 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3712 if(nla_parse(channel,
3713 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3714 nla_data(channels), nla_len(channels),
3715 NULL)) { //wlan_hdd_extscan_config_policy here
3716 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3717 goto fail;
3718 }
3719
3720 /* Parse and fetch channel */
3721 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3722 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3723 goto fail;
3724 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303725 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303726 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3727 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303728 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303729
3730 /* Parse and fetch dwell time */
3731 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3732 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3733 goto fail;
3734 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303735 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303736 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3737 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303738 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303739
3740 /* Parse and fetch channel spec passive */
3741 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3742 hddLog(VOS_TRACE_LEVEL_ERROR,
3743 FL("attr channel spec passive failed"));
3744 goto fail;
3745 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303746 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303747 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3748 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303749 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303750 j++;
3751 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303752 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303753 }
3754 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3755 if (!HAL_STATUS_SUCCESS(status)) {
3756 hddLog(VOS_TRACE_LEVEL_ERROR,
3757 FL("sme_EXTScanStart failed(err=%d)"), status);
3758 vos_mem_free(pReqMsg);
3759 return -EINVAL;
3760 }
3761
Dino Myclee8843b32014-07-04 14:21:45 +05303762 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303763 return 0;
3764
3765fail:
3766 vos_mem_free(pReqMsg);
3767 return -EINVAL;
3768}
3769
3770static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
3771 struct wireless_dev *wdev,
3772 void *data, int dataLen)
3773{
Dino Myclee8843b32014-07-04 14:21:45 +05303774 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303775 struct net_device *dev = wdev->netdev;
3776 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3777 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3778 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3779 eHalStatus status;
3780
3781 status = wlan_hdd_validate_context(pHddCtx);
3782 if (0 != status)
3783 {
3784 hddLog(VOS_TRACE_LEVEL_ERROR,
3785 FL("HDD context is not valid"));
3786 return -EINVAL;
3787 }
Dino Myclee8843b32014-07-04 14:21:45 +05303788 /* check the EXTScan Capability */
3789 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3790 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3791 {
3792 hddLog(VOS_TRACE_LEVEL_ERROR,
3793 FL("EXTScan not enabled/supported by Firmware"));
3794 return -EINVAL;
3795 }
3796
Dino Mycle6fb96c12014-06-10 11:52:40 +05303797 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3798 data, dataLen,
3799 wlan_hdd_extscan_config_policy)) {
3800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3801 return -EINVAL;
3802 }
3803
3804 /* Parse and fetch request Id */
3805 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3806 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3807 return -EINVAL;
3808 }
3809
Dino Myclee8843b32014-07-04 14:21:45 +05303810 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303811 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303812 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303813
Dino Myclee8843b32014-07-04 14:21:45 +05303814 reqMsg.sessionId = pAdapter->sessionId;
3815 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303816
Dino Myclee8843b32014-07-04 14:21:45 +05303817 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303818 if (!HAL_STATUS_SUCCESS(status)) {
3819 hddLog(VOS_TRACE_LEVEL_ERROR,
3820 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303821 return -EINVAL;
3822 }
3823
3824 return 0;
3825}
3826
3827static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
3828 struct wireless_dev *wdev,
3829 void *data, int dataLen)
3830{
Dino Myclee8843b32014-07-04 14:21:45 +05303831 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303832 struct net_device *dev = wdev->netdev;
3833 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3834 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3835 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3836 eHalStatus status;
3837
3838 status = wlan_hdd_validate_context(pHddCtx);
3839 if (0 != status)
3840 {
3841 hddLog(VOS_TRACE_LEVEL_ERROR,
3842 FL("HDD context is not valid"));
3843 return -EINVAL;
3844 }
Dino Myclee8843b32014-07-04 14:21:45 +05303845 /* check the EXTScan Capability */
3846 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3847 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3848 {
3849 hddLog(VOS_TRACE_LEVEL_ERROR,
3850 FL("EXTScan not enabled/supported by Firmware"));
3851 return -EINVAL;
3852 }
3853
Dino Mycle6fb96c12014-06-10 11:52:40 +05303854 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3855 data, dataLen,
3856 wlan_hdd_extscan_config_policy)) {
3857 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3858 return -EINVAL;
3859 }
3860
3861 /* Parse and fetch request Id */
3862 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3863 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3864 return -EINVAL;
3865 }
3866
Dino Myclee8843b32014-07-04 14:21:45 +05303867 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303868 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303869 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303870
Dino Myclee8843b32014-07-04 14:21:45 +05303871 reqMsg.sessionId = pAdapter->sessionId;
3872 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303873
Dino Myclee8843b32014-07-04 14:21:45 +05303874 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303875 if (!HAL_STATUS_SUCCESS(status)) {
3876 hddLog(VOS_TRACE_LEVEL_ERROR,
3877 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303878 return -EINVAL;
3879 }
3880
3881 return 0;
3882}
3883
3884static int wlan_hdd_cfg80211_extscan_reset_significant_change(
3885 struct wiphy *wiphy,
3886 struct wireless_dev *wdev,
3887 void *data, int dataLen)
3888{
Dino Myclee8843b32014-07-04 14:21:45 +05303889 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303890 struct net_device *dev = wdev->netdev;
3891 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3892 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3893 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3894 eHalStatus status;
3895
3896 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
3897 status = wlan_hdd_validate_context(pHddCtx);
3898 if (0 != status)
3899 {
3900 hddLog(VOS_TRACE_LEVEL_ERROR,
3901 FL("HDD context is not valid"));
3902 return -EINVAL;
3903 }
Dino Myclee8843b32014-07-04 14:21:45 +05303904 /* check the EXTScan Capability */
3905 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3906 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3907 {
3908 hddLog(VOS_TRACE_LEVEL_ERROR,
3909 FL("EXTScan not enabled/supported by Firmware"));
3910 return -EINVAL;
3911 }
3912
Dino Mycle6fb96c12014-06-10 11:52:40 +05303913 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3914 data, dataLen,
3915 wlan_hdd_extscan_config_policy)) {
3916 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3917 return -EINVAL;
3918 }
3919
3920 /* Parse and fetch request Id */
3921 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3922 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3923 return -EINVAL;
3924 }
3925
Dino Mycle6fb96c12014-06-10 11:52:40 +05303926
Dino Myclee8843b32014-07-04 14:21:45 +05303927 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303928 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303929 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303930
Dino Myclee8843b32014-07-04 14:21:45 +05303931 reqMsg.sessionId = pAdapter->sessionId;
3932 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303933
Dino Myclee8843b32014-07-04 14:21:45 +05303934 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303935 if (!HAL_STATUS_SUCCESS(status)) {
3936 hddLog(VOS_TRACE_LEVEL_ERROR,
3937 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303938 return -EINVAL;
3939 }
3940
3941 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3942 return 0;
3943}
3944
3945#endif /* WLAN_FEATURE_EXTSCAN */
3946
Atul Mittal115287b2014-07-08 13:26:33 +05303947/*EXT TDLS*/
3948static const struct nla_policy
3949wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
3950{
3951 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
3952 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
3953 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
3954 {.type = NLA_S32 },
3955 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
3956 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
3957
3958};
3959
3960static const struct nla_policy
3961wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
3962{
3963 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
3964
3965};
3966
3967static const struct nla_policy
3968wlan_hdd_tdls_config_state_change_policy[
3969 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
3970{
3971 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
3972 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
3973 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05303974 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
3975 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
3976 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05303977
3978};
3979
3980static const struct nla_policy
3981wlan_hdd_tdls_config_get_status_policy[
3982 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
3983{
3984 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
3985 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
3986 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05303987 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
3988 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
3989 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05303990
3991};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05303992
3993static const struct nla_policy
3994wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
3995{
3996 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
3997};
3998
3999static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
4000 struct wireless_dev *wdev,
4001 void *data,
4002 int data_len)
4003{
4004
4005 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4006 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4007
4008 if (0 != wlan_hdd_validate_context(pHddCtx)){
4009 hddLog(VOS_TRACE_LEVEL_ERROR, FL("hdd Ctx invalid while spoof macAddr"));
4010 return -EINVAL;
4011 }
4012 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
4013 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN disabled in ini"));
4014 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304015 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304016 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
4017 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN not supported by FW"));
4018 return -ENOTSUPP;
4019 }
4020
4021 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4022 data, data_len, wlan_hdd_mac_config)) {
4023 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4024 return -EINVAL;
4025 }
4026
4027 /* Parse and fetch mac address */
4028 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4029 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4030 return -EINVAL;
4031 }
4032
4033 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4034 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4035 VOS_MAC_ADDR_LAST_3_BYTES);
4036
Siddharth Bhal76972212014-10-15 16:22:51 +05304037 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4038
4039 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304040 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4041 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304042 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4043 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4044 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4045 {
4046 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4047 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4048 VOS_MAC_ADDRESS_LEN);
4049 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304050 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304051
Siddharth Bhal76972212014-10-15 16:22:51 +05304052 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
4053 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304054 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4055 }
4056
4057 return 0;
4058}
4059
Atul Mittal115287b2014-07-08 13:26:33 +05304060static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4061 struct wireless_dev *wdev,
4062 void *data,
4063 int data_len)
4064{
4065 u8 peer[6] = {0};
4066 struct net_device *dev = wdev->netdev;
4067 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4068 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4069 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4070 eHalStatus ret;
4071 tANI_S32 state;
4072 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304073 tANI_S32 global_operating_class = 0;
4074 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304075 struct sk_buff *skb = NULL;
4076
4077 ret = wlan_hdd_validate_context(pHddCtx);
4078 if (0 != ret) {
4079
4080 return -EINVAL;
4081 }
4082 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4083
4084 return -ENOTSUPP;
4085 }
4086 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4087 data, data_len,
4088 wlan_hdd_tdls_config_get_status_policy)) {
4089 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4090 return -EINVAL;
4091 }
4092
4093 /* Parse and fetch mac address */
4094 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4095 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4096 return -EINVAL;
4097 }
4098
4099 memcpy(peer, nla_data(
4100 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4101 sizeof(peer));
4102 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4103
4104 ret = wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
4105
4106 if (0 != ret) {
4107 hddLog(VOS_TRACE_LEVEL_ERROR,
4108 FL("get status Failed"));
4109 return -EINVAL;
4110 }
4111 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304112 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304113 NLMSG_HDRLEN);
4114
4115 if (!skb) {
4116 hddLog(VOS_TRACE_LEVEL_ERROR,
4117 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4118 return -EINVAL;
4119 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304120 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 +05304121 reason,
4122 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304123 global_operating_class,
4124 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304125 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304126 if (nla_put_s32(skb,
4127 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4128 state) ||
4129 nla_put_s32(skb,
4130 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4131 reason) ||
4132 nla_put_s32(skb,
4133 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4134 global_operating_class) ||
4135 nla_put_s32(skb,
4136 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4137 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304138
4139 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4140 goto nla_put_failure;
4141 }
4142
4143 return cfg80211_vendor_cmd_reply(skb);
4144
4145nla_put_failure:
4146 kfree_skb(skb);
4147 return -EINVAL;
4148}
4149
4150static int wlan_hdd_cfg80211_exttdls_callback(tANI_U8* mac,
4151 tANI_S32 state,
4152 tANI_S32 reason,
4153 void *ctx)
4154{
4155 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
4156 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4157 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304158 tANI_S32 global_operating_class = 0;
4159 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304160
4161 if (wlan_hdd_validate_context(pHddCtx)) {
4162 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "));
4163 return -EINVAL;
4164 }
4165
4166 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4167
4168 return -ENOTSUPP;
4169 }
4170 skb = cfg80211_vendor_event_alloc(
4171 pHddCtx->wiphy,
4172 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4173 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4174 GFP_KERNEL);
4175
4176 if (!skb) {
4177 hddLog(VOS_TRACE_LEVEL_ERROR,
4178 FL("cfg80211_vendor_event_alloc failed"));
4179 return -EINVAL;
4180 }
4181 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304182 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4183 reason,
4184 state,
4185 global_operating_class,
4186 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304187 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4188 MAC_ADDR_ARRAY(mac));
4189
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304190 if (nla_put(skb,
4191 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4192 VOS_MAC_ADDR_SIZE, mac) ||
4193 nla_put_s32(skb,
4194 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4195 state) ||
4196 nla_put_s32(skb,
4197 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4198 reason) ||
4199 nla_put_s32(skb,
4200 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4201 channel) ||
4202 nla_put_s32(skb,
4203 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4204 global_operating_class)
4205 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304206 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4207 goto nla_put_failure;
4208 }
4209
4210 cfg80211_vendor_event(skb, GFP_KERNEL);
4211 return (0);
4212
4213nla_put_failure:
4214 kfree_skb(skb);
4215 return -EINVAL;
4216}
4217
4218static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4219 struct wireless_dev *wdev,
4220 void *data,
4221 int data_len)
4222{
4223 u8 peer[6] = {0};
4224 struct net_device *dev = wdev->netdev;
4225 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4226 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4227 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4228 eHalStatus status;
4229 tdls_req_params_t pReqMsg = {0};
4230
4231 status = wlan_hdd_validate_context(pHddCtx);
4232 if (0 != status) {
4233 hddLog(VOS_TRACE_LEVEL_ERROR,
4234 FL("HDD context is not valid"));
4235 return -EINVAL;
4236 }
4237 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4238
4239 return -ENOTSUPP;
4240 }
4241 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4242 data, data_len,
4243 wlan_hdd_tdls_config_enable_policy)) {
4244 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4245 return -EINVAL;
4246 }
4247
4248 /* Parse and fetch mac address */
4249 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4250 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4251 return -EINVAL;
4252 }
4253
4254 memcpy(peer, nla_data(
4255 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4256 sizeof(peer));
4257 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4258
4259 /* Parse and fetch channel */
4260 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4262 return -EINVAL;
4263 }
4264 pReqMsg.channel = nla_get_s32(
4265 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4266 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4267
4268 /* Parse and fetch global operating class */
4269 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4271 return -EINVAL;
4272 }
4273 pReqMsg.global_operating_class = nla_get_s32(
4274 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4275 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4276 pReqMsg.global_operating_class);
4277
4278 /* Parse and fetch latency ms */
4279 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4280 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4281 return -EINVAL;
4282 }
4283 pReqMsg.max_latency_ms = nla_get_s32(
4284 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4285 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4286 pReqMsg.max_latency_ms);
4287
4288 /* Parse and fetch required bandwidth kbps */
4289 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4290 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4291 return -EINVAL;
4292 }
4293
4294 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4295 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4296 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4297 pReqMsg.min_bandwidth_kbps);
4298
4299 return (wlan_hdd_tdls_extctrl_config_peer(pAdapter,
4300 peer,
4301 wlan_hdd_cfg80211_exttdls_callback));
4302}
4303
4304static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4305 struct wireless_dev *wdev,
4306 void *data,
4307 int data_len)
4308{
4309 u8 peer[6] = {0};
4310 struct net_device *dev = wdev->netdev;
4311 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4312 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4313 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4314 eHalStatus status;
4315
4316 status = wlan_hdd_validate_context(pHddCtx);
4317 if (0 != status) {
4318 hddLog(VOS_TRACE_LEVEL_ERROR,
4319 FL("HDD context is not valid"));
4320 return -EINVAL;
4321 }
4322 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4323
4324 return -ENOTSUPP;
4325 }
4326 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4327 data, data_len,
4328 wlan_hdd_tdls_config_disable_policy)) {
4329 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4330 return -EINVAL;
4331 }
4332 /* Parse and fetch mac address */
4333 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4334 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4335 return -EINVAL;
4336 }
4337
4338 memcpy(peer, nla_data(
4339 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4340 sizeof(peer));
4341 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4342
4343 return (wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer));
4344}
4345
Dasari Srinivas7875a302014-09-26 17:50:57 +05304346static int
4347wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
4348 struct wireless_dev *wdev,
4349 void *data, int data_len)
4350{
4351 struct net_device *dev = wdev->netdev;
4352 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4353 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4354 struct sk_buff *skb = NULL;
4355 tANI_U32 fset = 0;
4356
4357 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
4358 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
4359 fset |= WIFI_FEATURE_INFRA;
4360 }
4361
4362 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
4363 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
4364 fset |= WIFI_FEATURE_INFRA_5G;
4365 }
4366
4367#ifdef WLAN_FEATURE_P2P
4368 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
4369 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
4370 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
4371 fset |= WIFI_FEATURE_P2P;
4372 }
4373#endif
4374
4375 /* Soft-AP is supported currently by default */
4376 fset |= WIFI_FEATURE_SOFT_AP;
4377
4378#ifdef WLAN_FEATURE_EXTSCAN
4379 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
4380 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
4381 hddLog(LOG1, FL("EXTScan is supported by firmware"));
4382 fset |= WIFI_FEATURE_EXTSCAN;
4383 }
4384#endif
4385
4386#ifdef WLAN_FEATURE_NAN
4387 if (sme_IsFeatureSupportedByFW(NAN)) {
4388 hddLog(LOG1, FL("NAN is supported by firmware"));
4389 fset |= WIFI_FEATURE_NAN;
4390 }
4391#endif
4392
4393 /* D2D RTT is not supported currently by default */
4394 if (sme_IsFeatureSupportedByFW(RTT)) {
4395 hddLog(LOG1, FL("RTT is supported by firmware"));
4396 fset |= WIFI_FEATURE_D2AP_RTT;
4397 }
4398
4399#ifdef FEATURE_WLAN_BATCH_SCAN
4400 if (fset & WIFI_FEATURE_EXTSCAN) {
4401 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
4402 fset &= ~WIFI_FEATURE_BATCH_SCAN;
4403 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
4404 hddLog(LOG1, FL("Batch scan is supported by firmware"));
4405 fset |= WIFI_FEATURE_BATCH_SCAN;
4406 }
4407#endif
4408
4409#ifdef FEATURE_WLAN_SCAN_PNO
4410 if (pHddCtx->cfg_ini->configPNOScanSupport &&
4411 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
4412 hddLog(LOG1, FL("PNO is supported by firmware"));
4413 fset |= WIFI_FEATURE_PNO;
4414 }
4415#endif
4416
4417 /* STA+STA is supported currently by default */
4418 fset |= WIFI_FEATURE_ADDITIONAL_STA;
4419
4420#ifdef FEATURE_WLAN_TDLS
4421 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
4422 sme_IsFeatureSupportedByFW(TDLS)) {
4423 hddLog(LOG1, FL("TDLS is supported by firmware"));
4424 fset |= WIFI_FEATURE_TDLS;
4425 }
4426
4427 /* TDLS_OFFCHANNEL is not supported currently by default */
4428#endif
4429
4430#ifdef WLAN_AP_STA_CONCURRENCY
4431 /* AP+STA concurrency is supported currently by default */
4432 fset |= WIFI_FEATURE_AP_STA;
4433#endif
4434
4435 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
4436 NLMSG_HDRLEN);
4437
4438 if (!skb) {
4439 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4440 return -EINVAL;
4441 }
4442 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
4443
4444 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
4445 hddLog(LOGE, FL("nla put fail"));
4446 goto nla_put_failure;
4447 }
4448
4449 return cfg80211_vendor_cmd_reply(skb);
4450
4451nla_put_failure:
4452 kfree_skb(skb);
4453 return -EINVAL;
4454}
4455
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304456static int
4457wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
4458 struct wireless_dev *wdev,
4459 void *data, int data_len)
4460{
4461 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
4462 uint8_t i, feature_sets, max_feature_sets;
4463 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
4464 struct sk_buff *reply_skb;
4465
4466 ENTER();
4467
4468 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
4469 data, data_len, NULL)) {
4470 hddLog(LOGE, FL("Invalid ATTR"));
4471 return -EINVAL;
4472 }
4473
4474 /* Parse and fetch max feature set */
4475 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
4476 hddLog(LOGE, FL("Attr max feature set size failed"));
4477 return -EINVAL;
4478 }
4479 max_feature_sets = nla_get_u32(
4480 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
4481 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
4482
4483 /* Fill feature combination matrix */
4484 feature_sets = 0;
4485 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4486 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4487 WIFI_FEATURE_P2P;
4488
4489 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4490 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4491 WIFI_FEATURE_SOFT_AP;
4492
4493 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4494 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
4495 WIFI_FEATURE_SOFT_AP;
4496
4497 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4498 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4499 WIFI_FEATURE_SOFT_AP |
4500 WIFI_FEATURE_P2P;
4501
4502 /* Add more feature combinations here */
4503
4504 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
4505 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
4506 hddLog(LOG1, "Feature set matrix");
4507 for (i = 0; i < feature_sets; i++)
4508 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
4509
4510 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4511 sizeof(u32) * feature_sets +
4512 NLMSG_HDRLEN);
4513
4514 if (reply_skb) {
4515 if (nla_put_u32(reply_skb,
4516 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
4517 feature_sets) ||
4518 nla_put(reply_skb,
4519 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
4520 sizeof(u32) * feature_sets, feature_set_matrix)) {
4521 hddLog(LOGE, FL("nla put fail"));
4522 kfree_skb(reply_skb);
4523 return -EINVAL;
4524 }
4525
4526 return cfg80211_vendor_cmd_reply(reply_skb);
4527 }
4528 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
4529 return -ENOMEM;
4530
4531max_buffer_err:
4532 hddLog(LOGE, FL("Feature set max buffer size reached. feature_sets(%d) max(%d)"),
4533 feature_sets, WLAN_HDD_MAX_FEATURE_SET);
4534 return -EINVAL;
4535}
4536
Agarwal Ashish738843c2014-09-25 12:27:56 +05304537static const struct nla_policy
4538wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
4539 +1] =
4540{
4541 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
4542};
4543
4544static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
4545 struct wireless_dev *wdev,
4546 void *data,
4547 int data_len)
4548{
4549 struct net_device *dev = wdev->netdev;
4550 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4551 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4552 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4553 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
4554 eHalStatus status;
4555 u32 dfsFlag = 0;
4556
4557 status = wlan_hdd_validate_context(pHddCtx);
4558 if (0 != status) {
4559 hddLog(VOS_TRACE_LEVEL_ERROR,
4560 FL("HDD context is not valid"));
4561 return -EINVAL;
4562 }
4563 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
4564 data, data_len,
4565 wlan_hdd_set_no_dfs_flag_config_policy)) {
4566 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4567 return -EINVAL;
4568 }
4569
4570 /* Parse and fetch required bandwidth kbps */
4571 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
4572 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
4573 return -EINVAL;
4574 }
4575
4576 dfsFlag = nla_get_u32(
4577 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
4578 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
4579 dfsFlag);
4580
4581 pHddCtx->disable_dfs_flag = dfsFlag;
4582
4583 sme_disable_dfs_channel(hHal, dfsFlag);
4584 sme_FilterScanResults(hHal, pAdapter->sessionId);
4585 return 0;
4586}
Atul Mittal115287b2014-07-08 13:26:33 +05304587
Mukul Sharma2a271632014-10-13 14:59:01 +05304588const struct
4589nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
4590{
4591 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
4592 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
4593};
4594
4595static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
4596 struct wireless_dev *wdev, void *data, int data_len)
4597{
4598
4599 u8 bssid[6] = {0};
4600 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4601 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
4602 eHalStatus status = eHAL_STATUS_SUCCESS;
4603 v_U32_t isFwrRoamEnabled = FALSE;
4604 int ret;
4605
4606 if (NULL == pHddCtx) {
4607 hddLog(VOS_TRACE_LEVEL_ERROR,
4608 FL("HDD context is not valid"));
4609 return -EINVAL;
4610 }
4611
4612 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
4613 data, data_len,
4614 qca_wlan_vendor_attr);
4615 if (ret){
4616 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4617 return -EINVAL;
4618 }
4619
4620 /* Parse and fetch Enable flag */
4621 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
4622 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
4623 return -EINVAL;
4624 }
4625
4626 isFwrRoamEnabled = nla_get_u32(
4627 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
4628
4629 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
4630
4631 /* Parse and fetch bssid */
4632 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
4633 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
4634 return -EINVAL;
4635 }
4636
4637 memcpy(bssid, nla_data(
4638 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
4639 sizeof(bssid));
4640 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
4641
4642 //Update roaming
4643 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
4644 return status;
4645}
4646
Sunil Duttc69bccb2014-05-26 21:30:20 +05304647const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
4648{
Mukul Sharma2a271632014-10-13 14:59:01 +05304649 {
4650 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4651 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
4652 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4653 WIPHY_VENDOR_CMD_NEED_NETDEV |
4654 WIPHY_VENDOR_CMD_NEED_RUNNING,
4655 .doit = wlan_hdd_cfg80211_firmware_roaming
4656 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304657#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4658 {
4659 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4660 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
4661 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4662 WIPHY_VENDOR_CMD_NEED_NETDEV |
4663 WIPHY_VENDOR_CMD_NEED_RUNNING,
4664 .doit = wlan_hdd_cfg80211_ll_stats_clear
4665 },
4666
4667 {
4668 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4669 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
4670 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4671 WIPHY_VENDOR_CMD_NEED_NETDEV |
4672 WIPHY_VENDOR_CMD_NEED_RUNNING,
4673 .doit = wlan_hdd_cfg80211_ll_stats_set
4674 },
4675
4676 {
4677 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4678 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
4679 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4680 WIPHY_VENDOR_CMD_NEED_NETDEV |
4681 WIPHY_VENDOR_CMD_NEED_RUNNING,
4682 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05304683 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304684#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304685#ifdef WLAN_FEATURE_EXTSCAN
4686 {
4687 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4688 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
4689 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4690 WIPHY_VENDOR_CMD_NEED_NETDEV |
4691 WIPHY_VENDOR_CMD_NEED_RUNNING,
4692 .doit = wlan_hdd_cfg80211_extscan_start
4693 },
4694 {
4695 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4696 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
4697 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4698 WIPHY_VENDOR_CMD_NEED_NETDEV |
4699 WIPHY_VENDOR_CMD_NEED_RUNNING,
4700 .doit = wlan_hdd_cfg80211_extscan_stop
4701 },
4702 {
4703 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4704 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
4705 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4706 WIPHY_VENDOR_CMD_NEED_NETDEV,
4707 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
4708 },
4709 {
4710 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4711 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
4712 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4713 WIPHY_VENDOR_CMD_NEED_NETDEV |
4714 WIPHY_VENDOR_CMD_NEED_RUNNING,
4715 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
4716 },
4717 {
4718 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4719 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
4720 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4721 WIPHY_VENDOR_CMD_NEED_NETDEV |
4722 WIPHY_VENDOR_CMD_NEED_RUNNING,
4723 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
4724 },
4725 {
4726 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4727 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
4728 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4729 WIPHY_VENDOR_CMD_NEED_NETDEV |
4730 WIPHY_VENDOR_CMD_NEED_RUNNING,
4731 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
4732 },
4733 {
4734 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4735 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
4736 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4737 WIPHY_VENDOR_CMD_NEED_NETDEV |
4738 WIPHY_VENDOR_CMD_NEED_RUNNING,
4739 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
4740 },
4741 {
4742 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4743 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
4744 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4745 WIPHY_VENDOR_CMD_NEED_NETDEV |
4746 WIPHY_VENDOR_CMD_NEED_RUNNING,
4747 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
4748 },
4749 {
4750 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4751 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
4752 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4753 WIPHY_VENDOR_CMD_NEED_NETDEV |
4754 WIPHY_VENDOR_CMD_NEED_RUNNING,
4755 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
4756 },
4757#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304758/*EXT TDLS*/
4759 {
4760 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4761 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
4762 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4763 WIPHY_VENDOR_CMD_NEED_NETDEV |
4764 WIPHY_VENDOR_CMD_NEED_RUNNING,
4765 .doit = wlan_hdd_cfg80211_exttdls_enable
4766 },
4767 {
4768 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4769 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
4770 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4771 WIPHY_VENDOR_CMD_NEED_NETDEV |
4772 WIPHY_VENDOR_CMD_NEED_RUNNING,
4773 .doit = wlan_hdd_cfg80211_exttdls_disable
4774 },
4775 {
4776 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4777 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
4778 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4779 WIPHY_VENDOR_CMD_NEED_NETDEV,
4780 .doit = wlan_hdd_cfg80211_exttdls_get_status
4781 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05304782 {
4783 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4784 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
4785 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4786 WIPHY_VENDOR_CMD_NEED_NETDEV,
4787 .doit = wlan_hdd_cfg80211_get_supported_features
4788 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05304789 {
4790 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4791 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
4792 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4793 WIPHY_VENDOR_CMD_NEED_NETDEV,
4794 .doit = wlan_hdd_cfg80211_disable_dfs_channels
4795 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304796 {
4797 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4798 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
4799 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4800 WIPHY_VENDOR_CMD_NEED_NETDEV,
4801 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
4802 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304803 {
4804 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4805 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
4806 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4807 WIPHY_VENDOR_CMD_NEED_NETDEV,
4808 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
4809 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304810};
4811
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004812/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05304813static const
4814struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004815{
4816#ifdef FEATURE_WLAN_CH_AVOID
4817 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05304818 .vendor_id = QCA_NL80211_VENDOR_ID,
4819 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004820 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304821#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
4822#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4823 {
4824 /* Index = 1*/
4825 .vendor_id = QCA_NL80211_VENDOR_ID,
4826 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
4827 },
4828 {
4829 /* Index = 2*/
4830 .vendor_id = QCA_NL80211_VENDOR_ID,
4831 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
4832 },
4833 {
4834 /* Index = 3*/
4835 .vendor_id = QCA_NL80211_VENDOR_ID,
4836 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
4837 },
4838 {
4839 /* Index = 4*/
4840 .vendor_id = QCA_NL80211_VENDOR_ID,
4841 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
4842 },
4843 {
4844 /* Index = 5*/
4845 .vendor_id = QCA_NL80211_VENDOR_ID,
4846 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
4847 },
4848 {
4849 /* Index = 6*/
4850 .vendor_id = QCA_NL80211_VENDOR_ID,
4851 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
4852 },
4853#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304854#ifdef WLAN_FEATURE_EXTSCAN
4855 {
4856 .vendor_id = QCA_NL80211_VENDOR_ID,
4857 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
4858 },
4859 {
4860 .vendor_id = QCA_NL80211_VENDOR_ID,
4861 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
4862 },
4863 {
4864 .vendor_id = QCA_NL80211_VENDOR_ID,
4865 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
4866 },
4867 {
4868 .vendor_id = QCA_NL80211_VENDOR_ID,
4869 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
4870 },
4871 {
4872 .vendor_id = QCA_NL80211_VENDOR_ID,
4873 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
4874 },
4875 {
4876 .vendor_id = QCA_NL80211_VENDOR_ID,
4877 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
4878 },
4879 {
4880 .vendor_id = QCA_NL80211_VENDOR_ID,
4881 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
4882 },
4883 {
4884 .vendor_id = QCA_NL80211_VENDOR_ID,
4885 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
4886 },
4887 {
4888 .vendor_id = QCA_NL80211_VENDOR_ID,
4889 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
4890 },
4891 {
4892 .vendor_id = QCA_NL80211_VENDOR_ID,
4893 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
4894 },
4895 {
4896 .vendor_id = QCA_NL80211_VENDOR_ID,
4897 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
4898 },
4899 {
4900 .vendor_id = QCA_NL80211_VENDOR_ID,
4901 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
4902 },
4903 {
4904 .vendor_id = QCA_NL80211_VENDOR_ID,
4905 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
4906 },
4907#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304908/*EXT TDLS*/
4909 {
4910 .vendor_id = QCA_NL80211_VENDOR_ID,
4911 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
4912 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004913};
4914
Jeff Johnson295189b2012-06-20 16:38:30 -07004915/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304916 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304917 * This function is called by hdd_wlan_startup()
4918 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304919 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07004920 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304921struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07004922{
4923 struct wiphy *wiphy;
4924 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304925 /*
4926 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07004927 */
4928 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
4929
4930 if (!wiphy)
4931 {
4932 /* Print error and jump into err label and free the memory */
4933 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
4934 return NULL;
4935 }
4936
Sunil Duttc69bccb2014-05-26 21:30:20 +05304937
Jeff Johnson295189b2012-06-20 16:38:30 -07004938 return wiphy;
4939}
4940
4941/*
4942 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304943 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07004944 * private ioctl to change the band value
4945 */
4946int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
4947{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304948 int i, j;
4949 eNVChannelEnabledType channelEnabledState;
4950
Jeff Johnsone7245742012-09-05 17:12:55 -07004951 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304952
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304953 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07004954 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304955
4956 if (NULL == wiphy->bands[i])
4957 {
4958 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4959 __func__, i);
4960 continue;
4961 }
4962
4963 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4964 {
4965 struct ieee80211_supported_band *band = wiphy->bands[i];
4966
4967 channelEnabledState = vos_nv_getChannelEnabledState(
4968 band->channels[j].hw_value);
4969
4970 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
4971 {
Abhishek Singh678227a2014-11-04 10:52:38 +05304972 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304973 continue;
4974 }
4975 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
4976 {
4977 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4978 continue;
4979 }
4980
4981 if (NV_CHANNEL_DISABLE == channelEnabledState ||
4982 NV_CHANNEL_INVALID == channelEnabledState)
4983 {
4984 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4985 }
4986 else if (NV_CHANNEL_DFS == channelEnabledState)
4987 {
4988 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4989 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
4990 }
4991 else
4992 {
4993 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4994 |IEEE80211_CHAN_RADAR);
4995 }
4996 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004997 }
4998 return 0;
4999}
5000/*
5001 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305002 * This function is called by hdd_wlan_startup()
5003 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005004 * This function is used to initialize and register wiphy structure.
5005 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305006int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005007 struct wiphy *wiphy,
5008 hdd_config_t *pCfg
5009 )
5010{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305011 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305012 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5013
Jeff Johnsone7245742012-09-05 17:12:55 -07005014 ENTER();
5015
Jeff Johnson295189b2012-06-20 16:38:30 -07005016 /* Now bind the underlying wlan device with wiphy */
5017 set_wiphy_dev(wiphy, dev);
5018
5019 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005020
Kiet Lam6c583332013-10-14 05:37:09 +05305021#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005022 /* the flag for the other case would be initialzed in
5023 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005024 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305025#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005026
Amar Singhalfddc28c2013-09-05 13:03:40 -07005027 /* This will disable updating of NL channels from passive to
5028 * active if a beacon is received on passive channel. */
5029 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07005030
Amar Singhalfddc28c2013-09-05 13:03:40 -07005031
Amar Singhala49cbc52013-10-08 18:37:44 -07005032
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005033#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005034 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5035 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5036 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005037 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05305038 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005039#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005040
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005041#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005042 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005043#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005044 || pCfg->isFastRoamIniFeatureEnabled
5045#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005046#ifdef FEATURE_WLAN_ESE
5047 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005048#endif
5049 )
5050 {
5051 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5052 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005053#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005054#ifdef FEATURE_WLAN_TDLS
5055 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5056 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5057#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305058#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305059 if (pCfg->configPNOScanSupport)
5060 {
5061 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5062 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5063 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5064 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5065 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305066#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005067
Amar Singhalfddc28c2013-09-05 13:03:40 -07005068#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005069 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5070 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005071 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005072 driver need to determine what to do with both
5073 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005074
5075 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005076#else
5077 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005078#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005079
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305080 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5081
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05305082 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005083
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305084 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5085
Jeff Johnson295189b2012-06-20 16:38:30 -07005086 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305087 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07005088 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07005089 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5090 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005091 | BIT(NL80211_IFTYPE_AP);
5092
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305093 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005094 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305095#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5096 if( pCfg->enableMCC )
5097 {
5098 /* Currently, supports up to two channels */
5099 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005100
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305101 if( !pCfg->allowMCCGODiffBI )
5102 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005103
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305104 }
5105 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5106 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005107#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305108 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005109
Jeff Johnson295189b2012-06-20 16:38:30 -07005110 /* Before registering we need to update the ht capabilitied based
5111 * on ini values*/
5112 if( !pCfg->ShortGI20MhzEnable )
5113 {
5114 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5115 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5116 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5117 }
5118
5119 if( !pCfg->ShortGI40MhzEnable )
5120 {
5121 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5122 }
5123
5124 if( !pCfg->nChannelBondingMode5GHz )
5125 {
5126 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5127 }
5128
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305129 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305130 if (true == hdd_is_5g_supported(pHddCtx))
5131 {
5132 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5133 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305134
5135 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5136 {
5137
5138 if (NULL == wiphy->bands[i])
5139 {
5140 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5141 __func__, i);
5142 continue;
5143 }
5144
5145 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5146 {
5147 struct ieee80211_supported_band *band = wiphy->bands[i];
5148
5149 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5150 {
5151 // Enable social channels for P2P
5152 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5153 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5154 else
5155 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5156 continue;
5157 }
5158 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5159 {
5160 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5161 continue;
5162 }
5163 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005164 }
5165 /*Initialise the supported cipher suite details*/
5166 wiphy->cipher_suites = hdd_cipher_suites;
5167 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5168
5169 /*signal strength in mBm (100*dBm) */
5170 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5171
5172#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305173 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005174#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005175
Sunil Duttc69bccb2014-05-26 21:30:20 +05305176 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
5177 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005178 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
5179 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
5180
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305181 EXIT();
5182 return 0;
5183}
5184
5185/* In this function we are registering wiphy. */
5186int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
5187{
5188 ENTER();
5189 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005190 if (0 > wiphy_register(wiphy))
5191 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305192 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07005193 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
5194 return -EIO;
5195 }
5196
5197 EXIT();
5198 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305199}
Jeff Johnson295189b2012-06-20 16:38:30 -07005200
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305201/* In this function we are updating channel list when,
5202 regulatory domain is FCC and country code is US.
5203 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
5204 As per FCC smart phone is not a indoor device.
5205 GO should not opeate on indoor channels */
5206void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
5207{
5208 int j;
5209 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5210 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
5211 //Default counrtycode from NV at the time of wiphy initialization.
5212 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
5213 &defaultCountryCode[0]))
5214 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005215 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305216 }
5217 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
5218 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305219 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
5220 {
5221 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
5222 return;
5223 }
5224 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
5225 {
5226 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
5227 // Mark UNII -1 band channel as passive
5228 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
5229 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
5230 }
5231 }
5232}
5233
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305234/* This function registers for all frame which supplicant is interested in */
5235void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005236{
Jeff Johnson295189b2012-06-20 16:38:30 -07005237 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5238 /* Register for all P2P action, public action etc frames */
5239 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5240
Jeff Johnsone7245742012-09-05 17:12:55 -07005241 ENTER();
5242
Jeff Johnson295189b2012-06-20 16:38:30 -07005243 /* Right now we are registering these frame when driver is getting
5244 initialized. Once we will move to 2.6.37 kernel, in which we have
5245 frame register ops, we will move this code as a part of that */
5246 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305247 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07005248 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5249
5250 /* GAS Initial Response */
5251 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5252 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305253
Jeff Johnson295189b2012-06-20 16:38:30 -07005254 /* GAS Comeback Request */
5255 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5256 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5257
5258 /* GAS Comeback Response */
5259 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5260 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5261
5262 /* P2P Public Action */
5263 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305264 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005265 P2P_PUBLIC_ACTION_FRAME_SIZE );
5266
5267 /* P2P Action */
5268 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5269 (v_U8_t*)P2P_ACTION_FRAME,
5270 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07005271
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05305272 /* WNM BSS Transition Request frame */
5273 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5274 (v_U8_t*)WNM_BSS_ACTION_FRAME,
5275 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005276
5277 /* WNM-Notification */
5278 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5279 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5280 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005281}
5282
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305283void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005284{
Jeff Johnson295189b2012-06-20 16:38:30 -07005285 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5286 /* Register for all P2P action, public action etc frames */
5287 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5288
Jeff Johnsone7245742012-09-05 17:12:55 -07005289 ENTER();
5290
Jeff Johnson295189b2012-06-20 16:38:30 -07005291 /* Right now we are registering these frame when driver is getting
5292 initialized. Once we will move to 2.6.37 kernel, in which we have
5293 frame register ops, we will move this code as a part of that */
5294 /* GAS Initial Request */
5295
5296 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5297 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5298
5299 /* GAS Initial Response */
5300 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5301 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305302
Jeff Johnson295189b2012-06-20 16:38:30 -07005303 /* GAS Comeback Request */
5304 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5305 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5306
5307 /* GAS Comeback Response */
5308 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5309 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5310
5311 /* P2P Public Action */
5312 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305313 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005314 P2P_PUBLIC_ACTION_FRAME_SIZE );
5315
5316 /* P2P Action */
5317 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5318 (v_U8_t*)P2P_ACTION_FRAME,
5319 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005320 /* WNM-Notification */
5321 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5322 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5323 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005324}
5325
5326#ifdef FEATURE_WLAN_WAPI
5327void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
5328 const u8 *mac_addr, u8 *key , int key_Len)
5329{
5330 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5331 tCsrRoamSetKey setKey;
5332 v_BOOL_t isConnected = TRUE;
5333 int status = 0;
5334 v_U32_t roamId= 0xFF;
5335 tANI_U8 *pKeyPtr = NULL;
5336 int n = 0;
5337
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305338 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
5339 __func__, hdd_device_modetoString(pAdapter->device_mode),
5340 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005341
Gopichand Nakkalae7480202013-02-11 15:24:22 +05305342 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005343 setKey.keyId = key_index; // Store Key ID
5344 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
5345 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
5346 setKey.paeRole = 0 ; // the PAE role
5347 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
5348 {
5349 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
5350 }
5351 else
5352 {
5353 isConnected = hdd_connIsConnected(pHddStaCtx);
5354 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
5355 }
5356 setKey.keyLength = key_Len;
5357 pKeyPtr = setKey.Key;
5358 memcpy( pKeyPtr, key, key_Len);
5359
Arif Hussain6d2a3322013-11-17 19:50:10 -08005360 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005361 __func__, key_Len);
5362 for (n = 0 ; n < key_Len; n++)
5363 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
5364 __func__,n,setKey.Key[n]);
5365
5366 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
5367 if ( isConnected )
5368 {
5369 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
5370 pAdapter->sessionId, &setKey, &roamId );
5371 }
5372 if ( status != 0 )
5373 {
5374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5375 "[%4d] sme_RoamSetKey returned ERROR status= %d",
5376 __LINE__, status );
5377 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
5378 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05305379 /* Need to clear any trace of key value in the memory.
5380 * Thus zero out the memory even though it is local
5381 * variable.
5382 */
5383 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005384}
5385#endif /* FEATURE_WLAN_WAPI*/
5386
5387#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305388int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005389 beacon_data_t **ppBeacon,
5390 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005391#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305392int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005393 beacon_data_t **ppBeacon,
5394 struct cfg80211_beacon_data *params,
5395 int dtim_period)
5396#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305397{
Jeff Johnson295189b2012-06-20 16:38:30 -07005398 int size;
5399 beacon_data_t *beacon = NULL;
5400 beacon_data_t *old = NULL;
5401 int head_len,tail_len;
5402
Jeff Johnsone7245742012-09-05 17:12:55 -07005403 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005404 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305405 {
5406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5407 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005408 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305409 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005410
5411 old = pAdapter->sessionCtx.ap.beacon;
5412
5413 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305414 {
5415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5416 FL("session(%d) old and new heads points to NULL"),
5417 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005418 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305419 }
5420
5421 if (params->tail && !params->tail_len)
5422 {
5423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5424 FL("tail_len is zero but tail is not NULL"));
5425 return -EINVAL;
5426 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005427
Jeff Johnson295189b2012-06-20 16:38:30 -07005428#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
5429 /* Kernel 3.0 is not updating dtim_period for set beacon */
5430 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305431 {
5432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5433 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005434 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305435 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005436#endif
5437
5438 if(params->head)
5439 head_len = params->head_len;
5440 else
5441 head_len = old->head_len;
5442
5443 if(params->tail || !old)
5444 tail_len = params->tail_len;
5445 else
5446 tail_len = old->tail_len;
5447
5448 size = sizeof(beacon_data_t) + head_len + tail_len;
5449
5450 beacon = kzalloc(size, GFP_KERNEL);
5451
5452 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305453 {
5454 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5455 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005456 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305457 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005458
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005459#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005460 if(params->dtim_period || !old )
5461 beacon->dtim_period = params->dtim_period;
5462 else
5463 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005464#else
5465 if(dtim_period || !old )
5466 beacon->dtim_period = dtim_period;
5467 else
5468 beacon->dtim_period = old->dtim_period;
5469#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305470
Jeff Johnson295189b2012-06-20 16:38:30 -07005471 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
5472 beacon->tail = beacon->head + head_len;
5473 beacon->head_len = head_len;
5474 beacon->tail_len = tail_len;
5475
5476 if(params->head) {
5477 memcpy (beacon->head,params->head,beacon->head_len);
5478 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305479 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07005480 if(old)
5481 memcpy (beacon->head,old->head,beacon->head_len);
5482 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305483
Jeff Johnson295189b2012-06-20 16:38:30 -07005484 if(params->tail) {
5485 memcpy (beacon->tail,params->tail,beacon->tail_len);
5486 }
5487 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305488 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07005489 memcpy (beacon->tail,old->tail,beacon->tail_len);
5490 }
5491
5492 *ppBeacon = beacon;
5493
5494 kfree(old);
5495
5496 return 0;
5497
5498}
Jeff Johnson295189b2012-06-20 16:38:30 -07005499
5500v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
5501{
5502 int left = length;
5503 v_U8_t *ptr = pIes;
5504 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305505
Jeff Johnson295189b2012-06-20 16:38:30 -07005506 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305507 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005508 elem_id = ptr[0];
5509 elem_len = ptr[1];
5510 left -= 2;
5511 if(elem_len > left)
5512 {
5513 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005514 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005515 eid,elem_len,left);
5516 return NULL;
5517 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305518 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005519 {
5520 return ptr;
5521 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305522
Jeff Johnson295189b2012-06-20 16:38:30 -07005523 left -= elem_len;
5524 ptr += (elem_len + 2);
5525 }
5526 return NULL;
5527}
5528
Jeff Johnson295189b2012-06-20 16:38:30 -07005529/* Check if rate is 11g rate or not */
5530static int wlan_hdd_rate_is_11g(u8 rate)
5531{
Sanjay Devnani28322e22013-06-21 16:13:40 -07005532 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005533 u8 i;
5534 for (i = 0; i < 8; i++)
5535 {
5536 if(rate == gRateArray[i])
5537 return TRUE;
5538 }
5539 return FALSE;
5540}
5541
5542/* Check for 11g rate and set proper 11g only mode */
5543static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
5544 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
5545{
5546 u8 i, num_rates = pIe[0];
5547
5548 pIe += 1;
5549 for ( i = 0; i < num_rates; i++)
5550 {
5551 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
5552 {
5553 /* If rate set have 11g rate than change the mode to 11G */
5554 *pSapHw_mode = eSAP_DOT11_MODE_11g;
5555 if (pIe[i] & BASIC_RATE_MASK)
5556 {
5557 /* If we have 11g rate as basic rate, it means mode
5558 is 11g only mode.
5559 */
5560 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
5561 *pCheckRatesfor11g = FALSE;
5562 }
5563 }
5564 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
5565 {
5566 *require_ht = TRUE;
5567 }
5568 }
5569 return;
5570}
5571
5572static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
5573{
5574 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5575 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5576 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5577 u8 checkRatesfor11g = TRUE;
5578 u8 require_ht = FALSE;
5579 u8 *pIe=NULL;
5580
5581 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
5582
5583 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
5584 pBeacon->head_len, WLAN_EID_SUPP_RATES);
5585 if (pIe != NULL)
5586 {
5587 pIe += 1;
5588 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5589 &pConfig->SapHw_mode);
5590 }
5591
5592 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5593 WLAN_EID_EXT_SUPP_RATES);
5594 if (pIe != NULL)
5595 {
5596
5597 pIe += 1;
5598 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5599 &pConfig->SapHw_mode);
5600 }
5601
5602 if( pConfig->channel > 14 )
5603 {
5604 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
5605 }
5606
5607 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5608 WLAN_EID_HT_CAPABILITY);
5609
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305610 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005611 {
5612 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
5613 if(require_ht)
5614 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
5615 }
5616}
5617
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305618static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
5619 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
5620{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005621 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305622 v_U8_t *pIe = NULL;
5623 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5624
5625 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
5626 pBeacon->tail, pBeacon->tail_len);
5627
5628 if (pIe)
5629 {
5630 ielen = pIe[1] + 2;
5631 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5632 {
5633 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
5634 }
5635 else
5636 {
5637 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
5638 return -EINVAL;
5639 }
5640 *total_ielen += ielen;
5641 }
5642 return 0;
5643}
5644
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005645static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
5646 v_U8_t *genie, v_U8_t *total_ielen)
5647{
5648 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5649 int left = pBeacon->tail_len;
5650 v_U8_t *ptr = pBeacon->tail;
5651 v_U8_t elem_id, elem_len;
5652 v_U16_t ielen = 0;
5653
5654 if ( NULL == ptr || 0 == left )
5655 return;
5656
5657 while (left >= 2)
5658 {
5659 elem_id = ptr[0];
5660 elem_len = ptr[1];
5661 left -= 2;
5662 if (elem_len > left)
5663 {
5664 hddLog( VOS_TRACE_LEVEL_ERROR,
5665 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
5666 elem_id, elem_len, left);
5667 return;
5668 }
5669 if (IE_EID_VENDOR == elem_id)
5670 {
5671 /* skipping the VSIE's which we don't want to include or
5672 * it will be included by existing code
5673 */
5674 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
5675#ifdef WLAN_FEATURE_WFD
5676 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
5677#endif
5678 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5679 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5680 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
5681 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5682 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
5683 {
5684 ielen = ptr[1] + 2;
5685 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5686 {
5687 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
5688 *total_ielen += ielen;
5689 }
5690 else
5691 {
5692 hddLog( VOS_TRACE_LEVEL_ERROR,
5693 "IE Length is too big "
5694 "IEs eid=%d elem_len=%d total_ie_lent=%d",
5695 elem_id, elem_len, *total_ielen);
5696 }
5697 }
5698 }
5699
5700 left -= elem_len;
5701 ptr += (elem_len + 2);
5702 }
5703 return;
5704}
5705
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005706#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005707static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5708 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005709#else
5710static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5711 struct cfg80211_beacon_data *params)
5712#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005713{
5714 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305715 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005716 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07005717 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005718
5719 genie = vos_mem_malloc(MAX_GENIE_LEN);
5720
5721 if(genie == NULL) {
5722
5723 return -ENOMEM;
5724 }
5725
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305726 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5727 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005728 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305729 hddLog(LOGE,
5730 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305731 ret = -EINVAL;
5732 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005733 }
5734
5735#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305736 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5737 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
5738 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305739 hddLog(LOGE,
5740 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305741 ret = -EINVAL;
5742 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005743 }
5744#endif
5745
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305746 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5747 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005748 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305749 hddLog(LOGE,
5750 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305751 ret = -EINVAL;
5752 goto done;
5753 }
5754
5755 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
5756 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005757 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07005758 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005759
5760 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5761 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
5762 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
5763 {
5764 hddLog(LOGE,
5765 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005766 ret = -EINVAL;
5767 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005768 }
5769
5770 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5771 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5772 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5773 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5774 ==eHAL_STATUS_FAILURE)
5775 {
5776 hddLog(LOGE,
5777 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005778 ret = -EINVAL;
5779 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005780 }
5781
5782 // Added for ProResp IE
5783 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
5784 {
5785 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
5786 u8 probe_rsp_ie_len[3] = {0};
5787 u8 counter = 0;
5788 /* Check Probe Resp Length if it is greater then 255 then Store
5789 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
5790 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
5791 Store More then 255 bytes into One Variable.
5792 */
5793 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
5794 {
5795 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
5796 {
5797 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
5798 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
5799 }
5800 else
5801 {
5802 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
5803 rem_probe_resp_ie_len = 0;
5804 }
5805 }
5806
5807 rem_probe_resp_ie_len = 0;
5808
5809 if (probe_rsp_ie_len[0] > 0)
5810 {
5811 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5812 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
5813 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5814 probe_rsp_ie_len[0], NULL,
5815 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5816 {
5817 hddLog(LOGE,
5818 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005819 ret = -EINVAL;
5820 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005821 }
5822 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
5823 }
5824
5825 if (probe_rsp_ie_len[1] > 0)
5826 {
5827 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5828 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
5829 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5830 probe_rsp_ie_len[1], NULL,
5831 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5832 {
5833 hddLog(LOGE,
5834 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005835 ret = -EINVAL;
5836 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005837 }
5838 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
5839 }
5840
5841 if (probe_rsp_ie_len[2] > 0)
5842 {
5843 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5844 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
5845 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5846 probe_rsp_ie_len[2], NULL,
5847 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5848 {
5849 hddLog(LOGE,
5850 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005851 ret = -EINVAL;
5852 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005853 }
5854 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
5855 }
5856
5857 if (probe_rsp_ie_len[1] == 0 )
5858 {
5859 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5860 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
5861 eANI_BOOLEAN_FALSE) )
5862 {
5863 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005864 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005865 }
5866 }
5867
5868 if (probe_rsp_ie_len[2] == 0 )
5869 {
5870 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5871 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
5872 eANI_BOOLEAN_FALSE) )
5873 {
5874 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005875 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005876 }
5877 }
5878
5879 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5880 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5881 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5882 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5883 == eHAL_STATUS_FAILURE)
5884 {
5885 hddLog(LOGE,
5886 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005887 ret = -EINVAL;
5888 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005889 }
5890 }
5891 else
5892 {
5893 // Reset WNI_CFG_PROBE_RSP Flags
5894 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
5895
5896 hddLog(VOS_TRACE_LEVEL_INFO,
5897 "%s: No Probe Response IE received in set beacon",
5898 __func__);
5899 }
5900
5901 // Added for AssocResp IE
5902 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
5903 {
5904 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5905 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
5906 params->assocresp_ies_len, NULL,
5907 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5908 {
5909 hddLog(LOGE,
5910 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005911 ret = -EINVAL;
5912 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005913 }
5914
5915 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5916 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
5917 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5918 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5919 == eHAL_STATUS_FAILURE)
5920 {
5921 hddLog(LOGE,
5922 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005923 ret = -EINVAL;
5924 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005925 }
5926 }
5927 else
5928 {
5929 hddLog(VOS_TRACE_LEVEL_INFO,
5930 "%s: No Assoc Response IE received in set beacon",
5931 __func__);
5932
5933 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5934 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5935 eANI_BOOLEAN_FALSE) )
5936 {
5937 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005938 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005939 }
5940 }
5941
Jeff Johnsone7245742012-09-05 17:12:55 -07005942done:
Jeff Johnson295189b2012-06-20 16:38:30 -07005943 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305944 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005945}
Jeff Johnson295189b2012-06-20 16:38:30 -07005946
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305947/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005948 * FUNCTION: wlan_hdd_validate_operation_channel
5949 * called by wlan_hdd_cfg80211_start_bss() and
5950 * wlan_hdd_cfg80211_set_channel()
5951 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305952 * channel list.
5953 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005954VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005955{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305956
Jeff Johnson295189b2012-06-20 16:38:30 -07005957 v_U32_t num_ch = 0;
5958 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5959 u32 indx = 0;
5960 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305961 v_U8_t fValidChannel = FALSE, count = 0;
5962 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305963
Jeff Johnson295189b2012-06-20 16:38:30 -07005964 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5965
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305966 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005967 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305968 /* Validate the channel */
5969 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005970 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305971 if ( channel == rfChannels[count].channelNum )
5972 {
5973 fValidChannel = TRUE;
5974 break;
5975 }
5976 }
5977 if (fValidChannel != TRUE)
5978 {
5979 hddLog(VOS_TRACE_LEVEL_ERROR,
5980 "%s: Invalid Channel [%d]", __func__, channel);
5981 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005982 }
5983 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305984 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005985 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305986 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5987 valid_ch, &num_ch))
5988 {
5989 hddLog(VOS_TRACE_LEVEL_ERROR,
5990 "%s: failed to get valid channel list", __func__);
5991 return VOS_STATUS_E_FAILURE;
5992 }
5993 for (indx = 0; indx < num_ch; indx++)
5994 {
5995 if (channel == valid_ch[indx])
5996 {
5997 break;
5998 }
5999 }
6000
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306001 if (indx >= num_ch)
6002 {
6003 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6004 {
6005 eCsrBand band;
6006 unsigned int freq;
6007
6008 sme_GetFreqBand(hHal, &band);
6009
6010 if (eCSR_BAND_5G == band)
6011 {
6012#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6013 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6014 {
6015 freq = ieee80211_channel_to_frequency(channel,
6016 IEEE80211_BAND_2GHZ);
6017 }
6018 else
6019 {
6020 freq = ieee80211_channel_to_frequency(channel,
6021 IEEE80211_BAND_5GHZ);
6022 }
6023#else
6024 freq = ieee80211_channel_to_frequency(channel);
6025#endif
6026 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6027 return VOS_STATUS_SUCCESS;
6028 }
6029 }
6030
6031 hddLog(VOS_TRACE_LEVEL_ERROR,
6032 "%s: Invalid Channel [%d]", __func__, channel);
6033 return VOS_STATUS_E_FAILURE;
6034 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006035 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306036
Jeff Johnson295189b2012-06-20 16:38:30 -07006037 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306038
Jeff Johnson295189b2012-06-20 16:38:30 -07006039}
6040
Viral Modi3a32cc52013-02-08 11:14:52 -08006041/**
6042 * FUNCTION: wlan_hdd_cfg80211_set_channel
6043 * This function is used to set the channel number
6044 */
6045static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
6046 struct ieee80211_channel *chan,
6047 enum nl80211_channel_type channel_type
6048 )
6049{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306050 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006051 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006052 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006053 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306054 hdd_context_t *pHddCtx;
6055 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006056
6057 ENTER();
6058
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306059
Viral Modi3a32cc52013-02-08 11:14:52 -08006060 if( NULL == dev )
6061 {
6062 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006063 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006064 return -ENODEV;
6065 }
6066 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306067
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306068 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6069 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6070 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006071 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306072 "%s: device_mode = %s (%d) freq = %d", __func__,
6073 hdd_device_modetoString(pAdapter->device_mode),
6074 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306075
6076 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6077 status = wlan_hdd_validate_context(pHddCtx);
6078
6079 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006080 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6082 "%s: HDD context is not valid", __func__);
6083 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006084 }
6085
6086 /*
6087 * Do freq to chan conversion
6088 * TODO: for 11a
6089 */
6090
6091 channel = ieee80211_frequency_to_channel(freq);
6092
6093 /* Check freq range */
6094 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6095 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6096 {
6097 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006098 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006099 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6100 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6101 return -EINVAL;
6102 }
6103
6104 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6105
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306106 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6107 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006108 {
6109 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6110 {
6111 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006112 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006113 return -EINVAL;
6114 }
6115 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6116 "%s: set channel to [%d] for device mode =%d",
6117 __func__, channel,pAdapter->device_mode);
6118 }
6119 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006120 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006121 )
6122 {
6123 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6124 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6125 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6126
6127 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6128 {
6129 /* Link is up then return cant set channel*/
6130 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006131 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006132 return -EINVAL;
6133 }
6134
6135 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6136 pHddStaCtx->conn_info.operationChannel = channel;
6137 pRoamProfile->ChannelInfo.ChannelList =
6138 &pHddStaCtx->conn_info.operationChannel;
6139 }
6140 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006141 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006142 )
6143 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306144 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6145 {
6146 if(VOS_STATUS_SUCCESS !=
6147 wlan_hdd_validate_operation_channel(pAdapter,channel))
6148 {
6149 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006150 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306151 return -EINVAL;
6152 }
6153 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6154 }
6155 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006156 {
6157 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6158
6159 /* If auto channel selection is configured as enable/ 1 then ignore
6160 channel set by supplicant
6161 */
6162 if ( cfg_param->apAutoChannelSelection )
6163 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306164 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6165 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006166 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306167 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6168 __func__, hdd_device_modetoString(pAdapter->device_mode),
6169 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006170 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306171 else
6172 {
6173 if(VOS_STATUS_SUCCESS !=
6174 wlan_hdd_validate_operation_channel(pAdapter,channel))
6175 {
6176 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006177 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306178 return -EINVAL;
6179 }
6180 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6181 }
Viral Modi3a32cc52013-02-08 11:14:52 -08006182 }
6183 }
6184 else
6185 {
6186 hddLog(VOS_TRACE_LEVEL_FATAL,
6187 "%s: Invalid device mode failed to set valid channel", __func__);
6188 return -EINVAL;
6189 }
6190 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306191 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006192}
6193
Jeff Johnson295189b2012-06-20 16:38:30 -07006194#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6195static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6196 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006197#else
6198static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6199 struct cfg80211_beacon_data *params,
6200 const u8 *ssid, size_t ssid_len,
6201 enum nl80211_hidden_ssid hidden_ssid)
6202#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006203{
6204 tsap_Config_t *pConfig;
6205 beacon_data_t *pBeacon = NULL;
6206 struct ieee80211_mgmt *pMgmt_frame;
6207 v_U8_t *pIe=NULL;
6208 v_U16_t capab_info;
6209 eCsrAuthType RSNAuthType;
6210 eCsrEncryptionType RSNEncryptType;
6211 eCsrEncryptionType mcRSNEncryptType;
6212 int status = VOS_STATUS_SUCCESS;
6213 tpWLAN_SAPEventCB pSapEventCallback;
6214 hdd_hostapd_state_t *pHostapdState;
6215 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
6216 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306217 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006218 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306219 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07006220 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08006221 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05306222 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07006223 v_BOOL_t MFPCapable = VOS_FALSE;
6224 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306225 eHddDot11Mode sapDot11Mode =
6226 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07006227
6228 ENTER();
6229
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306230 iniConfig = pHddCtx->cfg_ini;
6231
Jeff Johnson295189b2012-06-20 16:38:30 -07006232 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
6233
6234 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6235
6236 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6237
6238 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6239
6240 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
6241
6242 //channel is already set in the set_channel Call back
6243 //pConfig->channel = pCommitConfig->channel;
6244
6245 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306246 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07006247 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
6248
6249 pConfig->dtim_period = pBeacon->dtim_period;
6250
Arif Hussain6d2a3322013-11-17 19:50:10 -08006251 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07006252 pConfig->dtim_period);
6253
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08006254 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07006255 {
6256 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006257 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05306258 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
6259 {
6260 tANI_BOOLEAN restartNeeded;
6261 pConfig->ieee80211d = 1;
6262 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
6263 sme_setRegInfo(hHal, pConfig->countryCode);
6264 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
6265 }
6266 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006267 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07006268 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07006269 pConfig->ieee80211d = 1;
6270 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
6271 sme_setRegInfo(hHal, pConfig->countryCode);
6272 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07006273 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006274 else
6275 {
6276 pConfig->ieee80211d = 0;
6277 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306278 /*
6279 * If auto channel is configured i.e. channel is 0,
6280 * so skip channel validation.
6281 */
6282 if( AUTO_CHANNEL_SELECT != pConfig->channel )
6283 {
6284 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
6285 {
6286 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006287 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306288 return -EINVAL;
6289 }
6290 }
6291 else
6292 {
6293 if(1 != pHddCtx->is_dynamic_channel_range_set)
6294 {
6295 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
6296 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
6297 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
6298 }
6299 pHddCtx->is_dynamic_channel_range_set = 0;
6300 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006301 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006302 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006303 {
6304 pConfig->ieee80211d = 0;
6305 }
6306 pConfig->authType = eSAP_AUTO_SWITCH;
6307
6308 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306309
6310 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07006311 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
6312
6313 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
6314
6315 /*Set wps station to configured*/
6316 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
6317
6318 if(pIe)
6319 {
6320 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
6321 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006322 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07006323 return -EINVAL;
6324 }
6325 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
6326 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006327 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07006328 /* Check 15 bit of WPS IE as it contain information for wps state
6329 * WPS state
6330 */
6331 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
6332 {
6333 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
6334 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
6335 {
6336 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
6337 }
6338 }
6339 }
6340 else
6341 {
6342 pConfig->wps_state = SAP_WPS_DISABLED;
6343 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306344 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07006345
c_hpothufe599e92014-06-16 11:38:55 +05306346 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6347 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6348 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
6349 eCSR_ENCRYPT_TYPE_NONE;
6350
Jeff Johnson295189b2012-06-20 16:38:30 -07006351 pConfig->RSNWPAReqIELength = 0;
6352 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306353 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006354 WLAN_EID_RSN);
6355 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306356 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006357 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6358 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6359 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306360 /* The actual processing may eventually be more extensive than
6361 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07006362 * by the app.
6363 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306364 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006365 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6366 &RSNEncryptType,
6367 &mcRSNEncryptType,
6368 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006369 &MFPCapable,
6370 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006371 pConfig->pRSNWPAReqIE[1]+2,
6372 pConfig->pRSNWPAReqIE );
6373
6374 if( VOS_STATUS_SUCCESS == status )
6375 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306376 /* Now copy over all the security attributes you have
6377 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006378 * */
6379 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6380 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6381 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6382 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306383 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006384 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006385 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6386 }
6387 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306388
Jeff Johnson295189b2012-06-20 16:38:30 -07006389 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6390 pBeacon->tail, pBeacon->tail_len);
6391
6392 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
6393 {
6394 if (pConfig->pRSNWPAReqIE)
6395 {
6396 /*Mixed mode WPA/WPA2*/
6397 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
6398 pConfig->RSNWPAReqIELength += pIe[1] + 2;
6399 }
6400 else
6401 {
6402 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6403 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6404 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306405 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006406 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6407 &RSNEncryptType,
6408 &mcRSNEncryptType,
6409 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006410 &MFPCapable,
6411 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006412 pConfig->pRSNWPAReqIE[1]+2,
6413 pConfig->pRSNWPAReqIE );
6414
6415 if( VOS_STATUS_SUCCESS == status )
6416 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306417 /* Now copy over all the security attributes you have
6418 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006419 * */
6420 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6421 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6422 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6423 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306424 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006425 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006426 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6427 }
6428 }
6429 }
6430
Jeff Johnson4416a782013-03-25 14:17:50 -07006431 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
6432 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
6433 return -EINVAL;
6434 }
6435
Jeff Johnson295189b2012-06-20 16:38:30 -07006436 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
6437
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006438#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006439 if (params->ssid != NULL)
6440 {
6441 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
6442 pConfig->SSIDinfo.ssid.length = params->ssid_len;
6443 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6444 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6445 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006446#else
6447 if (ssid != NULL)
6448 {
6449 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
6450 pConfig->SSIDinfo.ssid.length = ssid_len;
6451 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6452 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6453 }
6454#endif
6455
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306456 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07006457 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306458
Jeff Johnson295189b2012-06-20 16:38:30 -07006459 /* default value */
6460 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
6461 pConfig->num_accept_mac = 0;
6462 pConfig->num_deny_mac = 0;
6463
6464 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6465 pBeacon->tail, pBeacon->tail_len);
6466
6467 /* pIe for black list is following form:
6468 type : 1 byte
6469 length : 1 byte
6470 OUI : 4 bytes
6471 acl type : 1 byte
6472 no of mac addr in black list: 1 byte
6473 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306474 */
6475 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006476 {
6477 pConfig->SapMacaddr_acl = pIe[6];
6478 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006479 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006480 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306481 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
6482 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006483 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6484 for (i = 0; i < pConfig->num_deny_mac; i++)
6485 {
6486 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6487 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306488 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006489 }
6490 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6491 pBeacon->tail, pBeacon->tail_len);
6492
6493 /* pIe for white list is following form:
6494 type : 1 byte
6495 length : 1 byte
6496 OUI : 4 bytes
6497 acl type : 1 byte
6498 no of mac addr in white list: 1 byte
6499 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306500 */
6501 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006502 {
6503 pConfig->SapMacaddr_acl = pIe[6];
6504 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006505 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006506 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306507 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
6508 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006509 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6510 for (i = 0; i < pConfig->num_accept_mac; i++)
6511 {
6512 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6513 acl_entry++;
6514 }
6515 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306516
Jeff Johnson295189b2012-06-20 16:38:30 -07006517 wlan_hdd_set_sapHwmode(pHostapdAdapter);
6518
Jeff Johnsone7245742012-09-05 17:12:55 -07006519#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006520 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05306521 * This is valid only if mode is set to 11n in hostapd, either AUTO or
6522 * 11ac in .ini and 11ac is supported by both host and firmware.
6523 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
6524 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006525 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
6526 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306527 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
6528 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
6529 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
6530 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
6531 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07006532 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306533 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07006534 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306535 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006536
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306537 /* If ACS disable and selected channel <= 14
6538 * OR
6539 * ACS enabled and ACS operating band is choosen as 2.4
6540 * AND
6541 * VHT in 2.4G Disabled
6542 * THEN
6543 * Fallback to 11N mode
6544 */
6545 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
6546 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05306547 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306548 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006549 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306550 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
6551 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006552 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
6553 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006554 }
6555#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306556
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07006557 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
6558 {
6559 sme_SelectCBMode(hHal,
6560 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
6561 pConfig->channel);
6562 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006563 // ht_capab is not what the name conveys,this is used for protection bitmap
6564 pConfig->ht_capab =
6565 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
6566
6567 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
6568 {
6569 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
6570 return -EINVAL;
6571 }
6572
6573 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306574 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07006575 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
6576 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306577 pConfig->obssProtEnabled =
6578 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07006579
Chet Lanctot8cecea22014-02-11 19:09:36 -08006580#ifdef WLAN_FEATURE_11W
6581 pConfig->mfpCapable = MFPCapable;
6582 pConfig->mfpRequired = MFPRequired;
6583 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
6584 pConfig->mfpCapable, pConfig->mfpRequired);
6585#endif
6586
Arif Hussain6d2a3322013-11-17 19:50:10 -08006587 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07006588 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006589 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
6590 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
6591 (int)pConfig->channel);
6592 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
6593 pConfig->SapHw_mode, pConfig->privacy,
6594 pConfig->authType);
6595 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
6596 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
6597 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
6598 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07006599
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306600 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006601 {
6602 //Bss already started. just return.
6603 //TODO Probably it should update some beacon params.
6604 hddLog( LOGE, "Bss Already started...Ignore the request");
6605 EXIT();
6606 return 0;
6607 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306608
Agarwal Ashish51325b52014-06-16 16:50:49 +05306609 if (vos_max_concurrent_connections_reached()) {
6610 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6611 return -EINVAL;
6612 }
6613
Jeff Johnson295189b2012-06-20 16:38:30 -07006614 pConfig->persona = pHostapdAdapter->device_mode;
6615
Peng Xu2446a892014-09-05 17:21:18 +05306616 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
6617 if ( NULL != psmeConfig)
6618 {
6619 sme_GetConfigParam(hHal, psmeConfig);
6620 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
6621 vos_mem_free(psmeConfig);
6622 }
Peng Xuafc34e32014-09-25 13:23:55 +05306623 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05306624
Jeff Johnson295189b2012-06-20 16:38:30 -07006625 pSapEventCallback = hdd_hostapd_SAPEventCB;
6626 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
6627 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
6628 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006629 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006630 return -EINVAL;
6631 }
6632
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306633 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07006634 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
6635
6636 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306637
Jeff Johnson295189b2012-06-20 16:38:30 -07006638 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306639 {
6640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006641 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07006642 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07006643 VOS_ASSERT(0);
6644 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306645
Jeff Johnson295189b2012-06-20 16:38:30 -07006646 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05306647 /* Initialize WMM configuation */
6648 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306649 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006650
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006651#ifdef WLAN_FEATURE_P2P_DEBUG
6652 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
6653 {
6654 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
6655 {
6656 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6657 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006658 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006659 }
6660 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
6661 {
6662 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6663 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006664 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006665 }
6666 }
6667#endif
6668
Jeff Johnson295189b2012-06-20 16:38:30 -07006669 pHostapdState->bCommit = TRUE;
6670 EXIT();
6671
6672 return 0;
6673}
6674
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006675#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306676static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
6677 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006678 struct beacon_parameters *params)
6679{
6680 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306681 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306682 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006683
6684 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306685
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306686 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6687 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
6688 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306689 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
6690 hdd_device_modetoString(pAdapter->device_mode),
6691 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006692
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306693 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6694 status = wlan_hdd_validate_context(pHddCtx);
6695
6696 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006697 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306698 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6699 "%s: HDD context is not valid", __func__);
6700 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006701 }
6702
Agarwal Ashish51325b52014-06-16 16:50:49 +05306703 if (vos_max_concurrent_connections_reached()) {
6704 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6705 return -EINVAL;
6706 }
6707
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306708 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006709 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006710 )
6711 {
6712 beacon_data_t *old,*new;
6713
6714 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306715
Jeff Johnson295189b2012-06-20 16:38:30 -07006716 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306717 {
6718 hddLog(VOS_TRACE_LEVEL_WARN,
6719 FL("already beacon info added to session(%d)"),
6720 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006721 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306722 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006723
6724 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6725
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306726 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07006727 {
6728 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006729 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006730 return -EINVAL;
6731 }
6732
6733 pAdapter->sessionCtx.ap.beacon = new;
6734
6735 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6736 }
6737
6738 EXIT();
6739 return status;
6740}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306741
6742static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006743 struct net_device *dev,
6744 struct beacon_parameters *params)
6745{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306746 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306747 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6748 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306749 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006750
6751 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306752 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6753 TRACE_CODE_HDD_CFG80211_SET_BEACON,
6754 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
6755 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6756 __func__, hdd_device_modetoString(pAdapter->device_mode),
6757 pAdapter->device_mode);
6758
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306759 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6760 status = wlan_hdd_validate_context(pHddCtx);
6761
6762 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006763 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6765 "%s: HDD context is not valid", __func__);
6766 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006767 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306768
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)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306771 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006772 {
6773 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306774
Jeff Johnson295189b2012-06-20 16:38:30 -07006775 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 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6780 FL("session(%d) old and new heads points to NULL"),
6781 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006782 return -ENOENT;
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
6787 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306788 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006789 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006790 return -EINVAL;
6791 }
6792
6793 pAdapter->sessionCtx.ap.beacon = new;
6794
6795 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6796 }
6797
6798 EXIT();
6799 return status;
6800}
6801
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006802#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6803
6804#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006805static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
6806 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006807#else
6808static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
6809 struct net_device *dev)
6810#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006811{
6812 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07006813 hdd_context_t *pHddCtx = NULL;
6814 hdd_scaninfo_t *pScanInfo = NULL;
6815 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306816 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306817 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006818
6819 ENTER();
6820
6821 if (NULL == pAdapter)
6822 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306823 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006824 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006825 return -ENODEV;
6826 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006827
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306828 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6829 TRACE_CODE_HDD_CFG80211_STOP_AP,
6830 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306831 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6832 status = wlan_hdd_validate_context(pHddCtx);
6833
6834 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006835 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306836 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6837 "%s: HDD context is not valid", __func__);
6838 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07006839 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006840
6841 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
6842 if (NULL == staAdapter)
6843 {
6844 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
6845 if (NULL == staAdapter)
6846 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07006847 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6848 "%s: HDD adapter context for STA/P2P-CLI is Null",
6849 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006850 }
6851 }
6852
6853 pScanInfo = &pHddCtx->scan_info;
6854
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306855 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6856 __func__, hdd_device_modetoString(pAdapter->device_mode),
6857 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006858
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306859 ret = wlan_hdd_scan_abort(pAdapter);
6860
Girish Gowli4bf7a632014-06-12 13:42:11 +05306861 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07006862 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6864 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306865
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306866 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07006867 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6869 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08006870
Jeff Johnsone7245742012-09-05 17:12:55 -07006871 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306872 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07006873 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306874 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07006875 }
6876
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05306877 /* Delete all associated STAs before stopping AP/P2P GO */
6878 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05306879 hdd_hostapd_stop(dev);
6880
Jeff Johnson295189b2012-06-20 16:38:30 -07006881 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006882 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006883 )
6884 {
6885 beacon_data_t *old;
6886
6887 old = pAdapter->sessionCtx.ap.beacon;
6888
6889 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306890 {
6891 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6892 FL("session(%d) beacon data points to NULL"),
6893 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006894 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306895 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006896
Jeff Johnson295189b2012-06-20 16:38:30 -07006897 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006898
6899 mutex_lock(&pHddCtx->sap_lock);
6900 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6901 {
Jeff Johnson4416a782013-03-25 14:17:50 -07006902 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006903 {
6904 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6905
6906 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6907
6908 if (!VOS_IS_STATUS_SUCCESS(status))
6909 {
6910 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006911 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006912 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306913 }
6914 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006915 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306916 /* BSS stopped, clear the active sessions for this device mode */
6917 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006918 }
6919 mutex_unlock(&pHddCtx->sap_lock);
6920
6921 if(status != VOS_STATUS_SUCCESS)
6922 {
6923 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006924 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006925 return -EINVAL;
6926 }
6927
Jeff Johnson4416a782013-03-25 14:17:50 -07006928 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006929 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
6930 ==eHAL_STATUS_FAILURE)
6931 {
6932 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006933 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006934 }
6935
Jeff Johnson4416a782013-03-25 14:17:50 -07006936 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006937 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6938 eANI_BOOLEAN_FALSE) )
6939 {
6940 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006941 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006942 }
6943
6944 // Reset WNI_CFG_PROBE_RSP Flags
6945 wlan_hdd_reset_prob_rspies(pAdapter);
6946
6947 pAdapter->sessionCtx.ap.beacon = NULL;
6948 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006949#ifdef WLAN_FEATURE_P2P_DEBUG
6950 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
6951 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
6952 {
6953 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
6954 "GO got removed");
6955 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
6956 }
6957#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006958 }
6959 EXIT();
6960 return status;
6961}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006962
6963#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6964
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306965static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
6966 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006967 struct cfg80211_ap_settings *params)
6968{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306969 hdd_adapter_t *pAdapter;
6970 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306971 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006972
6973 ENTER();
6974
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306975 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006976 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306977 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306978 "%s: Device is Null", __func__);
6979 return -ENODEV;
6980 }
6981
6982 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6983 if (NULL == pAdapter)
6984 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306985 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306986 "%s: HDD adapter is Null", __func__);
6987 return -ENODEV;
6988 }
6989
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306990 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6991 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
6992 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306993 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6994 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306995 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306996 "%s: HDD adapter magic is invalid", __func__);
6997 return -ENODEV;
6998 }
6999
7000 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307001 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307002
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307003 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307004 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307005 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7006 "%s: HDD context is not valid", __func__);
7007 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307008 }
7009
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307010 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7011 __func__, hdd_device_modetoString(pAdapter->device_mode),
7012 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307013
7014 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007015 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007016 )
7017 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307018 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007019
7020 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307021
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007022 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307023 {
7024 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7025 FL("already beacon info added to session(%d)"),
7026 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007027 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307028 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007029
7030 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
7031
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307032 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007033 {
7034 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307035 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007036 return -EINVAL;
7037 }
7038 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007039#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007040 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7041#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7042 params->channel, params->channel_type);
7043#else
7044 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7045#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007046#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007047 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
7048 params->ssid_len, params->hidden_ssid);
7049 }
7050
7051 EXIT();
7052 return status;
7053}
7054
7055
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307056static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007057 struct net_device *dev,
7058 struct cfg80211_beacon_data *params)
7059{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307060 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307061 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307062 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007063
7064 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307065
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307066 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7067 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7068 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007069 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007070 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307071
7072 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7073 status = wlan_hdd_validate_context(pHddCtx);
7074
7075 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007076 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307077 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7078 "%s: HDD context is not valid", __func__);
7079 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007080 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007081
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307082 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007083 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307084 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007085 {
7086 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307087
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007088 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307089
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007090 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307091 {
7092 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7093 FL("session(%d) beacon data points to NULL"),
7094 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007095 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307096 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007097
7098 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
7099
7100 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307101 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007102 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007103 return -EINVAL;
7104 }
7105
7106 pAdapter->sessionCtx.ap.beacon = new;
7107
7108 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
7109 }
7110
7111 EXIT();
7112 return status;
7113}
7114
7115#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7116
Jeff Johnson295189b2012-06-20 16:38:30 -07007117
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307118static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007119 struct net_device *dev,
7120 struct bss_parameters *params)
7121{
7122 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7123
7124 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307125
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307126 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7127 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
7128 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307129 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7130 __func__, hdd_device_modetoString(pAdapter->device_mode),
7131 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007132
7133 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007134 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307135 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007136 {
7137 /* ap_isolate == -1 means that in change bss, upper layer doesn't
7138 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307139 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07007140 {
7141 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307142 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007143 }
7144
7145 EXIT();
7146 return 0;
7147}
7148
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307149static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
7150 struct net_device *dev,
7151 struct bss_parameters *params)
7152{
7153 int ret;
7154
7155 vos_ssr_protect(__func__);
7156 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
7157 vos_ssr_unprotect(__func__);
7158
7159 return ret;
7160}
Kiet Lam10841362013-11-01 11:36:50 +05307161/* FUNCTION: wlan_hdd_change_country_code_cd
7162* to wait for contry code completion
7163*/
7164void* wlan_hdd_change_country_code_cb(void *pAdapter)
7165{
7166 hdd_adapter_t *call_back_pAdapter = pAdapter;
7167 complete(&call_back_pAdapter->change_country_code);
7168 return NULL;
7169}
7170
Jeff Johnson295189b2012-06-20 16:38:30 -07007171/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307172 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07007173 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
7174 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307175int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007176 struct net_device *ndev,
7177 enum nl80211_iftype type,
7178 u32 *flags,
7179 struct vif_params *params
7180 )
7181{
7182 struct wireless_dev *wdev;
7183 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007184 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07007185 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007186 tCsrRoamProfile *pRoamProfile = NULL;
7187 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307188 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007189 eMib_dot11DesiredBssType connectedBssType;
7190 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307191 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007192
7193 ENTER();
7194
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307195 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007196 {
7197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7198 "%s: Adapter context is null", __func__);
7199 return VOS_STATUS_E_FAILURE;
7200 }
7201
7202 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7203 if (!pHddCtx)
7204 {
7205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7206 "%s: HDD context is null", __func__);
7207 return VOS_STATUS_E_FAILURE;
7208 }
7209
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307210 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7211 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
7212 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307213 status = wlan_hdd_validate_context(pHddCtx);
7214
7215 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007216 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307217 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7218 "%s: HDD context is not valid", __func__);
7219 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007220 }
7221
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307222 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7223 __func__, hdd_device_modetoString(pAdapter->device_mode),
7224 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007225
Agarwal Ashish51325b52014-06-16 16:50:49 +05307226 if (vos_max_concurrent_connections_reached()) {
7227 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7228 return -EINVAL;
7229 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307230 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007231 wdev = ndev->ieee80211_ptr;
7232
7233#ifdef WLAN_BTAMP_FEATURE
7234 if((NL80211_IFTYPE_P2P_CLIENT == type)||
7235 (NL80211_IFTYPE_ADHOC == type)||
7236 (NL80211_IFTYPE_AP == type)||
7237 (NL80211_IFTYPE_P2P_GO == type))
7238 {
7239 pHddCtx->isAmpAllowed = VOS_FALSE;
7240 // stop AMP traffic
7241 status = WLANBAP_StopAmp();
7242 if(VOS_STATUS_SUCCESS != status )
7243 {
7244 pHddCtx->isAmpAllowed = VOS_TRUE;
7245 hddLog(VOS_TRACE_LEVEL_FATAL,
7246 "%s: Failed to stop AMP", __func__);
7247 return -EINVAL;
7248 }
7249 }
7250#endif //WLAN_BTAMP_FEATURE
7251 /* Reset the current device mode bit mask*/
7252 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7253
7254 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007255 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07007256 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07007257 )
7258 {
7259 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007260 if (!pWextState)
7261 {
7262 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7263 "%s: pWextState is null", __func__);
7264 return VOS_STATUS_E_FAILURE;
7265 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007266 pRoamProfile = &pWextState->roamProfile;
7267 LastBSSType = pRoamProfile->BSSType;
7268
7269 switch (type)
7270 {
7271 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007272 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007273 hddLog(VOS_TRACE_LEVEL_INFO,
7274 "%s: setting interface Type to INFRASTRUCTURE", __func__);
7275 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07007276#ifdef WLAN_FEATURE_11AC
7277 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
7278 {
7279 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
7280 }
7281#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307282 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07007283 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007284 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007285 //Check for sub-string p2p to confirm its a p2p interface
7286 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307287 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007288 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7289 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7290 }
7291 else
7292 {
7293 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007294 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007295 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05307296#ifdef FEATURE_WLAN_TDLS
7297 /* The open adapter for the p2p shall skip initializations in
7298 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
7299 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
7300 * tdls_init when the change_iface sets the device mode to
7301 * WLAN_HDD_P2P_CLIENT.
7302 */
7303
7304 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
7305 {
Agarwal Ashish4b87f922014-06-18 03:03:21 +05307306 if (0 != wlan_hdd_sta_tdls_init (pAdapter))
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05307307 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307308 hddLog(VOS_TRACE_LEVEL_ERROR,
7309 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05307310 return -EINVAL;
7311 }
7312 }
7313#endif
7314
Jeff Johnson295189b2012-06-20 16:38:30 -07007315 break;
7316 case NL80211_IFTYPE_ADHOC:
7317 hddLog(VOS_TRACE_LEVEL_INFO,
7318 "%s: setting interface Type to ADHOC", __func__);
7319 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
7320 pRoamProfile->phyMode =
7321 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07007322 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007323 wdev->iftype = type;
7324 break;
7325
7326 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007327 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007328 {
7329 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7330 "%s: setting interface Type to %s", __func__,
7331 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
7332
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007333 //Cancel any remain on channel for GO mode
7334 if (NL80211_IFTYPE_P2P_GO == type)
7335 {
7336 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
7337 }
Mohit Khanna0f232092012-09-11 14:46:08 -07007338 if (NL80211_IFTYPE_AP == type)
7339 {
7340 /* As Loading WLAN Driver one interface being created for p2p device
7341 * address. This will take one HW STA and the max number of clients
7342 * that can connect to softAP will be reduced by one. so while changing
7343 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
7344 * interface as it is not required in SoftAP mode.
7345 */
7346
7347 // Get P2P Adapter
7348 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
7349
7350 if (pP2pAdapter)
7351 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307352 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07007353 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
7354 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
7355 }
7356 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05307357 //Disable IMPS & BMPS for SAP/GO
7358 if(VOS_STATUS_E_FAILURE ==
7359 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
7360 {
7361 //Fail to Exit BMPS
7362 VOS_ASSERT(0);
7363 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05307364
7365 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
7366
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307367#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07007368
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307369 /* A Mutex Lock is introduced while changing the mode to
7370 * protect the concurrent access for the Adapters by TDLS
7371 * module.
7372 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307373 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307374#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007375 //De-init the adapter.
Jeff Johnson295189b2012-06-20 16:38:30 -07007376 hdd_deinit_adapter( pHddCtx, pAdapter );
7377 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07007378 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7379 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307380#ifdef FEATURE_WLAN_TDLS
7381 mutex_unlock(&pHddCtx->tdls_lock);
7382#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007383 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
7384 (pConfig->apRandomBssidEnabled))
7385 {
7386 /* To meet Android requirements create a randomized
7387 MAC address of the form 02:1A:11:Fx:xx:xx */
7388 get_random_bytes(&ndev->dev_addr[3], 3);
7389 ndev->dev_addr[0] = 0x02;
7390 ndev->dev_addr[1] = 0x1A;
7391 ndev->dev_addr[2] = 0x11;
7392 ndev->dev_addr[3] |= 0xF0;
7393 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
7394 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08007395 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
7396 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007397 }
7398
Jeff Johnson295189b2012-06-20 16:38:30 -07007399 hdd_set_ap_ops( pAdapter->dev );
7400
Kiet Lam10841362013-11-01 11:36:50 +05307401 /* This is for only SAP mode where users can
7402 * control country through ini.
7403 * P2P GO follows station country code
7404 * acquired during the STA scanning. */
7405 if((NL80211_IFTYPE_AP == type) &&
7406 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
7407 {
7408 int status = 0;
7409 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
7410 "%s: setting country code from INI ", __func__);
7411 init_completion(&pAdapter->change_country_code);
7412 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
7413 (void *)(tSmeChangeCountryCallback)
7414 wlan_hdd_change_country_code_cb,
7415 pConfig->apCntryCode, pAdapter,
7416 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05307417 eSIR_FALSE,
7418 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05307419 if (eHAL_STATUS_SUCCESS == status)
7420 {
7421 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307422 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05307423 &pAdapter->change_country_code,
7424 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307425 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05307426 {
7427 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307428 FL("SME Timed out while setting country code %ld"),
7429 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08007430
7431 if (pHddCtx->isLogpInProgress)
7432 {
7433 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7434 "%s: LOGP in Progress. Ignore!!!", __func__);
7435 return -EAGAIN;
7436 }
Kiet Lam10841362013-11-01 11:36:50 +05307437 }
7438 }
7439 else
7440 {
7441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007442 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05307443 return -EINVAL;
7444 }
7445 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007446 status = hdd_init_ap_mode(pAdapter);
7447 if(status != VOS_STATUS_SUCCESS)
7448 {
7449 hddLog(VOS_TRACE_LEVEL_FATAL,
7450 "%s: Error initializing the ap mode", __func__);
7451 return -EINVAL;
7452 }
7453 hdd_set_conparam(1);
7454
Jeff Johnson295189b2012-06-20 16:38:30 -07007455 /*interface type changed update in wiphy structure*/
7456 if(wdev)
7457 {
7458 wdev->iftype = type;
7459 pHddCtx->change_iface = type;
7460 }
7461 else
7462 {
7463 hddLog(VOS_TRACE_LEVEL_ERROR,
7464 "%s: ERROR !!!! Wireless dev is NULL", __func__);
7465 return -EINVAL;
7466 }
7467 goto done;
7468 }
7469
7470 default:
7471 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7472 __func__);
7473 return -EOPNOTSUPP;
7474 }
7475 }
7476 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007477 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007478 )
7479 {
7480 switch(type)
7481 {
7482 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007483 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007484 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05307485
7486 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307487#ifdef FEATURE_WLAN_TDLS
7488
7489 /* A Mutex Lock is introduced while changing the mode to
7490 * protect the concurrent access for the Adapters by TDLS
7491 * module.
7492 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307493 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307494#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07007495 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007496 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007497 //Check for sub-string p2p to confirm its a p2p interface
7498 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007499 {
7500 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7501 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7502 }
7503 else
7504 {
7505 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007506 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007507 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007508 hdd_set_conparam(0);
7509 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007510 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
7511 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307512#ifdef FEATURE_WLAN_TDLS
7513 mutex_unlock(&pHddCtx->tdls_lock);
7514#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05307515 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007516 if( VOS_STATUS_SUCCESS != status )
7517 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07007518 /* In case of JB, for P2P-GO, only change interface will be called,
7519 * This is the right place to enable back bmps_imps()
7520 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307521 if (pHddCtx->hdd_wlan_suspended)
7522 {
7523 hdd_set_pwrparams(pHddCtx);
7524 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007525 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007526 goto done;
7527 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007528 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007529 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007530 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7531 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007532 goto done;
7533 default:
7534 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7535 __func__);
7536 return -EOPNOTSUPP;
7537
7538 }
7539
7540 }
7541 else
7542 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307543 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
7544 __func__, hdd_device_modetoString(pAdapter->device_mode),
7545 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007546 return -EOPNOTSUPP;
7547 }
7548
7549
7550 if(pRoamProfile)
7551 {
7552 if ( LastBSSType != pRoamProfile->BSSType )
7553 {
7554 /*interface type changed update in wiphy structure*/
7555 wdev->iftype = type;
7556
7557 /*the BSS mode changed, We need to issue disconnect
7558 if connected or in IBSS disconnect state*/
7559 if ( hdd_connGetConnectedBssType(
7560 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
7561 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
7562 {
7563 /*need to issue a disconnect to CSR.*/
7564 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7565 if( eHAL_STATUS_SUCCESS ==
7566 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
7567 pAdapter->sessionId,
7568 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
7569 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307570 ret = wait_for_completion_interruptible_timeout(
7571 &pAdapter->disconnect_comp_var,
7572 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7573 if (ret <= 0)
7574 {
7575 hddLog(VOS_TRACE_LEVEL_ERROR,
7576 FL("wait on disconnect_comp_var failed %ld"), ret);
7577 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007578 }
7579 }
7580 }
7581 }
7582
7583done:
7584 /*set bitmask based on updated value*/
7585 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07007586
7587 /* Only STA mode support TM now
7588 * all other mode, TM feature should be disabled */
7589 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
7590 (~VOS_STA & pHddCtx->concurrency_mode) )
7591 {
7592 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
7593 }
7594
Jeff Johnson295189b2012-06-20 16:38:30 -07007595#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307596 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05307597 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07007598 {
7599 //we are ok to do AMP
7600 pHddCtx->isAmpAllowed = VOS_TRUE;
7601 }
7602#endif //WLAN_BTAMP_FEATURE
7603 EXIT();
7604 return 0;
7605}
7606
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307607/*
7608 * FUNCTION: wlan_hdd_cfg80211_change_iface
7609 * wrapper function to protect the actual implementation from SSR.
7610 */
7611int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
7612 struct net_device *ndev,
7613 enum nl80211_iftype type,
7614 u32 *flags,
7615 struct vif_params *params
7616 )
7617{
7618 int ret;
7619
7620 vos_ssr_protect(__func__);
7621 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
7622 vos_ssr_unprotect(__func__);
7623
7624 return ret;
7625}
7626
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007627#ifdef FEATURE_WLAN_TDLS
7628static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
7629 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
7630{
7631 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7632 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7633 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007634 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307635 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307636 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007637
7638 ENTER();
7639
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307640 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007641 {
7642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7643 "Invalid arguments");
7644 return -EINVAL;
7645 }
Hoonki Lee27511902013-03-14 18:19:06 -07007646
7647 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
7648 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
7649 {
7650 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7651 "%s: TDLS mode is disabled OR not enabled in FW."
7652 MAC_ADDRESS_STR " Request declined.",
7653 __func__, MAC_ADDR_ARRAY(mac));
7654 return -ENOTSUPP;
7655 }
7656
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007657 if (pHddCtx->isLogpInProgress)
7658 {
7659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7660 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05307661 wlan_hdd_tdls_set_link_status(pAdapter,
7662 mac,
7663 eTDLS_LINK_IDLE,
7664 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007665 return -EBUSY;
7666 }
7667
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05307668 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007669
7670 if ( NULL == pTdlsPeer ) {
7671 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7672 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
7673 __func__, MAC_ADDR_ARRAY(mac), update);
7674 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007675 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007676
7677 /* in add station, we accept existing valid staId if there is */
7678 if ((0 == update) &&
7679 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
7680 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007681 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007682 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007683 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007684 " link_status %d. staId %d. add station ignored.",
7685 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
7686 return 0;
7687 }
7688 /* in change station, we accept only when staId is valid */
7689 if ((1 == update) &&
7690 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
7691 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
7692 {
7693 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7694 "%s: " MAC_ADDRESS_STR
7695 " link status %d. staId %d. change station %s.",
7696 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
7697 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
7698 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007699 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007700
7701 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307702 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007703 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7705 "%s: " MAC_ADDRESS_STR
7706 " TDLS setup is ongoing. Request declined.",
7707 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07007708 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007709 }
7710
7711 /* first to check if we reached to maximum supported TDLS peer.
7712 TODO: for now, return -EPERM looks working fine,
7713 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307714 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
7715 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007716 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007717 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7718 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307719 " TDLS Max peer already connected. Request declined."
7720 " Num of peers (%d), Max allowed (%d).",
7721 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
7722 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007723 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007724 }
7725 else
7726 {
7727 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307728 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007729 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007730 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007731 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7732 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
7733 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007734 return -EPERM;
7735 }
7736 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007737 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05307738 wlan_hdd_tdls_set_link_status(pAdapter,
7739 mac,
7740 eTDLS_LINK_CONNECTING,
7741 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007742
Jeff Johnsond75fe012013-04-06 10:53:06 -07007743 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307744 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007745 {
7746 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7747 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007748 if(StaParams->htcap_present)
7749 {
7750 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7751 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
7752 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7753 "ht_capa->extended_capabilities: %0x",
7754 StaParams->HTCap.extendedHtCapInfo);
7755 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007756 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7757 "params->capability: %0x",StaParams->capability);
7758 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007759 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007760 if(StaParams->vhtcap_present)
7761 {
7762 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7763 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
7764 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
7765 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
7766 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007767 {
7768 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007770 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
7771 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7772 "[%d]: %x ", i, StaParams->supported_rates[i]);
7773 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07007774 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307775 else if ((1 == update) && (NULL == StaParams))
7776 {
7777 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7778 "%s : update is true, but staParams is NULL. Error!", __func__);
7779 return -EPERM;
7780 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007781
7782 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
7783
7784 if (!update)
7785 {
7786 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7787 pAdapter->sessionId, mac);
7788 }
7789 else
7790 {
7791 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7792 pAdapter->sessionId, mac, StaParams);
7793 }
7794
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307795 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007796 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
7797
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307798 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007799 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007800 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307801 "%s: timeout waiting for tdls add station indication %ld",
7802 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007803 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007804 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307805
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007806 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
7807 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007809 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007810 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007811 }
7812
7813 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007814
7815error:
Atul Mittal115287b2014-07-08 13:26:33 +05307816 wlan_hdd_tdls_set_link_status(pAdapter,
7817 mac,
7818 eTDLS_LINK_IDLE,
7819 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007820 return -EPERM;
7821
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007822}
7823#endif
7824
Jeff Johnson295189b2012-06-20 16:38:30 -07007825static int wlan_hdd_change_station(struct wiphy *wiphy,
7826 struct net_device *dev,
7827 u8 *mac,
7828 struct station_parameters *params)
7829{
7830 VOS_STATUS status = VOS_STATUS_SUCCESS;
7831 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05307832 hdd_context_t *pHddCtx;
7833 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007834 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007835#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007836 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007837 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307838 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007839#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007840 ENTER();
7841
Gopichand Nakkala29149562013-05-10 21:43:41 +05307842 if ((NULL == pAdapter))
7843 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05307845 "invalid adapter ");
7846 return -EINVAL;
7847 }
7848
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307849 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7850 TRACE_CODE_HDD_CHANGE_STATION,
7851 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05307852 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7853 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7854
7855 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
7856 {
7857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7858 "invalid HDD state or HDD station context");
7859 return -EINVAL;
7860 }
7861
7862 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007863 {
7864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7865 "%s:LOGP in Progress. Ignore!!!", __func__);
7866 return -EAGAIN;
7867 }
7868
Jeff Johnson295189b2012-06-20 16:38:30 -07007869 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
7870
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007871 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
7872 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07007873 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007874 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07007875 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307876 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07007877 WLANTL_STA_AUTHENTICATED);
7878
Gopichand Nakkala29149562013-05-10 21:43:41 +05307879 if (status != VOS_STATUS_SUCCESS)
7880 {
7881 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7882 "%s: Not able to change TL state to AUTHENTICATED", __func__);
7883 return -EINVAL;
7884 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007885 }
7886 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07007887 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
7888 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05307889#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007890 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
7891 StaParams.capability = params->capability;
7892 StaParams.uapsd_queues = params->uapsd_queues;
7893 StaParams.max_sp = params->max_sp;
7894
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307895 /* Convert (first channel , number of channels) tuple to
7896 * the total list of channels. This goes with the assumption
7897 * that if the first channel is < 14, then the next channels
7898 * are an incremental of 1 else an incremental of 4 till the number
7899 * of channels.
7900 */
7901 if (0 != params->supported_channels_len) {
7902 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
7903 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
7904 {
7905 int wifi_chan_index;
7906 StaParams.supported_channels[j] = params->supported_channels[i];
7907 wifi_chan_index =
7908 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
7909 no_of_channels = params->supported_channels[i+1];
7910 for(k=1; k <= no_of_channels; k++)
7911 {
7912 StaParams.supported_channels[j+1] =
7913 StaParams.supported_channels[j] + wifi_chan_index;
7914 j+=1;
7915 }
7916 }
7917 StaParams.supported_channels_len = j;
7918 }
7919 vos_mem_copy(StaParams.supported_oper_classes,
7920 params->supported_oper_classes,
7921 params->supported_oper_classes_len);
7922 StaParams.supported_oper_classes_len =
7923 params->supported_oper_classes_len;
7924
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007925 if (0 != params->ext_capab_len)
7926 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
7927 sizeof(StaParams.extn_capability));
7928
7929 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007930 {
7931 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007932 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007933 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007934
7935 StaParams.supported_rates_len = params->supported_rates_len;
7936
7937 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
7938 * The supported_rates array , for all the structures propogating till Add Sta
7939 * to the firmware has to be modified , if the supplicant (ieee80211) is
7940 * modified to send more rates.
7941 */
7942
7943 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
7944 */
7945 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
7946 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
7947
7948 if (0 != StaParams.supported_rates_len) {
7949 int i = 0;
7950 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
7951 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007952 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007953 "Supported Rates with Length %d", StaParams.supported_rates_len);
7954 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007956 "[%d]: %0x", i, StaParams.supported_rates[i]);
7957 }
7958
7959 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007960 {
7961 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007962 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007963 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007964
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007965 if (0 != params->ext_capab_len ) {
7966 /*Define A Macro : TODO Sunil*/
7967 if ((1<<4) & StaParams.extn_capability[3]) {
7968 isBufSta = 1;
7969 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307970 /* TDLS Channel Switching Support */
7971 if ((1<<6) & StaParams.extn_capability[3]) {
7972 isOffChannelSupported = 1;
7973 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007974 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307975 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
7976 &StaParams, isBufSta,
7977 isOffChannelSupported);
7978
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307979 if (VOS_STATUS_SUCCESS != status) {
7980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7981 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
7982 return -EINVAL;
7983 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007984 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
7985
7986 if (VOS_STATUS_SUCCESS != status) {
7987 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7988 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
7989 return -EINVAL;
7990 }
7991 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007992#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05307993 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007994 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007995 return status;
7996}
7997
7998/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307999 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008000 * This function is used to initialize the key information
8001 */
8002#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308003static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008004 struct net_device *ndev,
8005 u8 key_index, bool pairwise,
8006 const u8 *mac_addr,
8007 struct key_params *params
8008 )
8009#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308010static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008011 struct net_device *ndev,
8012 u8 key_index, const u8 *mac_addr,
8013 struct key_params *params
8014 )
8015#endif
8016{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008017 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07008018 tCsrRoamSetKey setKey;
8019 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308020 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008021 v_U32_t roamId= 0xFF;
8022 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008023 hdd_hostapd_state_t *pHostapdState;
8024 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008025 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308026 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008027
8028 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308029
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308030 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8031 TRACE_CODE_HDD_CFG80211_ADD_KEY,
8032 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308033 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8034 status = wlan_hdd_validate_context(pHddCtx);
8035
8036 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008037 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308038 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8039 "%s: HDD context is not valid", __func__);
8040 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008041 }
8042
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308043 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8044 __func__, hdd_device_modetoString(pAdapter->device_mode),
8045 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008046
8047 if (CSR_MAX_NUM_KEY <= key_index)
8048 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008049 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008050 key_index);
8051
8052 return -EINVAL;
8053 }
8054
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008055 if (CSR_MAX_KEY_LEN < params->key_len)
8056 {
8057 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
8058 params->key_len);
8059
8060 return -EINVAL;
8061 }
8062
8063 hddLog(VOS_TRACE_LEVEL_INFO,
8064 "%s: called with key index = %d & key length %d",
8065 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008066
8067 /*extract key idx, key len and key*/
8068 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8069 setKey.keyId = key_index;
8070 setKey.keyLength = params->key_len;
8071 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
8072
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008073 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07008074 {
8075 case WLAN_CIPHER_SUITE_WEP40:
8076 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
8077 break;
8078
8079 case WLAN_CIPHER_SUITE_WEP104:
8080 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
8081 break;
8082
8083 case WLAN_CIPHER_SUITE_TKIP:
8084 {
8085 u8 *pKey = &setKey.Key[0];
8086 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
8087
8088 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
8089
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008090 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07008091
8092 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008093 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008094 |--------------|----------|----------|
8095 <---16bytes---><--8bytes--><--8bytes-->
8096
8097 */
8098 /*Sme expects the 32 bytes key to be in the below order
8099
8100 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008101 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008102 |--------------|----------|----------|
8103 <---16bytes---><--8bytes--><--8bytes-->
8104 */
8105 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008106 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07008107
8108 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008109 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008110
8111 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008112 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008113
8114
8115 break;
8116 }
8117
8118 case WLAN_CIPHER_SUITE_CCMP:
8119 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
8120 break;
8121
8122#ifdef FEATURE_WLAN_WAPI
8123 case WLAN_CIPHER_SUITE_SMS4:
8124 {
8125 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8126 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
8127 params->key, params->key_len);
8128 return 0;
8129 }
8130#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008131
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008132#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07008133 case WLAN_CIPHER_SUITE_KRK:
8134 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
8135 break;
8136#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008137
8138#ifdef WLAN_FEATURE_11W
8139 case WLAN_CIPHER_SUITE_AES_CMAC:
8140 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07008141 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07008142#endif
8143
Jeff Johnson295189b2012-06-20 16:38:30 -07008144 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008145 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07008146 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308147 status = -EOPNOTSUPP;
8148 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008149 }
8150
8151 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
8152 __func__, setKey.encType);
8153
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008154 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07008155#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8156 (!pairwise)
8157#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008158 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07008159#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008160 )
8161 {
8162 /* set group key*/
8163 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8164 "%s- %d: setting Broadcast key",
8165 __func__, __LINE__);
8166 setKey.keyDirection = eSIR_RX_ONLY;
8167 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8168 }
8169 else
8170 {
8171 /* set pairwise key*/
8172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8173 "%s- %d: setting pairwise key",
8174 __func__, __LINE__);
8175 setKey.keyDirection = eSIR_TX_RX;
8176 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8177 }
8178 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
8179 {
8180 setKey.keyDirection = eSIR_TX_RX;
8181 /*Set the group key*/
8182 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8183 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07008184
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008185 if ( 0 != status )
8186 {
8187 hddLog(VOS_TRACE_LEVEL_ERROR,
8188 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308189 status = -EINVAL;
8190 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008191 }
8192 /*Save the keys here and call sme_RoamSetKey for setting
8193 the PTK after peer joins the IBSS network*/
8194 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
8195 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308196 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008197 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05308198 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
8199 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
8200 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008201 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008202 if( pHostapdState->bssState == BSS_START )
8203 {
c_hpothu7c55da62014-01-23 18:34:02 +05308204 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8205 vos_status = wlan_hdd_check_ula_done(pAdapter);
8206
8207 if ( vos_status != VOS_STATUS_SUCCESS )
8208 {
8209 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8210 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8211 __LINE__, vos_status );
8212
8213 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8214
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308215 status = -EINVAL;
8216 goto end;
c_hpothu7c55da62014-01-23 18:34:02 +05308217 }
8218
Jeff Johnson295189b2012-06-20 16:38:30 -07008219 status = WLANSAP_SetKeySta( pVosContext, &setKey);
8220
8221 if ( status != eHAL_STATUS_SUCCESS )
8222 {
8223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8224 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8225 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308226 status = -EINVAL;
8227 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008228 }
8229 }
8230
8231 /* Saving WEP keys */
8232 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
8233 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
8234 {
8235 //Save the wep key in ap context. Issue setkey after the BSS is started.
8236 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8237 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
8238 }
8239 else
8240 {
8241 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008242 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008243 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
8244 }
8245 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008246 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
8247 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008248 {
8249 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8250 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8251
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308252#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8253 if (!pairwise)
8254#else
8255 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8256#endif
8257 {
8258 /* set group key*/
8259 if (pHddStaCtx->roam_info.deferKeyComplete)
8260 {
8261 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8262 "%s- %d: Perform Set key Complete",
8263 __func__, __LINE__);
8264 hdd_PerformRoamSetKeyComplete(pAdapter);
8265 }
8266 }
8267
Jeff Johnson295189b2012-06-20 16:38:30 -07008268 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
8269
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08008270 pWextState->roamProfile.Keys.defaultIndex = key_index;
8271
8272
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008273 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008274 params->key, params->key_len);
8275
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308276
Jeff Johnson295189b2012-06-20 16:38:30 -07008277 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8278
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308279 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008280 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308281 __func__, setKey.peerMac[0], setKey.peerMac[1],
8282 setKey.peerMac[2], setKey.peerMac[3],
8283 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008284 setKey.keyDirection);
8285
8286 vos_status = wlan_hdd_check_ula_done(pAdapter);
8287
8288 if ( vos_status != VOS_STATUS_SUCCESS )
8289 {
8290 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8291 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8292 __LINE__, vos_status );
8293
8294 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8295
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308296 status = -EINVAL;
8297 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008298
8299 }
8300
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008301#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308302 /* The supplicant may attempt to set the PTK once pre-authentication
8303 is done. Save the key in the UMAC and include it in the ADD BSS
8304 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008305 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308306 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008307 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308308 hddLog(VOS_TRACE_LEVEL_INFO_MED,
8309 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308310 status = 0;
8311 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308312 }
8313 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
8314 {
8315 hddLog(VOS_TRACE_LEVEL_ERROR,
8316 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308317 status = -EINVAL;
8318 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008319 }
8320#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07008321
8322 /* issue set key request to SME*/
8323 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8324 pAdapter->sessionId, &setKey, &roamId );
8325
8326 if ( 0 != status )
8327 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308328 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008329 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
8330 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308331 status = -EINVAL;
8332 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008333 }
8334
8335
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308336 /* in case of IBSS as there was no information available about WEP keys during
8337 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07008338 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308339 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
8340 !( ( IW_AUTH_KEY_MGMT_802_1X
8341 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07008342 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
8343 )
8344 &&
8345 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
8346 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
8347 )
8348 )
8349 {
8350 setKey.keyDirection = eSIR_RX_ONLY;
8351 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8352
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308353 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008354 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308355 __func__, setKey.peerMac[0], setKey.peerMac[1],
8356 setKey.peerMac[2], setKey.peerMac[3],
8357 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008358 setKey.keyDirection);
8359
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308360 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008361 pAdapter->sessionId, &setKey, &roamId );
8362
8363 if ( 0 != status )
8364 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308365 hddLog(VOS_TRACE_LEVEL_ERROR,
8366 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008367 __func__, status);
8368 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308369 status = -EINVAL;
8370 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008371 }
8372 }
8373 }
8374
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308375end:
8376 /* Need to clear any trace of key value in the memory.
8377 * Thus zero out the memory even though it is local
8378 * variable.
8379 */
8380 vos_mem_zero(&setKey, sizeof(setKey));
8381
8382 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008383}
8384
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308385#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8386static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8387 struct net_device *ndev,
8388 u8 key_index, bool pairwise,
8389 const u8 *mac_addr,
8390 struct key_params *params
8391 )
8392#else
8393static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8394 struct net_device *ndev,
8395 u8 key_index, const u8 *mac_addr,
8396 struct key_params *params
8397 )
8398#endif
8399{
8400 int ret;
8401 vos_ssr_protect(__func__);
8402#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8403 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
8404 mac_addr, params);
8405#else
8406 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
8407 params);
8408#endif
8409 vos_ssr_unprotect(__func__);
8410
8411 return ret;
8412}
8413
Jeff Johnson295189b2012-06-20 16:38:30 -07008414/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308415 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008416 * This function is used to get the key information
8417 */
8418#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308419static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308420 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008421 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308422 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008423 const u8 *mac_addr, void *cookie,
8424 void (*callback)(void *cookie, struct key_params*)
8425 )
8426#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308427static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308428 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008429 struct net_device *ndev,
8430 u8 key_index, const u8 *mac_addr, void *cookie,
8431 void (*callback)(void *cookie, struct key_params*)
8432 )
8433#endif
8434{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308435 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308436 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8437 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Jeff Johnson295189b2012-06-20 16:38:30 -07008438 struct key_params params;
8439
8440 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308441
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308442 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8443 __func__, hdd_device_modetoString(pAdapter->device_mode),
8444 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308445
Jeff Johnson295189b2012-06-20 16:38:30 -07008446 memset(&params, 0, sizeof(params));
8447
8448 if (CSR_MAX_NUM_KEY <= key_index)
8449 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308450 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07008451 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308452 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008453
8454 switch(pRoamProfile->EncryptionType.encryptionType[0])
8455 {
8456 case eCSR_ENCRYPT_TYPE_NONE:
8457 params.cipher = IW_AUTH_CIPHER_NONE;
8458 break;
8459
8460 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
8461 case eCSR_ENCRYPT_TYPE_WEP40:
8462 params.cipher = WLAN_CIPHER_SUITE_WEP40;
8463 break;
8464
8465 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
8466 case eCSR_ENCRYPT_TYPE_WEP104:
8467 params.cipher = WLAN_CIPHER_SUITE_WEP104;
8468 break;
8469
8470 case eCSR_ENCRYPT_TYPE_TKIP:
8471 params.cipher = WLAN_CIPHER_SUITE_TKIP;
8472 break;
8473
8474 case eCSR_ENCRYPT_TYPE_AES:
8475 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
8476 break;
8477
8478 default:
8479 params.cipher = IW_AUTH_CIPHER_NONE;
8480 break;
8481 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308482
c_hpothuaaf19692014-05-17 17:01:48 +05308483 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8484 TRACE_CODE_HDD_CFG80211_GET_KEY,
8485 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308486
Jeff Johnson295189b2012-06-20 16:38:30 -07008487 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
8488 params.seq_len = 0;
8489 params.seq = NULL;
8490 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
8491 callback(cookie, &params);
8492 return 0;
8493}
8494
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308495#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8496static int wlan_hdd_cfg80211_get_key(
8497 struct wiphy *wiphy,
8498 struct net_device *ndev,
8499 u8 key_index, bool pairwise,
8500 const u8 *mac_addr, void *cookie,
8501 void (*callback)(void *cookie, struct key_params*)
8502 )
8503#else
8504static int wlan_hdd_cfg80211_get_key(
8505 struct wiphy *wiphy,
8506 struct net_device *ndev,
8507 u8 key_index, const u8 *mac_addr, void *cookie,
8508 void (*callback)(void *cookie, struct key_params*)
8509 )
8510#endif
8511{
8512 int ret;
8513
8514 vos_ssr_protect(__func__);
8515#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8516 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
8517 mac_addr, cookie, callback);
8518#else
8519 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
8520 callback);
8521#endif
8522 vos_ssr_unprotect(__func__);
8523
8524 return ret;
8525}
8526
Jeff Johnson295189b2012-06-20 16:38:30 -07008527/*
8528 * FUNCTION: wlan_hdd_cfg80211_del_key
8529 * This function is used to delete the key information
8530 */
8531#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308532static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008533 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308534 u8 key_index,
8535 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008536 const u8 *mac_addr
8537 )
8538#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308539static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008540 struct net_device *ndev,
8541 u8 key_index,
8542 const u8 *mac_addr
8543 )
8544#endif
8545{
8546 int status = 0;
8547
8548 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308549 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07008550 //it is observed that this is invalidating peer
8551 //key index whenever re-key is done. This is affecting data link.
8552 //It should be ok to ignore del_key.
8553#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308554 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
8555 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008556 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
8557 tCsrRoamSetKey setKey;
8558 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308559
Jeff Johnson295189b2012-06-20 16:38:30 -07008560 ENTER();
8561
8562 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
8563 __func__,pAdapter->device_mode);
8564
8565 if (CSR_MAX_NUM_KEY <= key_index)
8566 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308567 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008568 key_index);
8569
8570 return -EINVAL;
8571 }
8572
8573 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8574 setKey.keyId = key_index;
8575
8576 if (mac_addr)
8577 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8578 else
8579 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
8580
8581 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
8582
8583 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008584 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308585 )
8586 {
8587
8588 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07008589 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8590 if( pHostapdState->bssState == BSS_START)
8591 {
8592 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308593
Jeff Johnson295189b2012-06-20 16:38:30 -07008594 if ( status != eHAL_STATUS_SUCCESS )
8595 {
8596 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8597 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8598 __LINE__, status );
8599 }
8600 }
8601 }
8602 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308603 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07008604 )
8605 {
8606 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8607
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308608 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8609
8610 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008611 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308612 __func__, setKey.peerMac[0], setKey.peerMac[1],
8613 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07008614 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308615 if(pAdapter->sessionCtx.station.conn_info.connState ==
8616 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07008617 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308618 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008619 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308620
Jeff Johnson295189b2012-06-20 16:38:30 -07008621 if ( 0 != status )
8622 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308623 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008624 "%s: sme_RoamSetKey failure, returned %d",
8625 __func__, status);
8626 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8627 return -EINVAL;
8628 }
8629 }
8630 }
8631#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008632 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008633 return status;
8634}
8635
8636/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308637 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008638 * This function is used to set the default tx key index
8639 */
8640#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308641static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008642 struct net_device *ndev,
8643 u8 key_index,
8644 bool unicast, bool multicast)
8645#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308646static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008647 struct net_device *ndev,
8648 u8 key_index)
8649#endif
8650{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308651 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308652 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308653 hdd_wext_state_t *pWextState;
8654 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308655 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008656
8657 ENTER();
8658
Gopichand Nakkala29149562013-05-10 21:43:41 +05308659 if ((NULL == pAdapter))
8660 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308662 "invalid adapter");
8663 return -EINVAL;
8664 }
8665
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308666 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8667 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
8668 pAdapter->sessionId, key_index));
8669
Gopichand Nakkala29149562013-05-10 21:43:41 +05308670 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8671 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8672
8673 if ((NULL == pWextState) || (NULL == pHddStaCtx))
8674 {
8675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8676 "invalid Wext state or HDD context");
8677 return -EINVAL;
8678 }
8679
Arif Hussain6d2a3322013-11-17 19:50:10 -08008680 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008681 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308682
Jeff Johnson295189b2012-06-20 16:38:30 -07008683 if (CSR_MAX_NUM_KEY <= key_index)
8684 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308685 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008686 key_index);
8687
8688 return -EINVAL;
8689 }
8690
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308691 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8692 status = wlan_hdd_validate_context(pHddCtx);
8693
8694 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008695 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8697 "%s: HDD context is not valid", __func__);
8698 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008699 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308700
Jeff Johnson295189b2012-06-20 16:38:30 -07008701 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008702 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308703 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008704 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308705 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08008706 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308707 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08008708 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07008709 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308710 {
8711 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07008712 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308713
Jeff Johnson295189b2012-06-20 16:38:30 -07008714 tCsrRoamSetKey setKey;
8715 v_U32_t roamId= 0xFF;
8716 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308717
8718 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008719 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308720
Jeff Johnson295189b2012-06-20 16:38:30 -07008721 Keys->defaultIndex = (u8)key_index;
8722 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8723 setKey.keyId = key_index;
8724 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308725
8726 vos_mem_copy(&setKey.Key[0],
8727 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008728 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308729
Gopichand Nakkala29149562013-05-10 21:43:41 +05308730 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308731
8732 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07008733 &pHddStaCtx->conn_info.bssId[0],
8734 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308735
Gopichand Nakkala29149562013-05-10 21:43:41 +05308736 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
8737 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
8738 eCSR_ENCRYPT_TYPE_WEP104)
8739 {
8740 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
8741 even though ap is configured for WEP-40 encryption. In this canse the key length
8742 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
8743 type(104) and switching encryption type to 40*/
8744 pWextState->roamProfile.EncryptionType.encryptionType[0] =
8745 eCSR_ENCRYPT_TYPE_WEP40;
8746 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
8747 eCSR_ENCRYPT_TYPE_WEP40;
8748 }
8749
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308750 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07008751 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308752
Jeff Johnson295189b2012-06-20 16:38:30 -07008753 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308754 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008755 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308756
Jeff Johnson295189b2012-06-20 16:38:30 -07008757 if ( 0 != status )
8758 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308759 hddLog(VOS_TRACE_LEVEL_ERROR,
8760 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008761 status);
8762 return -EINVAL;
8763 }
8764 }
8765 }
8766
8767 /* In SoftAp mode setting key direction for default mode */
8768 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
8769 {
8770 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
8771 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
8772 (eCSR_ENCRYPT_TYPE_AES !=
8773 pWextState->roamProfile.EncryptionType.encryptionType[0])
8774 )
8775 {
8776 /* Saving key direction for default key index to TX default */
8777 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8778 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
8779 }
8780 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308781
Jeff Johnson295189b2012-06-20 16:38:30 -07008782 return status;
8783}
8784
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308785#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8786static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8787 struct net_device *ndev,
8788 u8 key_index,
8789 bool unicast, bool multicast)
8790#else
8791static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8792 struct net_device *ndev,
8793 u8 key_index)
8794#endif
8795{
8796 int ret;
8797 vos_ssr_protect(__func__);
8798#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8799 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
8800 multicast);
8801#else
8802 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
8803#endif
8804 vos_ssr_unprotect(__func__);
8805
8806 return ret;
8807}
8808
Jeff Johnson295189b2012-06-20 16:38:30 -07008809/*
8810 * FUNCTION: wlan_hdd_cfg80211_inform_bss
8811 * This function is used to inform the BSS details to nl80211 interface.
8812 */
8813static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
8814 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
8815{
8816 struct net_device *dev = pAdapter->dev;
8817 struct wireless_dev *wdev = dev->ieee80211_ptr;
8818 struct wiphy *wiphy = wdev->wiphy;
8819 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
8820 int chan_no;
8821 int ie_length;
8822 const char *ie;
8823 unsigned int freq;
8824 struct ieee80211_channel *chan;
8825 int rssi = 0;
8826 struct cfg80211_bss *bss = NULL;
8827
8828 ENTER();
8829
8830 if( NULL == pBssDesc )
8831 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008832 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008833 return bss;
8834 }
8835
8836 chan_no = pBssDesc->channelId;
8837 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
8838 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
8839
8840 if( NULL == ie )
8841 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008842 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008843 return bss;
8844 }
8845
8846#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8847 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8848 {
8849 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8850 }
8851 else
8852 {
8853 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8854 }
8855#else
8856 freq = ieee80211_channel_to_frequency(chan_no);
8857#endif
8858
8859 chan = __ieee80211_get_channel(wiphy, freq);
8860
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05308861 if (!chan) {
8862 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
8863 return NULL;
8864 }
8865
Abhishek Singhaee43942014-06-16 18:55:47 +05308866 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07008867
Abhishek Singhaee43942014-06-16 18:55:47 +05308868 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308869 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07008870 pBssDesc->capabilityInfo,
8871 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05308872 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07008873}
8874
8875
8876
8877/*
8878 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
8879 * This function is used to inform the BSS details to nl80211 interface.
8880 */
8881struct cfg80211_bss*
8882wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
8883 tSirBssDescription *bss_desc
8884 )
8885{
8886 /*
8887 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
8888 already exists in bss data base of cfg80211 for that particular BSS ID.
8889 Using cfg80211_inform_bss_frame to update the bss entry instead of
8890 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
8891 now there is no possibility to get the mgmt(probe response) frame from PE,
8892 converting bss_desc to ieee80211_mgmt(probe response) and passing to
8893 cfg80211_inform_bss_frame.
8894 */
8895 struct net_device *dev = pAdapter->dev;
8896 struct wireless_dev *wdev = dev->ieee80211_ptr;
8897 struct wiphy *wiphy = wdev->wiphy;
8898 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008899#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8900 qcom_ie_age *qie_age = NULL;
8901 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
8902#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008903 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008904#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008905 const char *ie =
8906 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
8907 unsigned int freq;
8908 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05308909 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008910 struct cfg80211_bss *bss_status = NULL;
8911 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
8912 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07008913 hdd_context_t *pHddCtx;
8914 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07008915#ifdef WLAN_OPEN_SOURCE
8916 struct timespec ts;
8917#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008918
Wilson Yangf80a0542013-10-07 13:02:37 -07008919 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8920 status = wlan_hdd_validate_context(pHddCtx);
8921
8922 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308923 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008924 {
8925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8926 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8927 return NULL;
8928 }
8929
8930
8931 if (0 != status)
8932 {
8933 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8934 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008935 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008936 }
8937
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05308938 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07008939 if (!mgmt)
8940 {
8941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8942 "%s: memory allocation failed ", __func__);
8943 return NULL;
8944 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008945
Jeff Johnson295189b2012-06-20 16:38:30 -07008946 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07008947
8948#ifdef WLAN_OPEN_SOURCE
8949 /* Android does not want the timestamp from the frame.
8950 Instead it wants a monotonic increasing value */
8951 get_monotonic_boottime(&ts);
8952 mgmt->u.probe_resp.timestamp =
8953 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
8954#else
8955 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07008956 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
8957 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07008958
8959#endif
8960
Jeff Johnson295189b2012-06-20 16:38:30 -07008961 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
8962 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008963
8964#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8965 /* GPS Requirement: need age ie per entry. Using vendor specific. */
8966 /* Assuming this is the last IE, copy at the end */
8967 ie_length -=sizeof(qcom_ie_age);
8968 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
8969 qie_age->element_id = QCOM_VENDOR_IE_ID;
8970 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
8971 qie_age->oui_1 = QCOM_OUI1;
8972 qie_age->oui_2 = QCOM_OUI2;
8973 qie_age->oui_3 = QCOM_OUI3;
8974 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
8975 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
8976#endif
8977
Jeff Johnson295189b2012-06-20 16:38:30 -07008978 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05308979 if (bss_desc->fProbeRsp)
8980 {
8981 mgmt->frame_control |=
8982 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
8983 }
8984 else
8985 {
8986 mgmt->frame_control |=
8987 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
8988 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008989
8990#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308991 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008992 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
8993 {
8994 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8995 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308996 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008997 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
8998
8999 {
9000 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9001 }
9002 else
9003 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309004 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
9005 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07009006 kfree(mgmt);
9007 return NULL;
9008 }
9009#else
9010 freq = ieee80211_channel_to_frequency(chan_no);
9011#endif
9012 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009013 /*when the band is changed on the fly using the GUI, three things are done
9014 * 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)
9015 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
9016 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
9017 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
9018 * and discards the channels correponding to previous band and calls back with zero bss results.
9019 * 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
9020 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
9021 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
9022 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
9023 * So drop the bss and continue to next bss.
9024 */
9025 if(chan == NULL)
9026 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309027 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07009028 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009029 return NULL;
9030 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009031 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309032 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07009033 * */
9034 if (( eConnectionState_Associated ==
9035 pAdapter->sessionCtx.station.conn_info.connState ) &&
9036 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
9037 pAdapter->sessionCtx.station.conn_info.bssId,
9038 WNI_CFG_BSSID_LEN)))
9039 {
9040 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
9041 rssi = (pAdapter->rssi * 100);
9042 }
9043 else
9044 {
9045 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
9046 }
9047
Nirav Shah20ac06f2013-12-12 18:14:06 +05309048 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
9049 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
9050 chan->center_freq, (int)(rssi/100));
9051
Jeff Johnson295189b2012-06-20 16:38:30 -07009052 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
9053 frame_len, rssi, GFP_KERNEL);
9054 kfree(mgmt);
9055 return bss_status;
9056}
9057
9058/*
9059 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
9060 * This function is used to update the BSS data base of CFG8011
9061 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309062struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009063 tCsrRoamInfo *pRoamInfo
9064 )
9065{
9066 tCsrRoamConnectedProfile roamProfile;
9067 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9068 struct cfg80211_bss *bss = NULL;
9069
9070 ENTER();
9071
9072 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
9073 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
9074
9075 if (NULL != roamProfile.pBssDesc)
9076 {
Girish Gowlif4b68022014-08-28 23:18:57 +05309077 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9078 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009079
9080 if (NULL == bss)
9081 {
9082 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
9083 __func__);
9084 }
9085
9086 sme_RoamFreeConnectProfile(hHal, &roamProfile);
9087 }
9088 else
9089 {
9090 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
9091 __func__);
9092 }
9093 return bss;
9094}
9095
9096/*
9097 * FUNCTION: wlan_hdd_cfg80211_update_bss
9098 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309099static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
9100 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07009101 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309102{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309103 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009104 tCsrScanResultInfo *pScanResult;
9105 eHalStatus status = 0;
9106 tScanResultHandle pResult;
9107 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009108 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009109
9110 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309111
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309112 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9113 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
9114 NO_SESSION, pAdapter->sessionId));
9115
Wilson Yangf80a0542013-10-07 13:02:37 -07009116 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9117
9118 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009119 {
Wilson Yangf80a0542013-10-07 13:02:37 -07009120 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9121 "%s:LOGP in Progress. Ignore!!!",__func__);
9122 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009123 }
9124
Wilson Yangf80a0542013-10-07 13:02:37 -07009125
9126 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309127 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009128 {
9129 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9130 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9131 return VOS_STATUS_E_PERM;
9132 }
9133
9134
Jeff Johnson295189b2012-06-20 16:38:30 -07009135 /*
9136 * start getting scan results and populate cgf80211 BSS database
9137 */
9138 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
9139
9140 /* no scan results */
9141 if (NULL == pResult)
9142 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309143 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
9144 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009145 return status;
9146 }
9147
9148 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
9149
9150 while (pScanResult)
9151 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309152 /*
9153 * cfg80211_inform_bss() is not updating ie field of bss entry, if
9154 * entry already exists in bss data base of cfg80211 for that
9155 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
9156 * bss entry instead of cfg80211_inform_bss, But this call expects
9157 * mgmt packet as input. As of now there is no possibility to get
9158 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07009159 * ieee80211_mgmt(probe response) and passing to c
9160 * fg80211_inform_bss_frame.
9161 * */
9162
9163 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9164 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309165
Jeff Johnson295189b2012-06-20 16:38:30 -07009166
9167 if (NULL == bss_status)
9168 {
9169 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009170 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009171 }
9172 else
9173 {
Yue Maf49ba872013-08-19 12:04:25 -07009174 cfg80211_put_bss(
9175#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
9176 wiphy,
9177#endif
9178 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009179 }
9180
9181 pScanResult = sme_ScanResultGetNext(hHal, pResult);
9182 }
9183
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309184 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07009185
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309186 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009187}
9188
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009189void
9190hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
9191{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309192 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08009193 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009194} /****** end hddPrintMacAddr() ******/
9195
9196void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009197hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009198{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309199 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009200 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009201 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
9202 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
9203 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009204} /****** end hddPrintPmkId() ******/
9205
9206//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
9207//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
9208
9209//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
9210//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
9211
9212#define dump_bssid(bssid) \
9213 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009214 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
9215 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009216 }
9217
9218#define dump_pmkid(pMac, pmkid) \
9219 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009220 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
9221 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009222 }
9223
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009224#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009225/*
9226 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
9227 * This function is used to notify the supplicant of a new PMKSA candidate.
9228 */
9229int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309230 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009231 int index, bool preauth )
9232{
Jeff Johnsone7245742012-09-05 17:12:55 -07009233#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009234 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009235 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009236
9237 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07009238 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009239
9240 if( NULL == pRoamInfo )
9241 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009242 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009243 return -EINVAL;
9244 }
9245
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009246 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
9247 {
9248 dump_bssid(pRoamInfo->bssid);
9249 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009250 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009251 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009252#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309253 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009254}
9255#endif //FEATURE_WLAN_LFR
9256
Yue Maef608272013-04-08 23:09:17 -07009257#ifdef FEATURE_WLAN_LFR_METRICS
9258/*
9259 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
9260 * 802.11r/LFR metrics reporting function to report preauth initiation
9261 *
9262 */
9263#define MAX_LFR_METRICS_EVENT_LENGTH 100
9264VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
9265 tCsrRoamInfo *pRoamInfo)
9266{
9267 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9268 union iwreq_data wrqu;
9269
9270 ENTER();
9271
9272 if (NULL == pAdapter)
9273 {
9274 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9275 return VOS_STATUS_E_FAILURE;
9276 }
9277
9278 /* create the event */
9279 memset(&wrqu, 0, sizeof(wrqu));
9280 memset(metrics_notification, 0, sizeof(metrics_notification));
9281
9282 wrqu.data.pointer = metrics_notification;
9283 wrqu.data.length = scnprintf(metrics_notification,
9284 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
9285 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9286
9287 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9288
9289 EXIT();
9290
9291 return VOS_STATUS_SUCCESS;
9292}
9293
9294/*
9295 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
9296 * 802.11r/LFR metrics reporting function to report preauth completion
9297 * or failure
9298 */
9299VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
9300 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
9301{
9302 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9303 union iwreq_data wrqu;
9304
9305 ENTER();
9306
9307 if (NULL == pAdapter)
9308 {
9309 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9310 return VOS_STATUS_E_FAILURE;
9311 }
9312
9313 /* create the event */
9314 memset(&wrqu, 0, sizeof(wrqu));
9315 memset(metrics_notification, 0, sizeof(metrics_notification));
9316
9317 scnprintf(metrics_notification, sizeof(metrics_notification),
9318 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
9319 MAC_ADDR_ARRAY(pRoamInfo->bssid));
9320
9321 if (1 == preauth_status)
9322 strncat(metrics_notification, " TRUE", 5);
9323 else
9324 strncat(metrics_notification, " FALSE", 6);
9325
9326 wrqu.data.pointer = metrics_notification;
9327 wrqu.data.length = strlen(metrics_notification);
9328
9329 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9330
9331 EXIT();
9332
9333 return VOS_STATUS_SUCCESS;
9334}
9335
9336/*
9337 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
9338 * 802.11r/LFR metrics reporting function to report handover initiation
9339 *
9340 */
9341VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
9342 tCsrRoamInfo *pRoamInfo)
9343{
9344 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9345 union iwreq_data wrqu;
9346
9347 ENTER();
9348
9349 if (NULL == pAdapter)
9350 {
9351 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9352 return VOS_STATUS_E_FAILURE;
9353 }
9354
9355 /* create the event */
9356 memset(&wrqu, 0, sizeof(wrqu));
9357 memset(metrics_notification, 0, sizeof(metrics_notification));
9358
9359 wrqu.data.pointer = metrics_notification;
9360 wrqu.data.length = scnprintf(metrics_notification,
9361 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
9362 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9363
9364 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9365
9366 EXIT();
9367
9368 return VOS_STATUS_SUCCESS;
9369}
9370#endif
9371
Jeff Johnson295189b2012-06-20 16:38:30 -07009372/*
9373 * FUNCTION: hdd_cfg80211_scan_done_callback
9374 * scanning callback function, called after finishing scan
9375 *
9376 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309377static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07009378 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
9379{
9380 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309381 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009382 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009383 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9384 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07009385 struct cfg80211_scan_request *req = NULL;
9386 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309387 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309388 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009389
9390 ENTER();
9391
9392 hddLog(VOS_TRACE_LEVEL_INFO,
9393 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08009394 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009395 __func__, halHandle, pContext, (int) scanId, (int) status);
9396
Kiet Lamac06e2c2013-10-23 16:25:07 +05309397 pScanInfo->mScanPendingCounter = 0;
9398
Jeff Johnson295189b2012-06-20 16:38:30 -07009399 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309400 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009401 &pScanInfo->scan_req_completion_event,
9402 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309403 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009404 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309405 hddLog(VOS_TRACE_LEVEL_ERROR,
9406 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07009407 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009408 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009409 }
9410
Yue Maef608272013-04-08 23:09:17 -07009411 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07009412 {
9413 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009414 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009415 }
9416
9417 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309418 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07009419 {
9420 hddLog(VOS_TRACE_LEVEL_INFO,
9421 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009422 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07009423 (int) scanId);
9424 }
9425
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309426 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009427 pAdapter);
9428
9429 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309430 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009431
9432
9433 /* If any client wait scan result through WEXT
9434 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009435 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07009436 {
9437 /* The other scan request waiting for current scan finish
9438 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009439 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009440 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009441 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07009442 }
9443 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009444 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009445 {
9446 struct net_device *dev = pAdapter->dev;
9447 union iwreq_data wrqu;
9448 int we_event;
9449 char *msg;
9450
9451 memset(&wrqu, '\0', sizeof(wrqu));
9452 we_event = SIOCGIWSCAN;
9453 msg = NULL;
9454 wireless_send_event(dev, we_event, &wrqu, msg);
9455 }
9456 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009457 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009458
9459 /* Get the Scan Req */
9460 req = pAdapter->request;
9461
9462 if (!req)
9463 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009464 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009465 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07009466 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009467 }
9468
9469 /*
9470 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309471 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009472 req->n_ssids = 0;
9473 req->n_channels = 0;
9474 req->ie = 0;
9475
Jeff Johnson295189b2012-06-20 16:38:30 -07009476 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009477 /* Scan is no longer pending */
9478 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009479
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07009480 /*
9481 * cfg80211_scan_done informing NL80211 about completion
9482 * of scanning
9483 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309484 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
9485 {
9486 aborted = true;
9487 }
9488 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009489 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07009490
Siddharth Bhal76972212014-10-15 16:22:51 +05309491 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
9492 /* Generate new random mac addr for next scan */
9493 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
9494 hdd_processSpoofMacAddrRequest(pHddCtx);
9495 }
9496
Jeff Johnsone7245742012-09-05 17:12:55 -07009497allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009498 /* release the wake lock at the end of the scan*/
9499 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009500
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009501 /* Acquire wakelock to handle the case where APP's tries to suspend
9502 * immediatly after the driver gets connect request(i.e after scan)
9503 * from supplicant, this result in app's is suspending and not able
9504 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309505 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009506
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009507#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05309508 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
9509 {
9510 wlan_hdd_tdls_scan_done_callback(pAdapter);
9511 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009512#endif
9513
Jeff Johnson295189b2012-06-20 16:38:30 -07009514 EXIT();
9515 return 0;
9516}
9517
9518/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05309519 * FUNCTION: hdd_isConnectionInProgress
9520 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009521 *
9522 */
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309523v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx, v_BOOL_t isRoC )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009524{
9525 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9526 hdd_station_ctx_t *pHddStaCtx = NULL;
9527 hdd_adapter_t *pAdapter = NULL;
9528 VOS_STATUS status = 0;
9529 v_U8_t staId = 0;
9530 v_U8_t *staMac = NULL;
9531
c_hpothu9b781ba2013-12-30 20:57:45 +05309532 if (TRUE == pHddCtx->btCoexModeSet)
9533 {
9534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05309535 FL("BTCoex Mode operation in progress"));
9536 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05309537 }
9538
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009539 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9540
9541 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9542 {
9543 pAdapter = pAdapterNode->pAdapter;
9544
9545 if( pAdapter )
9546 {
9547 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309548 "%s: Adapter with device mode %s (%d) exists",
9549 __func__, hdd_device_modetoString(pAdapter->device_mode),
9550 pAdapter->device_mode);
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309551 if ((((!isRoC) && (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +05309552 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9553 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
9554 (eConnectionState_Connecting ==
9555 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
9556 {
9557 hddLog(VOS_TRACE_LEVEL_ERROR,
9558 "%s: %p(%d) Connection is in progress", __func__,
9559 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
9560 return VOS_TRUE;
9561 }
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309562 if (((!isRoC) && (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309563 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9564 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009565 {
9566 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9567 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309568 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009569 {
9570 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
9571 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009572 "%s: client " MAC_ADDRESS_STR
9573 " is in the middle of WPS/EAPOL exchange.", __func__,
9574 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309575 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009576 }
9577 }
9578 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
9579 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
9580 {
9581 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
9582 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309583 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009584 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
9585 {
9586 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
9587
9588 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009589 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
9590 "middle of WPS/EAPOL exchange.", __func__,
9591 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309592 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009593 }
9594 }
9595 }
9596 }
9597 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9598 pAdapterNode = pNext;
9599 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05309600 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309601}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009602
9603/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309604 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07009605 * this scan respond to scan trigger and update cfg80211 scan database
9606 * later, scan dump command can be used to recieve scan results
9607 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309608int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009609#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9610 struct net_device *dev,
9611#endif
9612 struct cfg80211_scan_request *request)
9613{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309614 hdd_adapter_t *pAdapter = NULL;
9615 hdd_context_t *pHddCtx = NULL;
9616 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309617 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009618 tCsrScanRequest scanRequest;
9619 tANI_U8 *channelList = NULL, i;
9620 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309621 int status;
9622 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009623 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009624
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309625#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
9626 struct net_device *dev = NULL;
9627 if (NULL == request)
9628 {
9629 hddLog(VOS_TRACE_LEVEL_ERROR,
9630 "%s: scan req param null", __func__);
9631 return -EINVAL;
9632 }
9633 dev = request->wdev->netdev;
9634#endif
9635
9636 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
9637 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9638 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9639
Jeff Johnson295189b2012-06-20 16:38:30 -07009640 ENTER();
9641
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309642
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309643 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9644 __func__, hdd_device_modetoString(pAdapter->device_mode),
9645 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309646
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309647 status = wlan_hdd_validate_context(pHddCtx);
9648
9649 if (0 != status)
9650 {
9651 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9652 "%s: HDD context is not valid", __func__);
9653 return status;
9654 }
9655
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309656 if (NULL == pwextBuf)
9657 {
9658 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
9659 __func__);
9660 return -EIO;
9661 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309662 cfg_param = pHddCtx->cfg_ini;
9663 pScanInfo = &pHddCtx->scan_info;
9664
Jeff Johnson295189b2012-06-20 16:38:30 -07009665#ifdef WLAN_BTAMP_FEATURE
9666 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009667 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07009668 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009669 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009670 "%s: No scanning when AMP is on", __func__);
9671 return -EOPNOTSUPP;
9672 }
9673#endif
9674 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009675 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009676 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009677 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309678 "%s: Not scanning on device_mode = %s (%d)",
9679 __func__, hdd_device_modetoString(pAdapter->device_mode),
9680 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009681 return -EOPNOTSUPP;
9682 }
9683
9684 if (TRUE == pScanInfo->mScanPending)
9685 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309686 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
9687 {
9688 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
9689 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009690 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009691 }
9692
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309693 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07009694 //Channel and action frame is pending
9695 //Otherwise Cancel Remain On Channel and allow Scan
9696 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009697 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07009698 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309699 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009700 return -EBUSY;
9701 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009702#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009703 /* if tdls disagree scan right now, return immediately.
9704 tdls will schedule the scan when scan is allowed. (return SUCCESS)
9705 or will reject the scan if any TDLS is in progress. (return -EBUSY)
9706 */
9707 status = wlan_hdd_tdls_scan_callback (pAdapter,
9708 wiphy,
9709#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9710 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07009711#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009712 request);
9713 if(status <= 0)
9714 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309715 if(!status)
9716 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
9717 "scan rejected %d", __func__, status);
9718 else
9719 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
9720 __func__, status);
9721
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009722 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009723 }
9724#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07009725
Jeff Johnson295189b2012-06-20 16:38:30 -07009726 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
9727 {
9728 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08009729 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009730 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309731 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009732 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
9733 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309734 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009735 "%s: MAX TM Level Scan not allowed", __func__);
9736 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309737 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009738 }
9739 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
9740
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009741 /* Check if scan is allowed at this point of time.
9742 */
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309743 if (hdd_isConnectionInProgress(pHddCtx, VOS_FALSE))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009744 {
9745 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
9746 return -EBUSY;
9747 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309748
Jeff Johnson295189b2012-06-20 16:38:30 -07009749 vos_mem_zero( &scanRequest, sizeof(scanRequest));
9750
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309751 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
9752 (int)request->n_ssids);
9753
9754 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
9755 * Becasue of this, driver is assuming that this is not wildcard scan and so
9756 * is not aging out the scan results.
9757 */
9758 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07009759 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309760 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009761 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309762
9763 if ((request->ssids) && (0 < request->n_ssids))
9764 {
9765 tCsrSSIDInfo *SsidInfo;
9766 int j;
9767 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
9768 /* Allocate num_ssid tCsrSSIDInfo structure */
9769 SsidInfo = scanRequest.SSIDs.SSIDList =
9770 ( tCsrSSIDInfo *)vos_mem_malloc(
9771 request->n_ssids*sizeof(tCsrSSIDInfo));
9772
9773 if(NULL == scanRequest.SSIDs.SSIDList)
9774 {
9775 hddLog(VOS_TRACE_LEVEL_ERROR,
9776 "%s: memory alloc failed SSIDInfo buffer", __func__);
9777 return -ENOMEM;
9778 }
9779
9780 /* copy all the ssid's and their length */
9781 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
9782 {
9783 /* get the ssid length */
9784 SsidInfo->SSID.length = request->ssids[j].ssid_len;
9785 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
9786 SsidInfo->SSID.length);
9787 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
9788 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
9789 j, SsidInfo->SSID.ssId);
9790 }
9791 /* set the scan type to active */
9792 scanRequest.scanType = eSIR_ACTIVE_SCAN;
9793 }
9794 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07009795 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309796 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9797 TRACE_CODE_HDD_CFG80211_SCAN,
9798 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07009799 /* set the scan type to active */
9800 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009801 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309802 else
9803 {
9804 /*Set the scan type to default type, in this case it is ACTIVE*/
9805 scanRequest.scanType = pScanInfo->scan_mode;
9806 }
9807 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
9808 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07009809
9810 /* set BSSType to default type */
9811 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
9812
9813 /*TODO: scan the requested channels only*/
9814
9815 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309816 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -07009817 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309818 hddLog(VOS_TRACE_LEVEL_WARN,
9819 "No of Scan Channels exceeded limit: %d", request->n_channels);
9820 request->n_channels = MAX_CHANNEL;
9821 }
9822
9823 hddLog(VOS_TRACE_LEVEL_INFO,
9824 "No of Scan Channels: %d", request->n_channels);
9825
9826
9827 if( request->n_channels )
9828 {
9829 char chList [(request->n_channels*5)+1];
9830 int len;
9831 channelList = vos_mem_malloc( request->n_channels );
9832 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +05309833 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309834 hddLog(VOS_TRACE_LEVEL_ERROR,
9835 "%s: memory alloc failed channelList", __func__);
9836 status = -ENOMEM;
9837 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +05309838 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309839
9840 for( i = 0, len = 0; i < request->n_channels ; i++ )
9841 {
9842 channelList[i] = request->channels[i]->hw_value;
9843 len += snprintf(chList+len, 5, "%d ", channelList[i]);
9844 }
9845
Nirav Shah20ac06f2013-12-12 18:14:06 +05309846 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309847 "Channel-List: %s ", chList);
9848 }
c_hpothu53512302014-04-15 18:49:53 +05309849
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309850 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
9851 scanRequest.ChannelInfo.ChannelList = channelList;
9852
9853 /* set requestType to full scan */
9854 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
9855
9856 /* Flush the scan results(only p2p beacons) for STA scan and P2P
9857 * search (Flush on both full scan and social scan but not on single
9858 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
9859 */
9860
9861 /* Supplicant does single channel scan after 8-way handshake
9862 * and in that case driver shoudnt flush scan results. If
9863 * driver flushes the scan results here and unfortunately if
9864 * the AP doesnt respond to our probe req then association
9865 * fails which is not desired
9866 */
9867
9868 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
9869 {
9870 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
9871 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
9872 pAdapter->sessionId );
9873 }
9874
9875 if( request->ie_len )
9876 {
9877 /* save this for future association (join requires this) */
9878 /*TODO: Array needs to be converted to dynamic allocation,
9879 * as multiple ie.s can be sent in cfg80211_scan_request structure
9880 * CR 597966
9881 */
9882 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
9883 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
9884 pScanInfo->scanAddIE.length = request->ie_len;
9885
9886 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9887 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9888 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07009889 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309890 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -07009891 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309892 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
9893 memcpy( pwextBuf->roamProfile.addIEScan,
9894 request->ie, request->ie_len);
9895 }
9896 else
9897 {
9898 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
9899 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009900 }
9901
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309902 }
9903 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
9904 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
9905
9906 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
9907 request->ie_len);
9908 if (pP2pIe != NULL)
9909 {
9910#ifdef WLAN_FEATURE_P2P_DEBUG
9911 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
9912 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
9913 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +05309914 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309915 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
9916 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9917 "Go nego completed to Connection is started");
9918 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9919 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +05309920 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309921 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
9922 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07009923 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309924 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
9925 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9926 "Disconnected state to Connection is started");
9927 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9928 "for 4way Handshake");
9929 }
9930#endif
9931
9932 /* no_cck will be set during p2p find to disable 11b rates */
9933 if(TRUE == request->no_cck)
9934 {
9935 hddLog(VOS_TRACE_LEVEL_INFO,
9936 "%s: This is a P2P Search", __func__);
9937 scanRequest.p2pSearch = 1;
9938
9939 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +05309940 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309941 /* set requestType to P2P Discovery */
9942 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
9943 }
9944
9945 /*
9946 Skip Dfs Channel in case of P2P Search
9947 if it is set in ini file
9948 */
9949 if(cfg_param->skipDfsChnlInP2pSearch)
9950 {
9951 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309952 }
9953 else
9954 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309955 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309956 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009957
Agarwal Ashish4f616132013-12-30 23:32:50 +05309958 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009959 }
9960 }
9961
9962 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
9963
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009964 /* acquire the wakelock to avoid the apps suspend during the scan. To
9965 * address the following issues.
9966 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
9967 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
9968 * for long time, this result in apps running at full power for long time.
9969 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
9970 * be stuck in full power because of resume BMPS
9971 */
9972 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009973
Nirav Shah20ac06f2013-12-12 18:14:06 +05309974 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9975 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309976 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
9977 scanRequest.requestType, scanRequest.scanType,
9978 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05309979 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
9980
Siddharth Bhal76972212014-10-15 16:22:51 +05309981 if (pHddCtx->spoofMacAddr.isEnabled)
9982 {
9983 hddLog(VOS_TRACE_LEVEL_INFO,
9984 "%s: MAC Spoofing enabled for current scan", __func__);
9985 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
9986 * to fill TxBds for probe request during current scan
9987 */
9988 WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
9989 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
9990 }
9991
Jeff Johnsone7245742012-09-05 17:12:55 -07009992 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009993 pAdapter->sessionId, &scanRequest, &scanId,
9994 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07009995
Jeff Johnson295189b2012-06-20 16:38:30 -07009996 if (eHAL_STATUS_SUCCESS != status)
9997 {
9998 hddLog(VOS_TRACE_LEVEL_ERROR,
9999 "%s: sme_ScanRequest returned error %d", __func__, status);
10000 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010001 if(eHAL_STATUS_RESOURCES == status)
10002 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010003 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
10004 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010005 status = -EBUSY;
10006 } else {
10007 status = -EIO;
10008 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010009 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -070010010 goto free_mem;
10011 }
10012
10013 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010014 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070010015 pAdapter->request = request;
10016 pScanInfo->scanId = scanId;
10017
10018 complete(&pScanInfo->scan_req_completion_event);
10019
10020free_mem:
10021 if( scanRequest.SSIDs.SSIDList )
10022 {
10023 vos_mem_free(scanRequest.SSIDs.SSIDList);
10024 }
10025
10026 if( channelList )
10027 vos_mem_free( channelList );
10028
10029 EXIT();
10030
10031 return status;
10032}
10033
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010034int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
10035#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10036 struct net_device *dev,
10037#endif
10038 struct cfg80211_scan_request *request)
10039{
10040 int ret;
10041
10042 vos_ssr_protect(__func__);
10043 ret = __wlan_hdd_cfg80211_scan(wiphy,
10044#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10045 dev,
10046#endif
10047 request);
10048 vos_ssr_unprotect(__func__);
10049
10050 return ret;
10051}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010052
10053void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
10054{
10055 v_U8_t iniDot11Mode =
10056 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
10057 eHddDot11Mode hddDot11Mode = iniDot11Mode;
10058
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010059 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
10060 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010061 switch ( iniDot11Mode )
10062 {
10063 case eHDD_DOT11_MODE_AUTO:
10064 case eHDD_DOT11_MODE_11ac:
10065 case eHDD_DOT11_MODE_11ac_ONLY:
10066#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053010067 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
10068 sme_IsFeatureSupportedByFW(DOT11AC) )
10069 hddDot11Mode = eHDD_DOT11_MODE_11ac;
10070 else
10071 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010072#else
10073 hddDot11Mode = eHDD_DOT11_MODE_11n;
10074#endif
10075 break;
10076 case eHDD_DOT11_MODE_11n:
10077 case eHDD_DOT11_MODE_11n_ONLY:
10078 hddDot11Mode = eHDD_DOT11_MODE_11n;
10079 break;
10080 default:
10081 hddDot11Mode = iniDot11Mode;
10082 break;
10083 }
10084 /* This call decides required channel bonding mode */
10085 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
10086 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
10087 operationChannel);
10088}
10089
Jeff Johnson295189b2012-06-20 16:38:30 -070010090/*
10091 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010092 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010093 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010094int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010095 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010096{
10097 int status = 0;
10098 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080010099 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010100 v_U32_t roamId;
10101 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070010102 eCsrAuthType RSNAuthType;
10103
10104 ENTER();
10105
10106 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080010107 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10108
10109 status = wlan_hdd_validate_context(pHddCtx);
10110 if (status)
10111 {
10112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10113 "%s: HDD context is not valid!", __func__);
10114 return status;
10115 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010116
Jeff Johnson295189b2012-06-20 16:38:30 -070010117 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
10118 {
10119 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
10120 return -EINVAL;
10121 }
10122
10123 pRoamProfile = &pWextState->roamProfile;
10124
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010125 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070010126 {
Jeff Johnsone7245742012-09-05 17:12:55 -070010127 hdd_station_ctx_t *pHddStaCtx;
10128 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010129
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010130 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070010131 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
10132 {
10133 /*QoS not enabled in cfg file*/
10134 pRoamProfile->uapsd_mask = 0;
10135 }
10136 else
10137 {
10138 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010139 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070010140 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
10141 }
10142
10143 pRoamProfile->SSIDs.numOfSSIDs = 1;
10144 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
10145 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010146 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070010147 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
10148 ssid, ssid_len);
10149
10150 if (bssid)
10151 {
10152 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
10153 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
10154 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010155 /* Save BSSID in seperate variable as well, as RoamProfile
10156 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070010157 case of join failure we should send valid BSSID to supplicant
10158 */
10159 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
10160 WNI_CFG_BSSID_LEN);
10161 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070010162 else
10163 {
10164 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
10165 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010166
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010167 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
10168 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010169 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
10170 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010171 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010172 /*set gen ie*/
10173 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
10174 /*set auth*/
10175 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
10176 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010177#ifdef FEATURE_WLAN_WAPI
10178 if (pAdapter->wapi_info.nWapiMode)
10179 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010180 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010181 switch (pAdapter->wapi_info.wapiAuthMode)
10182 {
10183 case WAPI_AUTH_MODE_PSK:
10184 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010185 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010186 pAdapter->wapi_info.wapiAuthMode);
10187 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
10188 break;
10189 }
10190 case WAPI_AUTH_MODE_CERT:
10191 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010192 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010193 pAdapter->wapi_info.wapiAuthMode);
10194 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
10195 break;
10196 }
10197 } // End of switch
10198 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
10199 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
10200 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010201 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010202 pRoamProfile->AuthType.numEntries = 1;
10203 pRoamProfile->EncryptionType.numEntries = 1;
10204 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10205 pRoamProfile->mcEncryptionType.numEntries = 1;
10206 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10207 }
10208 }
10209#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010210#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010211 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010212 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10213 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
10214 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010215 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
10216 sizeof (tSirGtkOffloadParams));
10217 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010218 }
10219#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010220 pRoamProfile->csrPersona = pAdapter->device_mode;
10221
Jeff Johnson32d95a32012-09-10 13:15:23 -070010222 if( operatingChannel )
10223 {
10224 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
10225 pRoamProfile->ChannelInfo.numOfChannels = 1;
10226 }
Chet Lanctot186b5732013-03-18 10:26:30 -070010227 else
10228 {
10229 pRoamProfile->ChannelInfo.ChannelList = NULL;
10230 pRoamProfile->ChannelInfo.numOfChannels = 0;
10231 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010232 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
10233 {
10234 hdd_select_cbmode(pAdapter,operatingChannel);
10235 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010236
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010237 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
10238 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010239 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010240 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010241 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
10242 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010243 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10244 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053010245 {
10246 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10247 "%s: Set HDD connState to eConnectionState_Connecting",
10248 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010249 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
10250 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053010251 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010252 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010253 pAdapter->sessionId, pRoamProfile, &roamId);
10254
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010255 if ((eHAL_STATUS_SUCCESS != status) &&
10256 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10257 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010258
10259 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010260 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
10261 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
10262 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010263 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010264 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010265 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010266
10267 pRoamProfile->ChannelInfo.ChannelList = NULL;
10268 pRoamProfile->ChannelInfo.numOfChannels = 0;
10269
Jeff Johnson295189b2012-06-20 16:38:30 -070010270 }
10271 else
10272 {
10273 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
10274 return -EINVAL;
10275 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010276 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010277 return status;
10278}
10279
10280/*
10281 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
10282 * This function is used to set the authentication type (OPEN/SHARED).
10283 *
10284 */
10285static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
10286 enum nl80211_auth_type auth_type)
10287{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010288 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010289 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10290
10291 ENTER();
10292
10293 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010294 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070010295 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010296 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010297 hddLog(VOS_TRACE_LEVEL_INFO,
10298 "%s: set authentication type to AUTOSWITCH", __func__);
10299 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
10300 break;
10301
10302 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010303#ifdef WLAN_FEATURE_VOWIFI_11R
10304 case NL80211_AUTHTYPE_FT:
10305#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010306 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010307 "%s: set authentication type to OPEN", __func__);
10308 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
10309 break;
10310
10311 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010312 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010313 "%s: set authentication type to SHARED", __func__);
10314 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
10315 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010316#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010317 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010318 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010319 "%s: set authentication type to CCKM WPA", __func__);
10320 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
10321 break;
10322#endif
10323
10324
10325 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010326 hddLog(VOS_TRACE_LEVEL_ERROR,
10327 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010328 auth_type);
10329 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
10330 return -EINVAL;
10331 }
10332
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010333 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010334 pHddStaCtx->conn_info.authType;
10335 return 0;
10336}
10337
10338/*
10339 * FUNCTION: wlan_hdd_set_akm_suite
10340 * This function is used to set the key mgmt type(PSK/8021x).
10341 *
10342 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010343static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010344 u32 key_mgmt
10345 )
10346{
10347 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10348 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053010349 /* Should be in ieee802_11_defs.h */
10350#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
10351#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070010352 /*set key mgmt type*/
10353 switch(key_mgmt)
10354 {
10355 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053010356 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010357#ifdef WLAN_FEATURE_VOWIFI_11R
10358 case WLAN_AKM_SUITE_FT_PSK:
10359#endif
10360 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070010361 __func__);
10362 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
10363 break;
10364
10365 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053010366 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010367#ifdef WLAN_FEATURE_VOWIFI_11R
10368 case WLAN_AKM_SUITE_FT_8021X:
10369#endif
10370 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070010371 __func__);
10372 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10373 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010374#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010375#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
10376#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
10377 case WLAN_AKM_SUITE_CCKM:
10378 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
10379 __func__);
10380 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
10381 break;
10382#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070010383#ifndef WLAN_AKM_SUITE_OSEN
10384#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
10385 case WLAN_AKM_SUITE_OSEN:
10386 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
10387 __func__);
10388 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10389 break;
10390#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010391
10392 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010393 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010394 __func__, key_mgmt);
10395 return -EINVAL;
10396
10397 }
10398 return 0;
10399}
10400
10401/*
10402 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010403 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070010404 * (NONE/WEP40/WEP104/TKIP/CCMP).
10405 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010406static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
10407 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070010408 bool ucast
10409 )
10410{
10411 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010412 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010413 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10414
10415 ENTER();
10416
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010417 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010418 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010419 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070010420 __func__, cipher);
10421 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10422 }
10423 else
10424 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010425
Jeff Johnson295189b2012-06-20 16:38:30 -070010426 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010427 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010428 {
10429 case IW_AUTH_CIPHER_NONE:
10430 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10431 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010432
Jeff Johnson295189b2012-06-20 16:38:30 -070010433 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010434 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070010435 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010436
Jeff Johnson295189b2012-06-20 16:38:30 -070010437 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010438 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070010439 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010440
Jeff Johnson295189b2012-06-20 16:38:30 -070010441 case WLAN_CIPHER_SUITE_TKIP:
10442 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
10443 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010444
Jeff Johnson295189b2012-06-20 16:38:30 -070010445 case WLAN_CIPHER_SUITE_CCMP:
10446 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10447 break;
10448#ifdef FEATURE_WLAN_WAPI
10449 case WLAN_CIPHER_SUITE_SMS4:
10450 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
10451 break;
10452#endif
10453
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010454#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010455 case WLAN_CIPHER_SUITE_KRK:
10456 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
10457 break;
10458#endif
10459 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010460 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010461 __func__, cipher);
10462 return -EOPNOTSUPP;
10463 }
10464 }
10465
10466 if (ucast)
10467 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010468 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010469 __func__, encryptionType);
10470 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10471 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010472 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010473 encryptionType;
10474 }
10475 else
10476 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010477 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010478 __func__, encryptionType);
10479 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
10480 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
10481 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
10482 }
10483
10484 return 0;
10485}
10486
10487
10488/*
10489 * FUNCTION: wlan_hdd_cfg80211_set_ie
10490 * This function is used to parse WPA/RSN IE's.
10491 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010492int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
10493 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070010494 size_t ie_len
10495 )
10496{
10497 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10498 u8 *genie = ie;
10499 v_U16_t remLen = ie_len;
10500#ifdef FEATURE_WLAN_WAPI
10501 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
10502 u16 *tmp;
10503 v_U16_t akmsuiteCount;
10504 int *akmlist;
10505#endif
10506 ENTER();
10507
10508 /* clear previous assocAddIE */
10509 pWextState->assocAddIE.length = 0;
10510 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010511 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010512
10513 while (remLen >= 2)
10514 {
10515 v_U16_t eLen = 0;
10516 v_U8_t elementId;
10517 elementId = *genie++;
10518 eLen = *genie++;
10519 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010520
Arif Hussain6d2a3322013-11-17 19:50:10 -080010521 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070010522 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010523
10524 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070010525 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010526 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010527 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 -070010528 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010529 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010530 "%s: Invalid WPA IE", __func__);
10531 return -EINVAL;
10532 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010533 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070010534 {
10535 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010536 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010537 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010538
Jeff Johnson295189b2012-06-20 16:38:30 -070010539 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10540 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010541 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
10542 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010543 VOS_ASSERT(0);
10544 return -ENOMEM;
10545 }
10546 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10547 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10548 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010549
Jeff Johnson295189b2012-06-20 16:38:30 -070010550 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
10551 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10552 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10553 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010554 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
10555 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010556 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
10557 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10558 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
10559 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
10560 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
10561 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010562 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053010563 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010564 {
10565 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010566 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010567 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010568
Jeff Johnson295189b2012-06-20 16:38:30 -070010569 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10570 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010571 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10572 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010573 VOS_ASSERT(0);
10574 return -ENOMEM;
10575 }
10576 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10577 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10578 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010579
Jeff Johnson295189b2012-06-20 16:38:30 -070010580 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10581 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10582 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010583#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010584 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
10585 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010586 /*Consider WFD IE, only for P2P Client */
10587 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10588 {
10589 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010590 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010591 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010592
Jeff Johnson295189b2012-06-20 16:38:30 -070010593 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10594 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010595 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10596 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010597 VOS_ASSERT(0);
10598 return -ENOMEM;
10599 }
10600 // WFD IE is saved to Additional IE ; it should be accumulated to handle
10601 // WPS IE + P2P IE + WFD IE
10602 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10603 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010604
Jeff Johnson295189b2012-06-20 16:38:30 -070010605 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10606 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10607 }
10608#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010609 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010610 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010611 HS20_OUI_TYPE_SIZE)) )
10612 {
10613 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010614 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010615 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010616
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010617 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10618 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010619 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10620 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010621 VOS_ASSERT(0);
10622 return -ENOMEM;
10623 }
10624 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10625 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010626
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010627 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10628 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10629 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010630 /* Appending OSEN Information Element in Assiciation Request */
10631 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
10632 OSEN_OUI_TYPE_SIZE)) )
10633 {
10634 v_U16_t curAddIELen = pWextState->assocAddIE.length;
10635 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
10636 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010637
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010638 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10639 {
10640 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10641 "Need bigger buffer space");
10642 VOS_ASSERT(0);
10643 return -ENOMEM;
10644 }
10645 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10646 pWextState->assocAddIE.length += eLen + 2;
10647
10648 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
10649 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10650 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10651 }
10652
10653 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070010654 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
10655
10656 /* populating as ADDIE in beacon frames */
10657 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10658 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
10659 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
10660 {
10661 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10662 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10663 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10664 {
10665 hddLog(LOGE,
10666 "Coldn't pass "
10667 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
10668 }
10669 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
10670 else
10671 hddLog(LOGE,
10672 "Could not pass on "
10673 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
10674
10675 /* IBSS mode doesn't contain params->proberesp_ies still
10676 beaconIE's need to be populated in probe response frames */
10677 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
10678 {
10679 u16 rem_probe_resp_ie_len = eLen + 2;
10680 u8 probe_rsp_ie_len[3] = {0};
10681 u8 counter = 0;
10682
10683 /* Check Probe Resp Length if it is greater then 255 then
10684 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
10685 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
10686 not able Store More then 255 bytes into One Variable */
10687
10688 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
10689 {
10690 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
10691 {
10692 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
10693 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
10694 }
10695 else
10696 {
10697 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
10698 rem_probe_resp_ie_len = 0;
10699 }
10700 }
10701
10702 rem_probe_resp_ie_len = 0;
10703
10704 if (probe_rsp_ie_len[0] > 0)
10705 {
10706 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10707 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
10708 (tANI_U8*)(genie - 2),
10709 probe_rsp_ie_len[0], NULL,
10710 eANI_BOOLEAN_FALSE)
10711 == eHAL_STATUS_FAILURE)
10712 {
10713 hddLog(LOGE,
10714 "Could not pass"
10715 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
10716 }
10717 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10718 }
10719
10720 if (probe_rsp_ie_len[1] > 0)
10721 {
10722 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10723 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
10724 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10725 probe_rsp_ie_len[1], NULL,
10726 eANI_BOOLEAN_FALSE)
10727 == eHAL_STATUS_FAILURE)
10728 {
10729 hddLog(LOGE,
10730 "Could not pass"
10731 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
10732 }
10733 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10734 }
10735
10736 if (probe_rsp_ie_len[2] > 0)
10737 {
10738 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10739 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
10740 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10741 probe_rsp_ie_len[2], NULL,
10742 eANI_BOOLEAN_FALSE)
10743 == eHAL_STATUS_FAILURE)
10744 {
10745 hddLog(LOGE,
10746 "Could not pass"
10747 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
10748 }
10749 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10750 }
10751
10752 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10753 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10754 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10755 {
10756 hddLog(LOGE,
10757 "Could not pass"
10758 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
10759 }
10760 }
10761 else
10762 {
10763 // Reset WNI_CFG_PROBE_RSP Flags
10764 wlan_hdd_reset_prob_rspies(pAdapter);
10765
10766 hddLog(VOS_TRACE_LEVEL_INFO,
10767 "%s: No Probe Response IE received in set beacon",
10768 __func__);
10769 }
10770 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010771 break;
10772 case DOT11F_EID_RSN:
10773 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
10774 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10775 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
10776 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
10777 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
10778 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010779 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
10780 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010781 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010782 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010783 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010784 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010785
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010786 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10787 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010788 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10789 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010790 VOS_ASSERT(0);
10791 return -ENOMEM;
10792 }
10793 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10794 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010795
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010796 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10797 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10798 break;
10799 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010800#ifdef FEATURE_WLAN_WAPI
10801 case WLAN_EID_WAPI:
10802 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010803 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070010804 pAdapter->wapi_info.nWapiMode);
10805 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010806 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070010807 akmsuiteCount = WPA_GET_LE16(tmp);
10808 tmp = tmp + 1;
10809 akmlist = (int *)(tmp);
10810 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
10811 {
10812 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
10813 }
10814 else
10815 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010816 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070010817 VOS_ASSERT(0);
10818 return -EINVAL;
10819 }
10820
10821 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
10822 {
10823 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010824 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010825 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010826 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010827 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010828 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010829 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010830 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010831 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
10832 }
10833 break;
10834#endif
10835 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010836 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010837 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010838 /* when Unknown IE is received we should break and continue
10839 * to the next IE in the buffer instead we were returning
10840 * so changing this to break */
10841 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010842 }
10843 genie += eLen;
10844 remLen -= eLen;
10845 }
10846 EXIT();
10847 return 0;
10848}
10849
10850/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053010851 * FUNCTION: hdd_isWPAIEPresent
10852 * Parse the received IE to find the WPA IE
10853 *
10854 */
10855static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
10856{
10857 v_U8_t eLen = 0;
10858 v_U16_t remLen = ie_len;
10859 v_U8_t elementId = 0;
10860
10861 while (remLen >= 2)
10862 {
10863 elementId = *ie++;
10864 eLen = *ie++;
10865 remLen -= 2;
10866 if (eLen > remLen)
10867 {
10868 hddLog(VOS_TRACE_LEVEL_ERROR,
10869 "%s: IE length is wrong %d", __func__, eLen);
10870 return FALSE;
10871 }
10872 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
10873 {
10874 /* OUI - 0x00 0X50 0XF2
10875 WPA Information Element - 0x01
10876 WPA version - 0x01*/
10877 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
10878 return TRUE;
10879 }
10880 ie += eLen;
10881 remLen -= eLen;
10882 }
10883 return FALSE;
10884}
10885
10886/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010887 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010888 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010889 * parameters during connect operation.
10890 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010891int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010892 struct cfg80211_connect_params *req
10893 )
10894{
10895 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010896 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010897 ENTER();
10898
10899 /*set wpa version*/
10900 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
10901
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010902 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070010903 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053010904 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070010905 {
10906 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
10907 }
10908 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
10909 {
10910 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
10911 }
10912 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010913
10914 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010915 pWextState->wpaVersion);
10916
10917 /*set authentication type*/
10918 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
10919
10920 if (0 > status)
10921 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010922 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010923 "%s: failed to set authentication type ", __func__);
10924 return status;
10925 }
10926
10927 /*set key mgmt type*/
10928 if (req->crypto.n_akm_suites)
10929 {
10930 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
10931 if (0 > status)
10932 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010933 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070010934 __func__);
10935 return status;
10936 }
10937 }
10938
10939 /*set pairwise cipher type*/
10940 if (req->crypto.n_ciphers_pairwise)
10941 {
10942 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
10943 req->crypto.ciphers_pairwise[0], true);
10944 if (0 > status)
10945 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010946 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010947 "%s: failed to set unicast cipher type", __func__);
10948 return status;
10949 }
10950 }
10951 else
10952 {
10953 /*Reset previous cipher suite to none*/
10954 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
10955 if (0 > status)
10956 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010957 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010958 "%s: failed to set unicast cipher type", __func__);
10959 return status;
10960 }
10961 }
10962
10963 /*set group cipher type*/
10964 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
10965 false);
10966
10967 if (0 > status)
10968 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010969 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070010970 __func__);
10971 return status;
10972 }
10973
Chet Lanctot186b5732013-03-18 10:26:30 -070010974#ifdef WLAN_FEATURE_11W
10975 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
10976#endif
10977
Jeff Johnson295189b2012-06-20 16:38:30 -070010978 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
10979 if (req->ie_len)
10980 {
10981 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
10982 if ( 0 > status)
10983 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010984 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010985 __func__);
10986 return status;
10987 }
10988 }
10989
10990 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010991 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010992 {
10993 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
10994 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
10995 )
10996 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010997 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070010998 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
10999 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011000 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011001 __func__);
11002 return -EOPNOTSUPP;
11003 }
11004 else
11005 {
11006 u8 key_len = req->key_len;
11007 u8 key_idx = req->key_idx;
11008
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011009 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011010 && (CSR_MAX_NUM_KEY > key_idx)
11011 )
11012 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011013 hddLog(VOS_TRACE_LEVEL_INFO,
11014 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011015 __func__, key_idx, key_len);
11016 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011017 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011018 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011019 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011020 (u8)key_len;
11021 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
11022 }
11023 }
11024 }
11025 }
11026
11027 return status;
11028}
11029
11030/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011031 * FUNCTION: wlan_hdd_try_disconnect
11032 * This function is used to disconnect from previous
11033 * connection
11034 */
11035static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
11036{
11037 long ret = 0;
11038 hdd_station_ctx_t *pHddStaCtx;
11039 eMib_dot11DesiredBssType connectedBssType;
11040
11041 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11042
11043 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
11044
11045 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
11046 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
11047 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
11048 {
11049 /* Issue disconnect to CSR */
11050 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11051 if( eHAL_STATUS_SUCCESS ==
11052 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11053 pAdapter->sessionId,
11054 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11055 {
11056 ret = wait_for_completion_interruptible_timeout(
11057 &pAdapter->disconnect_comp_var,
11058 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11059 if (0 >= ret)
11060 {
11061 hddLog(LOGE, FL("Failed to receive disconnect event"));
11062 return -EALREADY;
11063 }
11064 }
11065 }
11066 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
11067 {
11068 ret = wait_for_completion_interruptible_timeout(
11069 &pAdapter->disconnect_comp_var,
11070 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11071 if (0 >= ret)
11072 {
11073 hddLog(LOGE, FL("Failed to receive disconnect event"));
11074 return -EALREADY;
11075 }
11076 }
11077
11078 return 0;
11079}
11080
11081/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053011082 * FUNCTION: __wlan_hdd_cfg80211_connect
11083 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011084 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011085static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011086 struct net_device *ndev,
11087 struct cfg80211_connect_params *req
11088 )
11089{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011090 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011091 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011092 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053011093 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011094
11095 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011096
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011097 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11098 TRACE_CODE_HDD_CFG80211_CONNECT,
11099 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011100 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011101 "%s: device_mode = %s (%d)", __func__,
11102 hdd_device_modetoString(pAdapter->device_mode),
11103 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011104
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011105 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011106 if (!pHddCtx)
11107 {
11108 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11109 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011110 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011111 }
11112
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011113 status = wlan_hdd_validate_context(pHddCtx);
11114
11115 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011116 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11118 "%s: HDD context is not valid", __func__);
11119 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011120 }
11121
Agarwal Ashish51325b52014-06-16 16:50:49 +053011122 if (vos_max_concurrent_connections_reached()) {
11123 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11124 return -ECONNREFUSED;
11125 }
11126
Jeff Johnson295189b2012-06-20 16:38:30 -070011127#ifdef WLAN_BTAMP_FEATURE
11128 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011129 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070011130 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011131 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011132 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011133 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070011134 }
11135#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011136
11137 //If Device Mode is Station Concurrent Sessions Exit BMps
11138 //P2P Mode will be taken care in Open/close adapter
11139 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011140 (vos_concurrent_open_sessions_running())) {
11141 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
11142 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011143 }
11144
11145 /*Try disconnecting if already in connected state*/
11146 status = wlan_hdd_try_disconnect(pAdapter);
11147 if ( 0 > status)
11148 {
11149 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11150 " connection"));
11151 return -EALREADY;
11152 }
11153
Jeff Johnson295189b2012-06-20 16:38:30 -070011154 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011155 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070011156
11157 if ( 0 > status)
11158 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011159 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070011160 __func__);
11161 return status;
11162 }
Mohit Khanna765234a2012-09-11 15:08:35 -070011163 if ( req->channel )
11164 {
11165 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
11166 req->ssid_len, req->bssid,
11167 req->channel->hw_value);
11168 }
11169 else
11170 {
11171 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011172 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070011173 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011174
11175 if (0 > status)
11176 {
11177 //ReEnable BMPS if disabled
11178 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
11179 (NULL != pHddCtx))
11180 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011181 if (pHddCtx->hdd_wlan_suspended)
11182 {
11183 hdd_set_pwrparams(pHddCtx);
11184 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011185 //ReEnable Bmps and Imps back
11186 hdd_enable_bmps_imps(pHddCtx);
11187 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011188 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011189 return status;
11190 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011191 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011192 EXIT();
11193 return status;
11194}
11195
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011196static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
11197 struct net_device *ndev,
11198 struct cfg80211_connect_params *req)
11199{
11200 int ret;
11201 vos_ssr_protect(__func__);
11202 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
11203 vos_ssr_unprotect(__func__);
11204
11205 return ret;
11206}
Jeff Johnson295189b2012-06-20 16:38:30 -070011207
11208/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011209 * FUNCTION: wlan_hdd_disconnect
11210 * This function is used to issue a disconnect request to SME
11211 */
11212int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
11213{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011214 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011215 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011216 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011217 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011218
11219 status = wlan_hdd_validate_context(pHddCtx);
11220
11221 if (0 != status)
11222 {
11223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11224 "%s: HDD context is not valid", __func__);
11225 return status;
11226 }
11227
11228 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011229
Agarwal Ashish47d18112014-08-04 19:55:07 +053011230 /* Need to apply spin lock before decreasing active sessions
11231 * as there can be chance for double decrement if context switch
11232 * Calls hdd_DisConnectHandler.
11233 */
11234
11235 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011236 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11237 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011238 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11239 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053011240 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
11241 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011242
Abhishek Singhf4669da2014-05-26 15:07:49 +053011243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053011244 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
11245
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011246 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011247
Mihir Shete182a0b22014-08-18 16:08:48 +053011248 /*
11249 * stop tx queues before deleting STA/BSS context from the firmware.
11250 * tx has to be disabled because the firmware can get busy dropping
11251 * the tx frames after BSS/STA has been deleted and will not send
11252 * back a response resulting in WDI timeout
11253 */
11254 netif_tx_disable(pAdapter->dev);
11255 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011256
Mihir Shete182a0b22014-08-18 16:08:48 +053011257 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011258 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11259 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011260 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
11261 {
11262 hddLog(VOS_TRACE_LEVEL_INFO,
11263 FL("status = %d, already disconnected"),
11264 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011265
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011266 }
11267 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011268 {
11269 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011270 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011271 __func__, (int)status );
11272 return -EINVAL;
11273 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011274 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011275 &pAdapter->disconnect_comp_var,
11276 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011277 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011278 {
11279 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011280 "%s: Failed to disconnect, timed out", __func__);
11281 return -ETIMEDOUT;
11282 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011283 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011284 {
11285 hddLog(VOS_TRACE_LEVEL_ERROR,
11286 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011287 return ret;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011288 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11290 FL("Set HDD connState to eConnectionState_NotConnected"));
11291 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
11292
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011293 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011294}
11295
11296
11297/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011298 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070011299 * This function is used to issue a disconnect request to SME
11300 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011301static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011302 struct net_device *dev,
11303 u16 reason
11304 )
11305{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011306 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011307 tCsrRoamProfile *pRoamProfile =
11308 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011309 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011310 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11311 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011312#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011313 tANI_U8 staIdx;
11314#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011315
Jeff Johnson295189b2012-06-20 16:38:30 -070011316 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011317
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011318 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11319 TRACE_CODE_HDD_CFG80211_DISCONNECT,
11320 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011321 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
11322 __func__, hdd_device_modetoString(pAdapter->device_mode),
11323 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011324
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011325 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
11326 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070011327
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011328 status = wlan_hdd_validate_context(pHddCtx);
11329
11330 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011331 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011332 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11333 "%s: HDD context is not valid", __func__);
11334 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011335 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011336
Jeff Johnson295189b2012-06-20 16:38:30 -070011337 if (NULL != pRoamProfile)
11338 {
11339 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011340 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
11341 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070011342 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011343 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070011344 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011345 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070011346 switch(reason)
11347 {
11348 case WLAN_REASON_MIC_FAILURE:
11349 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
11350 break;
11351
11352 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
11353 case WLAN_REASON_DISASSOC_AP_BUSY:
11354 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
11355 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
11356 break;
11357
11358 case WLAN_REASON_PREV_AUTH_NOT_VALID:
11359 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053011360 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070011361 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
11362 break;
11363
Jeff Johnson295189b2012-06-20 16:38:30 -070011364 default:
11365 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
11366 break;
11367 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011368 pScanInfo = &pHddCtx->scan_info;
11369 if (pScanInfo->mScanPending)
11370 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011371 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011372 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011373 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011374 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011375 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011376
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011377#ifdef FEATURE_WLAN_TDLS
11378 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011379 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011380 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011381 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
11382 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011383 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011384 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011385 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011386 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011387 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011388 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011389 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011390 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011391 pAdapter->sessionId,
11392 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011393 }
11394 }
11395#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011396 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011397 status = wlan_hdd_disconnect(pAdapter, reasonCode);
11398 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070011399 {
11400 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011401 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011402 __func__, (int)status );
11403 return -EINVAL;
11404 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011405 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011406 else
11407 {
11408 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
11409 "called while in %d state", __func__,
11410 pHddStaCtx->conn_info.connState);
11411 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011412 }
11413 else
11414 {
11415 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
11416 }
11417
11418 return status;
11419}
11420
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011421static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
11422 struct net_device *dev,
11423 u16 reason
11424 )
11425{
11426 int ret;
11427 vos_ssr_protect(__func__);
11428 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
11429 vos_ssr_unprotect(__func__);
11430
11431 return ret;
11432}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011433
Jeff Johnson295189b2012-06-20 16:38:30 -070011434/*
11435 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011436 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011437 * settings in IBSS mode.
11438 */
11439static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011440 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011441 struct cfg80211_ibss_params *params
11442 )
11443{
11444 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011445 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011446 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11447 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011448
Jeff Johnson295189b2012-06-20 16:38:30 -070011449 ENTER();
11450
11451 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070011452 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070011453
11454 if (params->ie_len && ( NULL != params->ie) )
11455 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011456 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11457 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011458 {
11459 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11460 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11461 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011462 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011463 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011464 tDot11fIEWPA dot11WPAIE;
11465 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011466 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011467
Wilson Yang00256342013-10-10 23:13:38 -070011468 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011469 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11470 params->ie_len, DOT11F_EID_WPA);
11471 if ( NULL != ie )
11472 {
11473 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11474 // Unpack the WPA IE
11475 //Skip past the EID byte and length byte - and four byte WiFi OUI
11476 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
11477 &ie[2+4],
11478 ie[1] - 4,
11479 &dot11WPAIE);
11480 /*Extract the multicast cipher, the encType for unicast
11481 cipher for wpa-none is none*/
11482 encryptionType =
11483 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
11484 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011485 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011486
Jeff Johnson295189b2012-06-20 16:38:30 -070011487 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
11488
11489 if (0 > status)
11490 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011491 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011492 __func__);
11493 return status;
11494 }
11495 }
11496
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011497 pWextState->roamProfile.AuthType.authType[0] =
11498 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011499 eCSR_AUTH_TYPE_OPEN_SYSTEM;
11500
11501 if (params->privacy)
11502 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011503 /* Security enabled IBSS, At this time there is no information available
11504 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070011505 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011506 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070011507 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011508 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070011509 *enable privacy bit in beacons */
11510
11511 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11512 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011513 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
11514 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070011515 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11516 pWextState->roamProfile.EncryptionType.numEntries = 1;
11517 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070011518 return status;
11519}
11520
11521/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011522 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011523 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011524 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011525static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011526 struct net_device *dev,
11527 struct cfg80211_ibss_params *params
11528 )
11529{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011530 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011531 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11532 tCsrRoamProfile *pRoamProfile;
11533 int status;
krunal sonie9002db2013-11-25 14:24:17 -080011534 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011535 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11536 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011537
11538 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011539
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011540 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11541 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
11542 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011543 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011544 "%s: device_mode = %s (%d)", __func__,
11545 hdd_device_modetoString(pAdapter->device_mode),
11546 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011547
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011548 status = wlan_hdd_validate_context(pHddCtx);
11549
11550 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011551 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11553 "%s: HDD context is not valid", __func__);
11554 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011555 }
11556
11557 if (NULL == pWextState)
11558 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011559 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011560 __func__);
11561 return -EIO;
11562 }
11563
Agarwal Ashish51325b52014-06-16 16:50:49 +053011564 if (vos_max_concurrent_connections_reached()) {
11565 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11566 return -ECONNREFUSED;
11567 }
11568
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011569 /*Try disconnecting if already in connected state*/
11570 status = wlan_hdd_try_disconnect(pAdapter);
11571 if ( 0 > status)
11572 {
11573 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11574 " IBSS connection"));
11575 return -EALREADY;
11576 }
11577
Jeff Johnson295189b2012-06-20 16:38:30 -070011578 pRoamProfile = &pWextState->roamProfile;
11579
11580 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
11581 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011582 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011583 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011584 return -EINVAL;
11585 }
11586
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011587 /* BSSID is provided by upper layers hence no need to AUTO generate */
11588 if (NULL != params->bssid) {
11589 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11590 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
11591 hddLog (VOS_TRACE_LEVEL_ERROR,
11592 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11593 return -EIO;
11594 }
11595 }
krunal sonie9002db2013-11-25 14:24:17 -080011596 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
11597 {
11598 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11599 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
11600 {
11601 hddLog (VOS_TRACE_LEVEL_ERROR,
11602 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11603 return -EIO;
11604 }
11605 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
11606 if (!params->bssid)
11607 {
11608 hddLog (VOS_TRACE_LEVEL_ERROR,
11609 "%s:Failed memory allocation", __func__);
11610 return -EIO;
11611 }
11612 vos_mem_copy((v_U8_t *)params->bssid,
11613 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
11614 VOS_MAC_ADDR_SIZE);
11615 alloc_bssid = VOS_TRUE;
11616 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011617
Jeff Johnson295189b2012-06-20 16:38:30 -070011618 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070011619 if (NULL !=
11620#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11621 params->chandef.chan)
11622#else
11623 params->channel)
11624#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011625 {
11626 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011627 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
11628 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
11629 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
11630 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011631
11632 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011633 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070011634 ieee80211_frequency_to_channel(
11635#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11636 params->chandef.chan->center_freq);
11637#else
11638 params->channel->center_freq);
11639#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011640
11641 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
11642 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070011643 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011644 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
11645 __func__);
11646 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070011647 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011648
11649 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011650 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011651 if (channelNum == validChan[indx])
11652 {
11653 break;
11654 }
11655 }
11656 if (indx >= numChans)
11657 {
11658 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011659 __func__, channelNum);
11660 return -EINVAL;
11661 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011662 /* Set the Operational Channel */
11663 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
11664 channelNum);
11665 pRoamProfile->ChannelInfo.numOfChannels = 1;
11666 pHddStaCtx->conn_info.operationChannel = channelNum;
11667 pRoamProfile->ChannelInfo.ChannelList =
11668 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070011669 }
11670
11671 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011672 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070011673 if (status < 0)
11674 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011675 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070011676 __func__);
11677 return status;
11678 }
11679
11680 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011681 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011682 params->ssid_len, params->bssid,
11683 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011684
11685 if (0 > status)
11686 {
11687 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
11688 return status;
11689 }
11690
krunal sonie9002db2013-11-25 14:24:17 -080011691 if (NULL != params->bssid &&
11692 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
11693 alloc_bssid == VOS_TRUE)
11694 {
11695 vos_mem_free(params->bssid);
11696 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011697 return 0;
11698}
11699
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011700static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
11701 struct net_device *dev,
11702 struct cfg80211_ibss_params *params
11703 )
11704{
11705 int ret = 0;
11706
11707 vos_ssr_protect(__func__);
11708 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
11709 vos_ssr_unprotect(__func__);
11710
11711 return ret;
11712}
11713
Jeff Johnson295189b2012-06-20 16:38:30 -070011714/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011715 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011716 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011717 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011718static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011719 struct net_device *dev
11720 )
11721{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011722 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011723 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11724 tCsrRoamProfile *pRoamProfile;
11725 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011726 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011727
11728 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011729
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011730 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11731 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
11732 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011733 status = wlan_hdd_validate_context(pHddCtx);
11734
11735 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011736 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011737 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11738 "%s: HDD context is not valid", __func__);
11739 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011740 }
11741
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011742 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
11743 hdd_device_modetoString(pAdapter->device_mode),
11744 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011745 if (NULL == pWextState)
11746 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011747 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011748 __func__);
11749 return -EIO;
11750 }
11751
11752 pRoamProfile = &pWextState->roamProfile;
11753
11754 /* Issue disconnect only if interface type is set to IBSS */
11755 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
11756 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011757 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070011758 __func__);
11759 return -EINVAL;
11760 }
11761
11762 /* Issue Disconnect request */
11763 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11764 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
11765 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
11766
11767 return 0;
11768}
11769
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011770static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
11771 struct net_device *dev
11772 )
11773{
11774 int ret = 0;
11775
11776 vos_ssr_protect(__func__);
11777 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
11778 vos_ssr_unprotect(__func__);
11779
11780 return ret;
11781}
11782
Jeff Johnson295189b2012-06-20 16:38:30 -070011783/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011784 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070011785 * This function is used to set the phy parameters
11786 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
11787 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011788static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011789 u32 changed)
11790{
11791 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
11792 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011793 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011794
11795 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011796 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11797 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
11798 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011799 status = wlan_hdd_validate_context(pHddCtx);
11800
11801 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011802 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11804 "%s: HDD context is not valid", __func__);
11805 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011806 }
11807
Jeff Johnson295189b2012-06-20 16:38:30 -070011808 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
11809 {
11810 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
11811 WNI_CFG_RTS_THRESHOLD_STAMAX :
11812 wiphy->rts_threshold;
11813
11814 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011815 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070011816 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011817 hddLog(VOS_TRACE_LEVEL_ERROR,
11818 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011819 __func__, rts_threshold);
11820 return -EINVAL;
11821 }
11822
11823 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
11824 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011825 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011826 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011827 hddLog(VOS_TRACE_LEVEL_ERROR,
11828 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011829 __func__, rts_threshold);
11830 return -EIO;
11831 }
11832
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011833 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011834 rts_threshold);
11835 }
11836
11837 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
11838 {
11839 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
11840 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
11841 wiphy->frag_threshold;
11842
11843 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011844 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011845 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011846 hddLog(VOS_TRACE_LEVEL_ERROR,
11847 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011848 frag_threshold);
11849 return -EINVAL;
11850 }
11851
11852 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
11853 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011854 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011855 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011856 hddLog(VOS_TRACE_LEVEL_ERROR,
11857 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011858 __func__, frag_threshold);
11859 return -EIO;
11860 }
11861
11862 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
11863 frag_threshold);
11864 }
11865
11866 if ((changed & WIPHY_PARAM_RETRY_SHORT)
11867 || (changed & WIPHY_PARAM_RETRY_LONG))
11868 {
11869 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
11870 wiphy->retry_short :
11871 wiphy->retry_long;
11872
11873 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
11874 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
11875 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011876 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011877 __func__, retry_value);
11878 return -EINVAL;
11879 }
11880
11881 if (changed & WIPHY_PARAM_RETRY_SHORT)
11882 {
11883 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
11884 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011885 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011886 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011887 hddLog(VOS_TRACE_LEVEL_ERROR,
11888 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011889 __func__, retry_value);
11890 return -EIO;
11891 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011892 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011893 __func__, retry_value);
11894 }
11895 else if (changed & WIPHY_PARAM_RETRY_SHORT)
11896 {
11897 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
11898 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011899 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011900 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011901 hddLog(VOS_TRACE_LEVEL_ERROR,
11902 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011903 __func__, retry_value);
11904 return -EIO;
11905 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011906 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011907 __func__, retry_value);
11908 }
11909 }
11910
11911 return 0;
11912}
11913
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011914static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
11915 u32 changed)
11916{
11917 int ret;
11918
11919 vos_ssr_protect(__func__);
11920 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
11921 vos_ssr_unprotect(__func__);
11922
11923 return ret;
11924}
11925
Jeff Johnson295189b2012-06-20 16:38:30 -070011926/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011927 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070011928 * This function is used to set the txpower
11929 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011930static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070011931#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11932 struct wireless_dev *wdev,
11933#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011934#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011935 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070011936#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011937 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070011938#endif
11939 int dbm)
11940{
11941 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011942 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011943 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11944 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011945 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011946
11947 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011948 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11949 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
11950 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011951 status = wlan_hdd_validate_context(pHddCtx);
11952
11953 if (0 != status)
11954 {
11955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11956 "%s: HDD context is not valid", __func__);
11957 return status;
11958 }
11959
11960 hHal = pHddCtx->hHal;
11961
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011962 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
11963 dbm, ccmCfgSetCallback,
11964 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011965 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011966 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011967 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
11968 return -EIO;
11969 }
11970
11971 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
11972 dbm);
11973
11974 switch(type)
11975 {
11976 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
11977 /* Fall through */
11978 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
11979 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
11980 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011981 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
11982 __func__);
11983 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011984 }
11985 break;
11986 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011987 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011988 __func__);
11989 return -EOPNOTSUPP;
11990 break;
11991 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011992 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
11993 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070011994 return -EIO;
11995 }
11996
11997 return 0;
11998}
11999
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012000static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
12001#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12002 struct wireless_dev *wdev,
12003#endif
12004#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12005 enum tx_power_setting type,
12006#else
12007 enum nl80211_tx_power_setting type,
12008#endif
12009 int dbm)
12010{
12011 int ret;
12012 vos_ssr_protect(__func__);
12013 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
12014#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12015 wdev,
12016#endif
12017#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12018 type,
12019#else
12020 type,
12021#endif
12022 dbm);
12023 vos_ssr_unprotect(__func__);
12024
12025 return ret;
12026}
12027
Jeff Johnson295189b2012-06-20 16:38:30 -070012028/*
12029 * FUNCTION: wlan_hdd_cfg80211_get_txpower
12030 * This function is used to read the txpower
12031 */
Yue Maf49ba872013-08-19 12:04:25 -070012032static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
12033#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12034 struct wireless_dev *wdev,
12035#endif
12036 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070012037{
12038
12039 hdd_adapter_t *pAdapter;
12040 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012041 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012042
Jeff Johnsone7245742012-09-05 17:12:55 -070012043 ENTER();
12044
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012045 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012046
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012047 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012048 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12050 "%s: HDD context is not valid", __func__);
12051 *dbm = 0;
12052 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012053 }
12054
Jeff Johnson295189b2012-06-20 16:38:30 -070012055 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
12056 if (NULL == pAdapter)
12057 {
12058 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
12059 return -ENOENT;
12060 }
12061
12062 wlan_hdd_get_classAstats(pAdapter);
12063 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
12064
Jeff Johnsone7245742012-09-05 17:12:55 -070012065 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012066 return 0;
12067}
12068
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012069static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070012070 u8* mac, struct station_info *sinfo)
12071{
12072 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12073 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12074 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053012075 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070012076
12077 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
12078 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012079
12080 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
12081 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
12082 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
12083 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
12084 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
12085 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
12086 tANI_U16 maxRate = 0;
12087 tANI_U16 myRate;
12088 tANI_U16 currentRate = 0;
12089 tANI_U8 maxSpeedMCS = 0;
12090 tANI_U8 maxMCSIdx = 0;
12091 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053012092 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012093 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012094 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012095
Leo Chang6f8870f2013-03-26 18:11:36 -070012096#ifdef WLAN_FEATURE_11AC
12097 tANI_U32 vht_mcs_map;
12098 eDataRate11ACMaxMcs vhtMaxMcs;
12099#endif /* WLAN_FEATURE_11AC */
12100
Jeff Johnsone7245742012-09-05 17:12:55 -070012101 ENTER();
12102
Jeff Johnson295189b2012-06-20 16:38:30 -070012103 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
12104 (0 == ssidlen))
12105 {
12106 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
12107 " Invalid ssidlen, %d", __func__, ssidlen);
12108 /*To keep GUI happy*/
12109 return 0;
12110 }
12111
Mukul Sharma811205f2014-07-09 21:07:30 +053012112 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
12113 {
12114 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12115 "%s: Roaming in progress, so unable to proceed this request", __func__);
12116 return 0;
12117 }
12118
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012119 status = wlan_hdd_validate_context(pHddCtx);
12120
12121 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012122 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12124 "%s: HDD context is not valid", __func__);
12125 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012126 }
12127
Jeff Johnson295189b2012-06-20 16:38:30 -070012128
Kiet Lam3b17fc82013-09-27 05:24:08 +053012129 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
12130 sinfo->filled |= STATION_INFO_SIGNAL;
12131
c_hpothu09f19542014-05-30 21:53:31 +053012132 wlan_hdd_get_station_stats(pAdapter);
12133 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
12134
12135 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053012136 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
12137 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053012138 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053012139 {
12140 rate_flags = pAdapter->maxRateFlags;
12141 }
c_hpothu44ff4e02014-05-08 00:13:57 +053012142
Jeff Johnson295189b2012-06-20 16:38:30 -070012143 //convert to the UI units of 100kbps
12144 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
12145
12146#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070012147 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 -070012148 sinfo->signal,
12149 pCfg->reportMaxLinkSpeed,
12150 myRate,
12151 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012152 (int) pCfg->linkSpeedRssiMid,
12153 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070012154 (int) rate_flags,
12155 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012156#endif //LINKSPEED_DEBUG_ENABLED
12157
12158 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
12159 {
12160 // we do not want to necessarily report the current speed
12161 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
12162 {
12163 // report the max possible speed
12164 rssidx = 0;
12165 }
12166 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
12167 {
12168 // report the max possible speed with RSSI scaling
12169 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
12170 {
12171 // report the max possible speed
12172 rssidx = 0;
12173 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012174 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070012175 {
12176 // report middle speed
12177 rssidx = 1;
12178 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012179 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
12180 {
12181 // report middle speed
12182 rssidx = 2;
12183 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012184 else
12185 {
12186 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012187 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070012188 }
12189 }
12190 else
12191 {
12192 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
12193 hddLog(VOS_TRACE_LEVEL_ERROR,
12194 "%s: Invalid value for reportMaxLinkSpeed: %u",
12195 __func__, pCfg->reportMaxLinkSpeed);
12196 rssidx = 0;
12197 }
12198
12199 maxRate = 0;
12200
12201 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012202 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
12203 OperationalRates, &ORLeng))
12204 {
12205 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12206 /*To keep GUI happy*/
12207 return 0;
12208 }
12209
Jeff Johnson295189b2012-06-20 16:38:30 -070012210 for (i = 0; i < ORLeng; i++)
12211 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012212 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012213 {
12214 /* Validate Rate Set */
12215 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
12216 {
12217 currentRate = supported_data_rate[j].supported_rate[rssidx];
12218 break;
12219 }
12220 }
12221 /* Update MAX rate */
12222 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12223 }
12224
12225 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012226 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
12227 ExtendedRates, &ERLeng))
12228 {
12229 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12230 /*To keep GUI happy*/
12231 return 0;
12232 }
12233
Jeff Johnson295189b2012-06-20 16:38:30 -070012234 for (i = 0; i < ERLeng; i++)
12235 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012236 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012237 {
12238 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
12239 {
12240 currentRate = supported_data_rate[j].supported_rate[rssidx];
12241 break;
12242 }
12243 }
12244 /* Update MAX rate */
12245 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12246 }
c_hpothu79aab322014-07-14 21:11:01 +053012247
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012248 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053012249 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012250 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053012251 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070012252 {
c_hpothu79aab322014-07-14 21:11:01 +053012253 if (rate_flags & eHAL_TX_RATE_VHT80)
12254 mode = 2;
12255 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
12256 mode = 1;
12257 else
12258 mode = 0;
12259
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012260 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
12261 MCSRates, &MCSLeng))
12262 {
12263 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12264 /*To keep GUI happy*/
12265 return 0;
12266 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012267 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070012268#ifdef WLAN_FEATURE_11AC
12269 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012270 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070012271 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012272 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012273 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070012274 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070012275 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012276 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070012277 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012278 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070012279 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012280 maxMCSIdx = 7;
12281 }
12282 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
12283 {
12284 maxMCSIdx = 8;
12285 }
12286 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
12287 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012288 //VHT20 is supporting 0~8
12289 if (rate_flags & eHAL_TX_RATE_VHT20)
12290 maxMCSIdx = 8;
12291 else
12292 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070012293 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012294
c_hpothu79aab322014-07-14 21:11:01 +053012295 if (0 != rssidx)/*check for scaled */
12296 {
12297 //get middle rate MCS index if rssi=1/2
12298 for (i=0; i <= maxMCSIdx; i++)
12299 {
12300 if (sinfo->signal <= rssiMcsTbl[mode][i])
12301 {
12302 maxMCSIdx = i;
12303 break;
12304 }
12305 }
12306 }
12307
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012308 if (rate_flags & eHAL_TX_RATE_VHT80)
12309 {
12310 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
12311 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
12312 }
12313 else if (rate_flags & eHAL_TX_RATE_VHT40)
12314 {
12315 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
12316 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
12317 }
12318 else if (rate_flags & eHAL_TX_RATE_VHT20)
12319 {
12320 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
12321 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
12322 }
12323
Leo Chang6f8870f2013-03-26 18:11:36 -070012324 maxSpeedMCS = 1;
12325 if (currentRate > maxRate)
12326 {
12327 maxRate = currentRate;
12328 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012329
Leo Chang6f8870f2013-03-26 18:11:36 -070012330 }
12331 else
12332#endif /* WLAN_FEATURE_11AC */
12333 {
12334 if (rate_flags & eHAL_TX_RATE_HT40)
12335 {
12336 rateFlag |= 1;
12337 }
12338 if (rate_flags & eHAL_TX_RATE_SGI)
12339 {
12340 rateFlag |= 2;
12341 }
12342
Girish Gowli01abcee2014-07-31 20:18:55 +053012343 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053012344 if (rssidx == 1 || rssidx == 2)
12345 {
12346 //get middle rate MCS index if rssi=1/2
12347 for (i=0; i <= 7; i++)
12348 {
12349 if (sinfo->signal <= rssiMcsTbl[mode][i])
12350 {
12351 temp = i+1;
12352 break;
12353 }
12354 }
12355 }
c_hpothu79aab322014-07-14 21:11:01 +053012356
12357 for (i = 0; i < MCSLeng; i++)
12358 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012359 for (j = 0; j < temp; j++)
12360 {
12361 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
12362 {
12363 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
12364 break;
12365 }
12366 }
12367 if ((j < temp) && (currentRate > maxRate))
12368 {
12369 maxRate = currentRate;
12370 maxSpeedMCS = 1;
12371 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
12372 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012373 }
12374 }
12375 }
12376
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012377 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
12378 {
12379 maxRate = myRate;
12380 maxSpeedMCS = 1;
12381 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12382 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012383 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053012384 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070012385 {
12386 maxRate = myRate;
12387 if (rate_flags & eHAL_TX_RATE_LEGACY)
12388 {
12389 maxSpeedMCS = 0;
12390 }
12391 else
12392 {
12393 maxSpeedMCS = 1;
12394 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12395 }
12396 }
12397
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012398 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070012399 {
12400 sinfo->txrate.legacy = maxRate;
12401#ifdef LINKSPEED_DEBUG_ENABLED
12402 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
12403#endif //LINKSPEED_DEBUG_ENABLED
12404 }
12405 else
12406 {
12407 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070012408#ifdef WLAN_FEATURE_11AC
12409 sinfo->txrate.nss = 1;
12410 if (rate_flags & eHAL_TX_RATE_VHT80)
12411 {
12412 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012413 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070012414 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012415 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070012416 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012417 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12418 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12419 }
12420 else if (rate_flags & eHAL_TX_RATE_VHT20)
12421 {
12422 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12423 }
12424#endif /* WLAN_FEATURE_11AC */
12425 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
12426 {
12427 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12428 if (rate_flags & eHAL_TX_RATE_HT40)
12429 {
12430 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12431 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012432 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012433 if (rate_flags & eHAL_TX_RATE_SGI)
12434 {
12435 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12436 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012437
Jeff Johnson295189b2012-06-20 16:38:30 -070012438#ifdef LINKSPEED_DEBUG_ENABLED
12439 pr_info("Reporting MCS rate %d flags %x\n",
12440 sinfo->txrate.mcs,
12441 sinfo->txrate.flags );
12442#endif //LINKSPEED_DEBUG_ENABLED
12443 }
12444 }
12445 else
12446 {
12447 // report current rate instead of max rate
12448
12449 if (rate_flags & eHAL_TX_RATE_LEGACY)
12450 {
12451 //provide to the UI in units of 100kbps
12452 sinfo->txrate.legacy = myRate;
12453#ifdef LINKSPEED_DEBUG_ENABLED
12454 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
12455#endif //LINKSPEED_DEBUG_ENABLED
12456 }
12457 else
12458 {
12459 //must be MCS
12460 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070012461#ifdef WLAN_FEATURE_11AC
12462 sinfo->txrate.nss = 1;
12463 if (rate_flags & eHAL_TX_RATE_VHT80)
12464 {
12465 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12466 }
12467 else
12468#endif /* WLAN_FEATURE_11AC */
12469 {
12470 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12471 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012472 if (rate_flags & eHAL_TX_RATE_SGI)
12473 {
12474 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12475 }
12476 if (rate_flags & eHAL_TX_RATE_HT40)
12477 {
12478 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12479 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012480#ifdef WLAN_FEATURE_11AC
12481 else if (rate_flags & eHAL_TX_RATE_VHT80)
12482 {
12483 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
12484 }
12485#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070012486#ifdef LINKSPEED_DEBUG_ENABLED
12487 pr_info("Reporting actual MCS rate %d flags %x\n",
12488 sinfo->txrate.mcs,
12489 sinfo->txrate.flags );
12490#endif //LINKSPEED_DEBUG_ENABLED
12491 }
12492 }
12493 sinfo->filled |= STATION_INFO_TX_BITRATE;
12494
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012495 sinfo->tx_packets =
12496 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
12497 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
12498 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
12499 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
12500
12501 sinfo->tx_retries =
12502 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
12503 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
12504 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
12505 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
12506
12507 sinfo->tx_failed =
12508 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
12509 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
12510 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
12511 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
12512
12513 sinfo->filled |=
12514 STATION_INFO_TX_PACKETS |
12515 STATION_INFO_TX_RETRIES |
12516 STATION_INFO_TX_FAILED;
12517
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012518 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12519 TRACE_CODE_HDD_CFG80211_GET_STA,
12520 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012521 EXIT();
12522 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012523}
12524
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012525static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
12526 u8* mac, struct station_info *sinfo)
12527{
12528 int ret;
12529
12530 vos_ssr_protect(__func__);
12531 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
12532 vos_ssr_unprotect(__func__);
12533
12534 return ret;
12535}
12536
12537static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070012538 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070012539{
12540 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012541 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012542 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012543 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012544
Jeff Johnsone7245742012-09-05 17:12:55 -070012545 ENTER();
12546
Jeff Johnson295189b2012-06-20 16:38:30 -070012547 if (NULL == pAdapter)
12548 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012549 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012550 return -ENODEV;
12551 }
12552
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012553 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12554 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
12555 pAdapter->sessionId, timeout));
12556
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012557 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012558 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012559
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012560 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012561 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12563 "%s: HDD context is not valid", __func__);
12564 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012565 }
12566
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012567 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
12568 (TRUE == pHddCtx->hdd_wlan_suspended) &&
12569 (pHddCtx->cfg_ini->fhostArpOffload) &&
12570 (eConnectionState_Associated ==
12571 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12572 {
Amar Singhald53568e2013-09-26 11:03:45 -070012573
12574 hddLog(VOS_TRACE_LEVEL_INFO,
12575 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053012576 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012577 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12578 {
12579 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012580 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012581 __func__, vos_status);
12582 }
12583 }
12584
Jeff Johnson295189b2012-06-20 16:38:30 -070012585 /**The get power cmd from the supplicant gets updated by the nl only
12586 *on successful execution of the function call
12587 *we are oppositely mapped w.r.t mode in the driver
12588 **/
12589 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
12590
Jeff Johnsone7245742012-09-05 17:12:55 -070012591 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012592 if (VOS_STATUS_E_FAILURE == vos_status)
12593 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012594 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12595 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012596 return -EINVAL;
12597 }
12598 return 0;
12599}
12600
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012601static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
12602 struct net_device *dev, bool mode, int timeout)
12603{
12604 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012605
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012606 vos_ssr_protect(__func__);
12607 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
12608 vos_ssr_unprotect(__func__);
12609
12610 return ret;
12611}
Jeff Johnson295189b2012-06-20 16:38:30 -070012612#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12613static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
12614 struct net_device *netdev,
12615 u8 key_index)
12616{
Jeff Johnsone7245742012-09-05 17:12:55 -070012617 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012618 return 0;
12619}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012620#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070012621
12622#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
12623static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12624 struct net_device *dev,
12625 struct ieee80211_txq_params *params)
12626{
Jeff Johnsone7245742012-09-05 17:12:55 -070012627 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012628 return 0;
12629}
12630#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12631static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12632 struct ieee80211_txq_params *params)
12633{
Jeff Johnsone7245742012-09-05 17:12:55 -070012634 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012635 return 0;
12636}
12637#endif //LINUX_VERSION_CODE
12638
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012639#ifdef CFG80211_DEL_STA_V2
12640static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
12641 struct net_device *dev,
12642 struct station_del_parameters *param)
12643#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012644static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012645 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012646#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012647{
12648 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012649 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012650 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012651 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012652 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -070012653
Jeff Johnsone7245742012-09-05 17:12:55 -070012654 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012655
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012656 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070012657 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012658 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012659 return -EINVAL;
12660 }
12661
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012662 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12663 TRACE_CODE_HDD_CFG80211_DEL_STA,
12664 pAdapter->sessionId, pAdapter->device_mode));
12665
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012666 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12667 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012668
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012669 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012670 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12672 "%s: HDD context is not valid", __func__);
12673 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012674 }
12675
Jeff Johnson295189b2012-06-20 16:38:30 -070012676 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012677 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012678 )
12679 {
12680 if( NULL == mac )
12681 {
12682 v_U16_t i;
12683 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
12684 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012685 if ((pAdapter->aStaInfo[i].isUsed) &&
12686 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070012687 {
12688 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
12689 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012690 "%s: Delete STA with MAC::"
12691 MAC_ADDRESS_STR,
12692 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012693 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
12694 if (VOS_IS_STATUS_SUCCESS(vos_status))
12695 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012696 }
12697 }
12698 }
12699 else
12700 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012701
12702 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
12703 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12704 {
12705 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012706 "%s: Skip this DEL STA as this is not used::"
12707 MAC_ADDRESS_STR,
12708 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012709 return -ENOENT;
12710 }
12711
12712 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
12713 {
12714 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012715 "%s: Skip this DEL STA as deauth is in progress::"
12716 MAC_ADDRESS_STR,
12717 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012718 return -ENOENT;
12719 }
12720
12721 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
12722
Jeff Johnson295189b2012-06-20 16:38:30 -070012723 hddLog(VOS_TRACE_LEVEL_INFO,
12724 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080012725 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012726 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080012727 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012728
12729 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
12730 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12731 {
12732 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
12733 hddLog(VOS_TRACE_LEVEL_INFO,
12734 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080012735 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012736 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080012737 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012738 return -ENOENT;
12739 }
12740
Jeff Johnson295189b2012-06-20 16:38:30 -070012741 }
12742 }
12743
12744 EXIT();
12745
12746 return 0;
12747}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012748
12749#ifdef CFG80211_DEL_STA_V2
12750static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
12751 struct net_device *dev,
12752 struct station_del_parameters *param)
12753#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012754static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
12755 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012756#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012757{
12758 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012759
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012760 vos_ssr_protect(__func__);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012761#ifdef CFG80211_DEL_STA_V2
12762 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, param);
12763#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012764 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, mac);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012765#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012766 vos_ssr_unprotect(__func__);
12767
12768 return ret;
12769}
12770
12771static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012772 struct net_device *dev, u8 *mac, struct station_parameters *params)
12773{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012774 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012775 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012776#ifdef FEATURE_WLAN_TDLS
12777 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012778 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012779
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012780 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12781 TRACE_CODE_HDD_CFG80211_ADD_STA,
12782 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012783 mask = params->sta_flags_mask;
12784
12785 set = params->sta_flags_set;
12786
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012787#ifdef WLAN_FEATURE_TDLS_DEBUG
12788 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12789 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
12790 __func__, mask, set, MAC_ADDR_ARRAY(mac));
12791#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012792
12793 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12794 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012795 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012796 }
12797 }
12798#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012799 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012800}
12801
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012802static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
12803 struct net_device *dev, u8 *mac, struct station_parameters *params)
12804{
12805 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012806
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012807 vos_ssr_protect(__func__);
12808 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
12809 vos_ssr_unprotect(__func__);
12810
12811 return ret;
12812}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012813#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070012814
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012815static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070012816 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012817{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012818 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12819 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012820 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012821 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012822 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012823 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070012824
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012825 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012826 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012827 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012828 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012829 return -EINVAL;
12830 }
12831
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012832 if (!pmksa) {
12833 hddLog(LOGE, FL("pmksa is NULL"));
12834 return -EINVAL;
12835 }
12836
12837 if (!pmksa->bssid || !pmksa->pmkid) {
12838 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
12839 pmksa->bssid, pmksa->pmkid);
12840 return -EINVAL;
12841 }
12842
12843 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
12844 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
12845
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012846 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12847 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012848
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012849 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012850 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012851 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12852 "%s: HDD context is not valid", __func__);
12853 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012854 }
12855
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012856 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012857 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
12858
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012859 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
12860 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012861
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012862 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012863 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012864 &pmk_id, 1, FALSE);
12865
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012866 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12867 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
12868 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012869
12870 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012871}
12872
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012873static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
12874 struct cfg80211_pmksa *pmksa)
12875{
12876 int ret;
12877
12878 vos_ssr_protect(__func__);
12879 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
12880 vos_ssr_unprotect(__func__);
12881
12882 return ret;
12883}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012884
Wilson Yang6507c4e2013-10-01 20:11:19 -070012885
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012886static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070012887 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012888{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012889 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12890 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012891 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080012892 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012893
Wilson Yang6507c4e2013-10-01 20:11:19 -070012894 /* Validate pAdapter */
12895 if (NULL == pAdapter)
12896 {
12897 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
12898 return -EINVAL;
12899 }
12900
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012901 if (!pmksa) {
12902 hddLog(LOGE, FL("pmksa is NULL"));
12903 return -EINVAL;
12904 }
12905
12906 if (!pmksa->bssid) {
12907 hddLog(LOGE, FL("pmksa->bssid is NULL"));
12908 return -EINVAL;
12909 }
12910
Kiet Lam98c46a12014-10-31 15:34:57 -070012911 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
12912 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
12913
Wilson Yang6507c4e2013-10-01 20:11:19 -070012914 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12915 status = wlan_hdd_validate_context(pHddCtx);
12916
12917 if (0 != status)
12918 {
12919 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12920 "%s: HDD context is not valid", __func__);
12921 return status;
12922 }
12923
12924 /*Retrieve halHandle*/
12925 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
12926
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012927 /* Delete the PMKID CSR cache */
12928 if (eHAL_STATUS_SUCCESS !=
12929 sme_RoamDelPMKIDfromCache(halHandle,
12930 pAdapter->sessionId, pmksa->bssid, FALSE)) {
12931 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
12932 MAC_ADDR_ARRAY(pmksa->bssid));
12933 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012934 }
12935
Wilson Yangef657d32014-01-15 19:19:23 -080012936 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012937}
12938
Wilson Yang6507c4e2013-10-01 20:11:19 -070012939
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012940static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
12941 struct cfg80211_pmksa *pmksa)
12942{
12943 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012944
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012945 vos_ssr_protect(__func__);
12946 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
12947 vos_ssr_unprotect(__func__);
12948
12949 return ret;
12950
12951}
12952
12953static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012954{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012955 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12956 tHalHandle halHandle;
12957 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080012958 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012959
12960 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
12961
12962 /* Validate pAdapter */
12963 if (NULL == pAdapter)
12964 {
12965 hddLog(VOS_TRACE_LEVEL_ERROR,
12966 "%s: Invalid Adapter" ,__func__);
12967 return -EINVAL;
12968 }
12969
12970 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12971 status = wlan_hdd_validate_context(pHddCtx);
12972
12973 if (0 != status)
12974 {
12975 hddLog(VOS_TRACE_LEVEL_ERROR,
12976 "%s: HDD context is not valid", __func__);
12977 return status;
12978 }
12979
12980 /*Retrieve halHandle*/
12981 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
12982
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012983 /* Flush the PMKID cache in CSR */
12984 if (eHAL_STATUS_SUCCESS !=
12985 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
12986 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
12987 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012988 }
12989
Wilson Yangef657d32014-01-15 19:19:23 -080012990 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012991}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012992
12993static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
12994{
12995 int ret;
12996
12997 vos_ssr_protect(__func__);
12998 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
12999 vos_ssr_unprotect(__func__);
13000
13001 return ret;
13002}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013003#endif
13004
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013005#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013006static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13007 struct net_device *dev,
13008 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013009{
13010 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13011 hdd_station_ctx_t *pHddStaCtx;
13012
13013 if (NULL == pAdapter)
13014 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013015 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013016 return -ENODEV;
13017 }
13018
13019 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13020
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013021 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13022 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
13023 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013024 // Added for debug on reception of Re-assoc Req.
13025 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
13026 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013027 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013028 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080013029 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013030 }
13031
13032#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080013033 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013034 ftie->ie_len);
13035#endif
13036
13037 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013038 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13039 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013040 ftie->ie_len);
13041 return 0;
13042}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013043
13044static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13045 struct net_device *dev,
13046 struct cfg80211_update_ft_ies_params *ftie)
13047{
13048 int ret;
13049
13050 vos_ssr_protect(__func__);
13051 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
13052 vos_ssr_unprotect(__func__);
13053
13054 return ret;
13055}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013056#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013057
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013058#ifdef FEATURE_WLAN_SCAN_PNO
13059
13060void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
13061 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
13062{
13063 int ret;
13064 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
13065 hdd_context_t *pHddCtx;
13066
Nirav Shah80830bf2013-12-31 16:35:12 +053013067 ENTER();
13068
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013069 if (NULL == pAdapter)
13070 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013071 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013072 "%s: HDD adapter is Null", __func__);
13073 return ;
13074 }
13075
13076 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13077 if (NULL == pHddCtx)
13078 {
13079 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13080 "%s: HDD context is Null!!!", __func__);
13081 return ;
13082 }
13083
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013084 spin_lock(&pHddCtx->schedScan_lock);
13085 if (TRUE == pHddCtx->isWiphySuspended)
13086 {
13087 pHddCtx->isSchedScanUpdatePending = TRUE;
13088 spin_unlock(&pHddCtx->schedScan_lock);
13089 hddLog(VOS_TRACE_LEVEL_INFO,
13090 "%s: Update cfg80211 scan database after it resume", __func__);
13091 return ;
13092 }
13093 spin_unlock(&pHddCtx->schedScan_lock);
13094
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013095 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
13096
13097 if (0 > ret)
13098 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
13099
13100 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013101 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13102 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013103}
13104
13105/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013106 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013107 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013108 */
13109static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
13110{
13111 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13112 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013113 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013114 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13115 int status = 0;
13116 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13117
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013118 /* The current firmware design does not allow PNO during any
13119 * active sessions. Hence, determine the active sessions
13120 * and return a failure.
13121 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013122 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
13123 {
13124 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013125 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013126
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013127 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
13128 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
13129 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
13130 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
13131 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
13132 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013133 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013134 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013135 }
13136 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13137 pAdapterNode = pNext;
13138 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013139 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013140}
13141
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013142void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
13143{
13144 hdd_adapter_t *pAdapter = callbackContext;
13145 hdd_context_t *pHddCtx;
13146
13147 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
13148 {
13149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13150 FL("Invalid adapter or adapter has invalid magic"));
13151 return;
13152 }
13153
13154 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13155 if (0 != wlan_hdd_validate_context(pHddCtx))
13156 {
13157 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13158 FL("HDD context is not valid"));
13159 return;
13160 }
13161
c_hpothub53c45d2014-08-18 16:53:14 +053013162 if (VOS_STATUS_SUCCESS != status)
13163 {
13164 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013165 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053013166 pHddCtx->isPnoEnable = FALSE;
13167 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013168
13169 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
13170 complete(&pAdapter->pno_comp_var);
13171}
13172
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013173/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013174 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
13175 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013176 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013177static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013178 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13179{
13180 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13181 tpSirPNOScanReq pPnoRequest = NULL;
13182 hdd_context_t *pHddCtx;
13183 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013184 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053013185 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
13186 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013187 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13188 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013189 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013190
13191 if (NULL == pAdapter)
13192 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013194 "%s: HDD adapter is Null", __func__);
13195 return -ENODEV;
13196 }
13197
13198 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013199 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013200
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013201 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013202 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013203 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13204 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013205 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013206 }
13207
13208 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13209 if (NULL == hHal)
13210 {
13211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13212 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013213 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013214 }
Sushant Kaushik2fe89932014-09-03 10:58:09 +053013215 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013216 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053013217 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013218 {
13219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13220 "%s: aborting the existing scan is unsuccessfull", __func__);
13221 return -EBUSY;
13222 }
13223
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013224 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013225 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013227 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013228 return -EBUSY;
13229 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013230
c_hpothu37f21312014-04-09 21:49:54 +053013231 if (TRUE == pHddCtx->isPnoEnable)
13232 {
13233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13234 FL("already PNO is enabled"));
13235 return -EBUSY;
13236 }
c_hpothu225aa7c2014-10-22 17:45:13 +053013237
13238 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
13239 {
13240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13241 "%s: abort ROC failed ", __func__);
13242 return -EBUSY;
13243 }
13244
c_hpothu37f21312014-04-09 21:49:54 +053013245 pHddCtx->isPnoEnable = TRUE;
13246
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013247 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13248 if (NULL == pPnoRequest)
13249 {
13250 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13251 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053013252 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013253 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013254 }
13255
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053013256 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013257 pPnoRequest->enable = 1; /*Enable PNO */
13258 pPnoRequest->ucNetworksCount = request->n_match_sets;
13259
13260 if (( !pPnoRequest->ucNetworksCount ) ||
13261 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
13262 {
13263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013264 "%s: Network input is not correct %d Max Network supported is %d",
13265 __func__, pPnoRequest->ucNetworksCount,
13266 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013267 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013268 goto error;
13269 }
13270
13271 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
13272 {
13273 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013274 "%s: Incorrect number of channels %d",
13275 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013276 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013277 goto error;
13278 }
13279
13280 /* Framework provides one set of channels(all)
13281 * common for all saved profile */
13282 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13283 channels_allowed, &num_channels_allowed))
13284 {
13285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13286 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013287 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013288 goto error;
13289 }
13290 /* Checking each channel against allowed channel list */
13291 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053013292 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013293 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013294 char chList [(request->n_channels*5)+1];
13295 int len;
13296 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013297 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013298 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013299 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013300 if (request->channels[i]->hw_value == channels_allowed[indx])
13301 {
13302 valid_ch[num_ch++] = request->channels[i]->hw_value;
13303 len += snprintf(chList+len, 5, "%d ",
13304 request->channels[i]->hw_value);
13305 break ;
13306 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013307 }
13308 }
Nirav Shah80830bf2013-12-31 16:35:12 +053013309 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
13310 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013311
13312 /* Filling per profile params */
13313 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
13314 {
13315 pPnoRequest->aNetworks[i].ssId.length =
13316 request->match_sets[i].ssid.ssid_len;
13317
13318 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
13319 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
13320 {
13321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013322 "%s: SSID Len %d is not correct for network %d",
13323 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013324 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013325 goto error;
13326 }
13327
13328 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
13329 request->match_sets[i].ssid.ssid,
13330 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013331 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13332 "%s: SSID of network %d is %s ", __func__,
13333 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013334 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
13335 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
13336 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
13337
13338 /*Copying list of valid channel into request */
13339 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
13340 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
13341
13342 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
13343 }
13344
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013345 for (i = 0; i < request->n_ssids; i++)
13346 {
13347 j = 0;
13348 while (j < pPnoRequest->ucNetworksCount)
13349 {
13350 if ((pPnoRequest->aNetworks[j].ssId.length ==
13351 request->ssids[i].ssid_len) &&
13352 (0 == memcmp(pPnoRequest->aNetworks[j].ssId.ssId,
13353 request->ssids[i].ssid,
13354 pPnoRequest->aNetworks[j].ssId.length)))
13355 {
13356 pPnoRequest->aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
13357 break;
13358 }
13359 j++;
13360 }
13361 }
13362 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13363 "Number of hidden networks being Configured = %d",
13364 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080013366 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013367 if ((0 < request->ie_len) && (NULL != request->ie))
13368 {
13369 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
13370 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
13371 pPnoRequest->us24GProbeTemplateLen);
13372
13373 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
13374 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
13375 pPnoRequest->us5GProbeTemplateLen);
13376 }
13377
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053013378 /* Driver gets only one time interval which is hardcoded in
13379 * supplicant for 10000ms. Taking power consumption into account 6 timers
13380 * will be used, Timervalue is increased exponentially i.e 10,20,40,
13381 * 80,160,320 secs. And number of scan cycle for each timer
13382 * is configurable through INI param gPNOScanTimerRepeatValue.
13383 * If it is set to 0 only one timer will be used and PNO scan cycle
13384 * will be repeated after each interval specified by supplicant
13385 * till PNO is disabled.
13386 */
13387 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
13388 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
13389 else
13390 pPnoRequest->scanTimers.ucScanTimersCount =
13391 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
13392
13393 tempInterval = (request->interval)/1000;
13394 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13395 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
13396 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
13397 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
13398 {
13399 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
13400 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
13401 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
13402 tempInterval *= 2;
13403 }
13404 //Repeat last timer until pno disabled.
13405 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
13406
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053013407 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013408
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013409 INIT_COMPLETION(pAdapter->pno_comp_var);
13410 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
13411 pPnoRequest->callbackContext = pAdapter;
13412 pAdapter->pno_req_status = 0;
13413
Nirav Shah80830bf2013-12-31 16:35:12 +053013414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13415 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
13416 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
13417 pPnoRequest->scanTimers.ucScanTimersCount);
13418
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013419 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
13420 pPnoRequest, pAdapter->sessionId,
13421 hdd_cfg80211_sched_scan_done_callback, pAdapter);
13422 if (eHAL_STATUS_SUCCESS != status)
13423 {
13424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013425 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013426 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013427 goto error;
13428 }
13429
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013430 ret = wait_for_completion_timeout(
13431 &pAdapter->pno_comp_var,
13432 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
13433 if (0 >= ret)
13434 {
13435 // Did not receive the response for PNO enable in time.
13436 // Assuming the PNO enable was success.
13437 // Returning error from here, because we timeout, results
13438 // in side effect of Wifi (Wifi Setting) not to work.
13439 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13440 FL("Timed out waiting for PNO to be Enabled"));
13441 ret = 0;
13442 goto error;
13443 }
13444
c_hpothu3c986b22014-07-09 14:45:09 +053013445 vos_mem_free(pPnoRequest);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013446 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053013447 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013448
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013449error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13451 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013452 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053013453 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013454 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013455}
13456
13457/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013458 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
13459 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013460 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013461static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
13462 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13463{
13464 int ret;
13465
13466 vos_ssr_protect(__func__);
13467 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
13468 vos_ssr_unprotect(__func__);
13469
13470 return ret;
13471}
13472
13473/*
13474 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
13475 * Function to disable PNO
13476 */
13477static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013478 struct net_device *dev)
13479{
13480 eHalStatus status = eHAL_STATUS_FAILURE;
13481 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13482 hdd_context_t *pHddCtx;
13483 tHalHandle hHal;
13484 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013485 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013486
13487 ENTER();
13488
13489 if (NULL == pAdapter)
13490 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013491 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013492 "%s: HDD adapter is Null", __func__);
13493 return -ENODEV;
13494 }
13495
13496 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013497
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013498 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013499 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013501 "%s: HDD context is Null", __func__);
13502 return -ENODEV;
13503 }
13504
13505 /* The return 0 is intentional when isLogpInProgress and
13506 * isLoadUnloadInProgress. We did observe a crash due to a return of
13507 * failure in sched_scan_stop , especially for a case where the unload
13508 * of the happens at the same time. The function __cfg80211_stop_sched_scan
13509 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
13510 * success. If it returns a failure , then its next invocation due to the
13511 * clean up of the second interface will have the dev pointer corresponding
13512 * to the first one leading to a crash.
13513 */
13514 if (pHddCtx->isLogpInProgress)
13515 {
13516 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13517 "%s: LOGP in Progress. Ignore!!!", __func__);
13518 return ret;
13519 }
13520
Mihir Shete18156292014-03-11 15:38:30 +053013521 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013522 {
13523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13524 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13525 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013526 }
13527
13528 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13529 if (NULL == hHal)
13530 {
13531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13532 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013533 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013534 }
13535
13536 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13537 if (NULL == pPnoRequest)
13538 {
13539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13540 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013541 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013542 }
13543
13544 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
13545 pPnoRequest->enable = 0; /* Disable PNO */
13546 pPnoRequest->ucNetworksCount = 0;
13547
13548 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
13549 pAdapter->sessionId,
13550 NULL, pAdapter);
13551 if (eHAL_STATUS_SUCCESS != status)
13552 {
13553 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13554 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013555 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013556 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013557 }
c_hpothu37f21312014-04-09 21:49:54 +053013558 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013559
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013560error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013562 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013563 vos_mem_free(pPnoRequest);
13564
13565 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013566 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013567}
13568
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013569/*
13570 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
13571 * NL interface to disable PNO
13572 */
13573static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
13574 struct net_device *dev)
13575{
13576 int ret;
13577
13578 vos_ssr_protect(__func__);
13579 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
13580 vos_ssr_unprotect(__func__);
13581
13582 return ret;
13583}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013584#endif /*FEATURE_WLAN_SCAN_PNO*/
13585
13586
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013587#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013588#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013589static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
13590 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013591 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
13592#else
13593static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
13594 u8 *peer, u8 action_code, u8 dialog_token,
13595 u16 status_code, const u8 *buf, size_t len)
13596#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013597{
13598
13599 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13600 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013601 u8 peerMac[6];
13602 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070013603 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080013604 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070013605 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013606#if !(TDLS_MGMT_VERSION2)
13607 u32 peer_capability = 0;
13608#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013609 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013610
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013611 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13612 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
13613 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013614 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013615 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013617 "Invalid arguments");
13618 return -EINVAL;
13619 }
13620
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013621 if (pHddCtx->isLogpInProgress)
13622 {
13623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13624 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053013625 wlan_hdd_tdls_set_link_status(pAdapter,
13626 peer,
13627 eTDLS_LINK_IDLE,
13628 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013629 return -EBUSY;
13630 }
13631
Hoonki Lee27511902013-03-14 18:19:06 -070013632 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013633 {
Hoonki Lee27511902013-03-14 18:19:06 -070013634 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13635 "%s: TDLS mode is disabled OR not enabled in FW."
13636 MAC_ADDRESS_STR " action %d declined.",
13637 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013638 return -ENOTSUPP;
13639 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013640
Hoonki Lee27511902013-03-14 18:19:06 -070013641 /* other than teardown frame, other mgmt frames are not sent if disabled */
13642 if (SIR_MAC_TDLS_TEARDOWN != action_code)
13643 {
13644 /* if tdls_mode is disabled to respond to peer's request */
13645 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
13646 {
13647 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13648 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013649 " TDLS mode is disabled. action %d declined.",
13650 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070013651
13652 return -ENOTSUPP;
13653 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053013654
13655 if (vos_max_concurrent_connections_reached())
13656 {
13657 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13658 return -EINVAL;
13659 }
Hoonki Lee27511902013-03-14 18:19:06 -070013660 }
13661
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013662 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
13663 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013664 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013665 {
13666 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013667 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013668 " TDLS setup is ongoing. action %d declined.",
13669 __func__, MAC_ADDR_ARRAY(peer), action_code);
13670 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013671 }
13672 }
13673
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013674 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
13675 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080013676 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013677 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
13678 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080013679 {
13680 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
13681 we return error code at 'add_station()'. Hence we have this
13682 check again in addtion to add_station().
13683 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013684 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080013685 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13687 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013688 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
13689 __func__, MAC_ADDR_ARRAY(peer), action_code,
13690 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013691 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080013692 }
13693 else
13694 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013695 /* maximum reached. tweak to send error code to peer and return
13696 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080013697 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013698 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13699 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013700 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
13701 __func__, MAC_ADDR_ARRAY(peer), status_code,
13702 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013703 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013704 /* fall through to send setup resp with failure status
13705 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080013706 }
13707 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013708 else
13709 {
13710 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013711 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013712 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013713 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013715 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
13716 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013717 return -EPERM;
13718 }
13719 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013720 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013721 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013722
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013723#ifdef WLAN_FEATURE_TDLS_DEBUG
13724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053013725 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013726 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
13727 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013728#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013729
Hoonki Leea34dd892013-02-05 22:56:02 -080013730 /*Except teardown responder will not be used so just make 0*/
13731 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013732 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080013733 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013734
13735 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013736 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013737
13738 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
13739 responder = pTdlsPeer->is_responder;
13740 else
Hoonki Leea34dd892013-02-05 22:56:02 -080013741 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053013743 "%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 -070013744 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
13745 dialog_token, status_code, len);
13746 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080013747 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013748 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013749
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013750 /* For explicit trigger of DIS_REQ come out of BMPS for
13751 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070013752 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013753 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
13754 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070013755 {
13756 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
13757 {
13758 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013759 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070013760 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
13761 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013762 if (SIR_MAC_TDLS_DIS_REQ != action_code)
13763 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070013764 }
13765
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013766 /* make sure doesn't call send_mgmt() while it is pending */
13767 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
13768 {
13769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013770 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013771 __func__, MAC_ADDR_ARRAY(peer), action_code);
13772 return -EBUSY;
13773 }
13774
13775 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013776 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
13777
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013778 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053013779 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013780
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013781 if (VOS_STATUS_SUCCESS != status)
13782 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13784 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013785 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -070013786 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013787 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013788 }
13789
Hoonki Leed37cbb32013-04-20 00:31:14 -070013790 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
13791 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
13792
13793 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013794 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070013795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013796 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070013797 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013798 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080013799
13800 if (pHddCtx->isLogpInProgress)
13801 {
13802 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13803 "%s: LOGP in Progress. Ignore!!!", __func__);
13804 return -EAGAIN;
13805 }
13806
Hoonki Leed37cbb32013-04-20 00:31:14 -070013807 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013808 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013809 }
13810
Gopichand Nakkala05922802013-03-14 12:23:19 -070013811 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070013812 {
13813 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013814 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070013815 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013816
Hoonki Leea34dd892013-02-05 22:56:02 -080013817 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
13818 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013819 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080013820 }
13821 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
13822 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013823 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080013824 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013825
13826 return 0;
13827}
13828
Atul Mittal115287b2014-07-08 13:26:33 +053013829
13830int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
13831 u8 *peer,
13832 cfg80211_exttdls_callback callback)
13833{
13834
13835 hddTdlsPeer_t *pTdlsPeer;
13836 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13837 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13838 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
13839 __func__, MAC_ADDR_ARRAY(peer));
13840
13841 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13842 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13843
13844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13845 " %s TDLS External control and Implicit Trigger not enabled ",
13846 __func__);
13847 return -ENOTSUPP;
13848 }
13849
13850 /* To cater the requirement of establishing the TDLS link
13851 * irrespective of the data traffic , get an entry of TDLS peer.
13852 */
13853 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
13854 if (pTdlsPeer == NULL) {
13855 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13856 "%s: peer " MAC_ADDRESS_STR " not existing",
13857 __func__, MAC_ADDR_ARRAY(peer));
13858 return -EINVAL;
13859 }
13860
13861 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
13862
13863 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13864 " %s TDLS Add Force Peer Failed",
13865 __func__);
13866 return -EINVAL;
13867 }
13868 /*EXT TDLS*/
13869
13870 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
13871 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13872 " %s TDLS set callback Failed",
13873 __func__);
13874 return -EINVAL;
13875 }
13876
13877 return(0);
13878
13879}
13880
13881int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
13882{
13883
13884 hddTdlsPeer_t *pTdlsPeer;
13885 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13887 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
13888 __func__, MAC_ADDR_ARRAY(peer));
13889
13890 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13891 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13892
13893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13894 " %s TDLS External control and Implicit Trigger not enabled ",
13895 __func__);
13896 return -ENOTSUPP;
13897 }
13898
13899
13900 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13901
13902 if ( NULL == pTdlsPeer ) {
13903 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
13904 " peer not exsting",
13905 __func__, MAC_ADDR_ARRAY(peer));
13906 return -EINVAL;
13907 }
13908 else {
13909 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
13910 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
13911 }
13912
13913 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
13914 return -EINVAL;
13915
13916 /*EXT TDLS*/
13917
13918 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
13919
13920 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13921 " %s TDLS set callback Failed",
13922 __func__);
13923 return -EINVAL;
13924 }
13925 return(0);
13926
13927}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013928static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013929 u8 *peer, enum nl80211_tdls_operation oper)
13930{
13931 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13932 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013933 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013934 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013935
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013936 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13937 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
13938 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013939 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013940 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070013942 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013943 return -EINVAL;
13944 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013945
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013946 status = wlan_hdd_validate_context(pHddCtx);
13947
13948 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013949 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13951 "%s: HDD context is not valid", __func__);
13952 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013953 }
13954
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013955
13956 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013957 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013958 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013959 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070013960 "TDLS Disabled in INI OR not enabled in FW. "
13961 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013962 return -ENOTSUPP;
13963 }
13964
13965 switch (oper) {
13966 case NL80211_TDLS_ENABLE_LINK:
13967 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013968 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013969 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013970 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013971
Sunil Dutt41de4e22013-11-14 18:09:02 +053013972 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13973
13974 if ( NULL == pTdlsPeer ) {
13975 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13976 " (oper %d) not exsting. ignored",
13977 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13978 return -EINVAL;
13979 }
13980
13981 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13982 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13983 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13984 "NL80211_TDLS_ENABLE_LINK");
13985
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070013986 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
13987 {
13988 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
13989 MAC_ADDRESS_STR " failed",
13990 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
13991 return -EINVAL;
13992 }
13993
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013994 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013995 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013996 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053013997
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013998 if (0 != wlan_hdd_tdls_get_link_establish_params(
13999 pAdapter, peer,&tdlsLinkEstablishParams)) {
14000 return -EINVAL;
14001 }
14002 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014003
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014004 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
14005 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
14006 /* Send TDLS peer UAPSD capabilities to the firmware and
14007 * register with the TL on after the response for this operation
14008 * is received .
14009 */
14010 ret = wait_for_completion_interruptible_timeout(
14011 &pAdapter->tdls_link_establish_req_comp,
14012 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
14013 if (ret <= 0)
14014 {
14015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14016 "%s: Link Establish Request Faled Status %ld",
14017 __func__, ret);
14018 return -EINVAL;
14019 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014020 }
Atul Mittal115287b2014-07-08 13:26:33 +053014021 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
14022 eTDLS_LINK_CONNECTED,
14023 eTDLS_LINK_SUCCESS);
Gopichand Nakkala471708b2013-06-04 20:03:01 +053014024 /* Mark TDLS client Authenticated .*/
14025 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
14026 pTdlsPeer->staId,
14027 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014028 if (VOS_STATUS_SUCCESS == status)
14029 {
Hoonki Lee14621352013-04-16 17:51:19 -070014030 if (pTdlsPeer->is_responder == 0)
14031 {
14032 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
14033
14034 wlan_hdd_tdls_timer_restart(pAdapter,
14035 &pTdlsPeer->initiatorWaitTimeoutTimer,
14036 WAIT_TIME_TDLS_INITIATOR);
14037 /* suspend initiator TX until it receives direct packet from the
14038 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
14039 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
14040 &staId, NULL);
14041 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014042 wlan_hdd_tdls_increment_peer_count(pAdapter);
14043 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014044 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014045
14046 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053014047 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
14048 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014049 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053014050 int ac;
14051 uint8 ucAc[4] = { WLANTL_AC_VO,
14052 WLANTL_AC_VI,
14053 WLANTL_AC_BK,
14054 WLANTL_AC_BE };
14055 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
14056 for(ac=0; ac < 4; ac++)
14057 {
14058 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
14059 pTdlsPeer->staId, ucAc[ac],
14060 tlTid[ac], tlTid[ac], 0, 0,
14061 WLANTL_BI_DIR );
14062 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014063 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014064 }
14065
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014066 }
14067 break;
14068 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080014069 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053014070 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
14071
14072 if ( NULL == pTdlsPeer ) {
14073 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
14074 " (oper %d) not exsting. ignored",
14075 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
14076 return -EINVAL;
14077 }
14078
14079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14080 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
14081 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
14082 "NL80211_TDLS_DISABLE_LINK");
14083
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014084 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080014085 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014086 long status;
14087
Atul Mittal271a7652014-09-12 13:18:22 +053014088
14089 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
14090 eTDLS_LINK_TEARING,
14091 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
14092 eTDLS_LINK_UNSPECIFIED:
14093 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014094 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
14095
Lee Hoonkic1262f22013-01-24 21:59:00 -080014096 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
14097 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014098
14099 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
14100 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053014101 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053014102 eTDLS_LINK_IDLE,
14103 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014104 if (status <= 0)
14105 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014106 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14107 "%s: Del station failed status %ld",
14108 __func__, status);
14109 return -EPERM;
14110 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014111 }
14112 else
14113 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014114 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14115 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080014116 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014117 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014118 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014119 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053014120 {
Atul Mittal115287b2014-07-08 13:26:33 +053014121 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053014122
Atul Mittal115287b2014-07-08 13:26:33 +053014123 if (0 != status)
14124 {
14125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14126 "%s: Error in TDLS Teardown", __func__);
14127 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053014128 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053014129 break;
14130 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014131 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053014132 {
Atul Mittal115287b2014-07-08 13:26:33 +053014133 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
14134 peer,
14135 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053014136
Atul Mittal115287b2014-07-08 13:26:33 +053014137 if (0 != status)
14138 {
14139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14140 "%s: Error in TDLS Setup", __func__);
14141 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053014142 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053014143 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053014144 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014145 case NL80211_TDLS_DISCOVERY_REQ:
14146 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14148 "%s: We don't support in-driver setup/teardown/discovery "
14149 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014150 return -ENOTSUPP;
14151 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14153 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014154 return -ENOTSUPP;
14155 }
14156 return 0;
14157}
Chilam NG571c65a2013-01-19 12:27:36 +053014158
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014159static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
14160 u8 *peer, enum nl80211_tdls_operation oper)
14161{
14162 int ret;
14163
14164 vos_ssr_protect(__func__);
14165 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
14166 vos_ssr_unprotect(__func__);
14167
14168 return ret;
14169}
14170
Chilam NG571c65a2013-01-19 12:27:36 +053014171int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
14172 struct net_device *dev, u8 *peer)
14173{
Arif Hussaina7c8e412013-11-20 11:06:42 -080014174 hddLog(VOS_TRACE_LEVEL_INFO,
14175 "tdls send discover req: "MAC_ADDRESS_STR,
14176 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053014177
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014178#if TDLS_MGMT_VERSION2
14179 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14180 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
14181#else
Chilam NG571c65a2013-01-19 12:27:36 +053014182 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14183 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014184#endif
Chilam NG571c65a2013-01-19 12:27:36 +053014185}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014186#endif
14187
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014188#ifdef WLAN_FEATURE_GTK_OFFLOAD
14189/*
14190 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
14191 * Callback rountine called upon receiving response for
14192 * get offload info
14193 */
14194void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
14195 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
14196{
14197
14198 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014199 tANI_U8 tempReplayCounter[8];
14200 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014201
14202 ENTER();
14203
14204 if (NULL == pAdapter)
14205 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014207 "%s: HDD adapter is Null", __func__);
14208 return ;
14209 }
14210
14211 if (NULL == pGtkOffloadGetInfoRsp)
14212 {
14213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14214 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
14215 return ;
14216 }
14217
14218 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
14219 {
14220 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14221 "%s: wlan Failed to get replay counter value",
14222 __func__);
14223 return ;
14224 }
14225
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014226 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14227 /* Update replay counter */
14228 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
14229 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14230
14231 {
14232 /* changing from little to big endian since supplicant
14233 * works on big endian format
14234 */
14235 int i;
14236 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14237
14238 for (i = 0; i < 8; i++)
14239 {
14240 tempReplayCounter[7-i] = (tANI_U8)p[i];
14241 }
14242 }
14243
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014244 /* Update replay counter to NL */
14245 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014246 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014247}
14248
14249/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014250 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014251 * This function is used to offload GTK rekeying job to the firmware.
14252 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014253int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014254 struct cfg80211_gtk_rekey_data *data)
14255{
14256 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14257 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14258 hdd_station_ctx_t *pHddStaCtx;
14259 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014260 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014261 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014262 eHalStatus status = eHAL_STATUS_FAILURE;
14263
14264 ENTER();
14265
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014266
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014267 if (NULL == pAdapter)
14268 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014269 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014270 "%s: HDD adapter is Null", __func__);
14271 return -ENODEV;
14272 }
14273
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014274 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14275 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
14276 pAdapter->sessionId, pAdapter->device_mode));
14277
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014278 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014279
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014280 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014281 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14283 "%s: HDD context is not valid", __func__);
14284 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014285 }
14286
14287 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14288 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14289 if (NULL == hHal)
14290 {
14291 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14292 "%s: HAL context is Null!!!", __func__);
14293 return -EAGAIN;
14294 }
14295
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014296 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
14297 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
14298 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
14299 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014300 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014301 {
14302 /* changing from big to little endian since driver
14303 * works on little endian format
14304 */
14305 tANI_U8 *p =
14306 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
14307 int i;
14308
14309 for (i = 0; i < 8; i++)
14310 {
14311 p[7-i] = data->replay_ctr[i];
14312 }
14313 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014314
14315 if (TRUE == pHddCtx->hdd_wlan_suspended)
14316 {
14317 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014318 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
14319 sizeof (tSirGtkOffloadParams));
14320 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014321 pAdapter->sessionId);
14322
14323 if (eHAL_STATUS_SUCCESS != status)
14324 {
14325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14326 "%s: sme_SetGTKOffload failed, returned %d",
14327 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053014328
14329 /* Need to clear any trace of key value in the memory.
14330 * Thus zero out the memory even though it is local
14331 * variable.
14332 */
14333 vos_mem_zero(&hddGtkOffloadReqParams,
14334 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014335 return status;
14336 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14338 "%s: sme_SetGTKOffload successfull", __func__);
14339 }
14340 else
14341 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14343 "%s: wlan not suspended GTKOffload request is stored",
14344 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014345 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014346
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053014347 /* Need to clear any trace of key value in the memory.
14348 * Thus zero out the memory even though it is local
14349 * variable.
14350 */
14351 vos_mem_zero(&hddGtkOffloadReqParams,
14352 sizeof(hddGtkOffloadReqParams));
14353
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014354 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014355}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014356
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014357int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
14358 struct cfg80211_gtk_rekey_data *data)
14359{
14360 int ret;
14361
14362 vos_ssr_protect(__func__);
14363 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
14364 vos_ssr_unprotect(__func__);
14365
14366 return ret;
14367}
14368#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014369/*
14370 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
14371 * This function is used to set access control policy
14372 */
14373static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
14374 struct net_device *dev, const struct cfg80211_acl_data *params)
14375{
14376 int i;
14377 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14378 hdd_hostapd_state_t *pHostapdState;
14379 tsap_Config_t *pConfig;
14380 v_CONTEXT_t pVosContext = NULL;
14381 hdd_context_t *pHddCtx;
14382 int status;
14383
14384 ENTER();
14385
14386 if (NULL == pAdapter)
14387 {
14388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14389 "%s: HDD adapter is Null", __func__);
14390 return -ENODEV;
14391 }
14392
14393 if (NULL == params)
14394 {
14395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14396 "%s: params is Null", __func__);
14397 return -EINVAL;
14398 }
14399
14400 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14401 status = wlan_hdd_validate_context(pHddCtx);
14402
14403 if (0 != status)
14404 {
14405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14406 "%s: HDD context is not valid", __func__);
14407 return status;
14408 }
14409
14410 pVosContext = pHddCtx->pvosContext;
14411 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
14412
14413 if (NULL == pHostapdState)
14414 {
14415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14416 "%s: pHostapdState is Null", __func__);
14417 return -EINVAL;
14418 }
14419
14420 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
14421 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
14422
14423 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
14424 {
14425 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
14426
14427 /* default value */
14428 pConfig->num_accept_mac = 0;
14429 pConfig->num_deny_mac = 0;
14430
14431 /**
14432 * access control policy
14433 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
14434 * listed in hostapd.deny file.
14435 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
14436 * listed in hostapd.accept file.
14437 */
14438 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
14439 {
14440 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
14441 }
14442 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
14443 {
14444 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
14445 }
14446 else
14447 {
14448 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14449 "%s:Acl Policy : %d is not supported",
14450 __func__, params->acl_policy);
14451 return -ENOTSUPP;
14452 }
14453
14454 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
14455 {
14456 pConfig->num_accept_mac = params->n_acl_entries;
14457 for (i = 0; i < params->n_acl_entries; i++)
14458 {
14459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14460 "** Add ACL MAC entry %i in WhiletList :"
14461 MAC_ADDRESS_STR, i,
14462 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14463
14464 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
14465 sizeof(qcmacaddr));
14466 }
14467 }
14468 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
14469 {
14470 pConfig->num_deny_mac = params->n_acl_entries;
14471 for (i = 0; i < params->n_acl_entries; i++)
14472 {
14473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14474 "** Add ACL MAC entry %i in BlackList :"
14475 MAC_ADDRESS_STR, i,
14476 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14477
14478 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
14479 sizeof(qcmacaddr));
14480 }
14481 }
14482
14483 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
14484 {
14485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14486 "%s: SAP Set Mac Acl fail", __func__);
14487 return -EINVAL;
14488 }
14489 }
14490 else
14491 {
14492 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014493 "%s: Invalid device_mode = %s (%d)",
14494 __func__, hdd_device_modetoString(pAdapter->device_mode),
14495 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014496 return -EINVAL;
14497 }
14498
14499 return 0;
14500}
14501
Leo Chang9056f462013-08-01 19:21:11 -070014502#ifdef WLAN_NL80211_TESTMODE
14503#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070014504void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070014505(
14506 void *pAdapter,
14507 void *indCont
14508)
14509{
Leo Changd9df8aa2013-09-26 13:32:26 -070014510 tSirLPHBInd *lphbInd;
14511 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053014512 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070014513
14514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014515 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070014516
c_hpothu73f35e62014-04-18 13:40:08 +053014517 if (pAdapter == NULL)
14518 {
14519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14520 "%s: pAdapter is NULL\n",__func__);
14521 return;
14522 }
14523
Leo Chang9056f462013-08-01 19:21:11 -070014524 if (NULL == indCont)
14525 {
14526 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014527 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070014528 return;
14529 }
14530
c_hpothu73f35e62014-04-18 13:40:08 +053014531 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070014532 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070014533 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053014534 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070014535 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070014536 GFP_ATOMIC);
14537 if (!skb)
14538 {
14539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14540 "LPHB timeout, NL buffer alloc fail");
14541 return;
14542 }
14543
Leo Changac3ba772013-10-07 09:47:04 -070014544 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070014545 {
14546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14547 "WLAN_HDD_TM_ATTR_CMD put fail");
14548 goto nla_put_failure;
14549 }
Leo Changac3ba772013-10-07 09:47:04 -070014550 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070014551 {
14552 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14553 "WLAN_HDD_TM_ATTR_TYPE put fail");
14554 goto nla_put_failure;
14555 }
Leo Changac3ba772013-10-07 09:47:04 -070014556 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070014557 sizeof(tSirLPHBInd), lphbInd))
14558 {
14559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14560 "WLAN_HDD_TM_ATTR_DATA put fail");
14561 goto nla_put_failure;
14562 }
Leo Chang9056f462013-08-01 19:21:11 -070014563 cfg80211_testmode_event(skb, GFP_ATOMIC);
14564 return;
14565
14566nla_put_failure:
14567 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14568 "NLA Put fail");
14569 kfree_skb(skb);
14570
14571 return;
14572}
14573#endif /* FEATURE_WLAN_LPHB */
14574
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014575static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070014576{
14577 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
14578 int err = 0;
14579#ifdef FEATURE_WLAN_LPHB
14580 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070014581 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -070014582#endif /* FEATURE_WLAN_LPHB */
14583
14584 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
14585 if (err)
14586 {
14587 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14588 "%s Testmode INV ATTR", __func__);
14589 return err;
14590 }
14591
14592 if (!tb[WLAN_HDD_TM_ATTR_CMD])
14593 {
14594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14595 "%s Testmode INV CMD", __func__);
14596 return -EINVAL;
14597 }
14598
14599 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
14600 {
14601#ifdef FEATURE_WLAN_LPHB
14602 /* Low Power Heartbeat configuration request */
14603 case WLAN_HDD_TM_CMD_WLAN_HB:
14604 {
14605 int buf_len;
14606 void *buf;
14607 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080014608 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070014609
14610 if (!tb[WLAN_HDD_TM_ATTR_DATA])
14611 {
14612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14613 "%s Testmode INV DATA", __func__);
14614 return -EINVAL;
14615 }
14616
14617 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
14618 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080014619
14620 hb_params_temp =(tSirLPHBReq *)buf;
14621 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
14622 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
14623 return -EINVAL;
14624
Leo Chang9056f462013-08-01 19:21:11 -070014625 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
14626 if (NULL == hb_params)
14627 {
14628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14629 "%s Request Buffer Alloc Fail", __func__);
14630 return -EINVAL;
14631 }
14632
14633 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070014634 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
14635 hb_params,
14636 wlan_hdd_cfg80211_lphb_ind_handler);
14637 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070014638 {
Leo Changd9df8aa2013-09-26 13:32:26 -070014639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14640 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070014641 vos_mem_free(hb_params);
14642 }
Leo Chang9056f462013-08-01 19:21:11 -070014643 return 0;
14644 }
14645#endif /* FEATURE_WLAN_LPHB */
14646 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014647 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14648 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070014649 return -EOPNOTSUPP;
14650 }
14651
14652 return err;
14653}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014654
14655static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
14656{
14657 int ret;
14658
14659 vos_ssr_protect(__func__);
14660 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
14661 vos_ssr_unprotect(__func__);
14662
14663 return ret;
14664}
Leo Chang9056f462013-08-01 19:21:11 -070014665#endif /* CONFIG_NL80211_TESTMODE */
14666
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014667static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014668 struct net_device *dev,
14669 int idx, struct survey_info *survey)
14670{
14671 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14672 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053014673 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014674 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053014675 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014676 v_S7_t snr,rssi;
14677 int status, i, j, filled = 0;
14678
14679 ENTER();
14680
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014681 if (NULL == pAdapter)
14682 {
14683 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14684 "%s: HDD adapter is Null", __func__);
14685 return -ENODEV;
14686 }
14687
14688 if (NULL == wiphy)
14689 {
14690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14691 "%s: wiphy is Null", __func__);
14692 return -ENODEV;
14693 }
14694
14695 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14696 status = wlan_hdd_validate_context(pHddCtx);
14697
14698 if (0 != status)
14699 {
14700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14701 "%s: HDD context is not valid", __func__);
14702 return status;
14703 }
14704
Mihir Sheted9072e02013-08-21 17:02:29 +053014705 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14706
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014707 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053014708 0 != pAdapter->survey_idx ||
14709 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014710 {
14711 /* The survey dump ops when implemented completely is expected to
14712 * return a survey of all channels and the ops is called by the
14713 * kernel with incremental values of the argument 'idx' till it
14714 * returns -ENONET. But we can only support the survey for the
14715 * operating channel for now. survey_idx is used to track
14716 * that the ops is called only once and then return -ENONET for
14717 * the next iteration
14718 */
14719 pAdapter->survey_idx = 0;
14720 return -ENONET;
14721 }
14722
14723 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14724
14725 wlan_hdd_get_snr(pAdapter, &snr);
14726 wlan_hdd_get_rssi(pAdapter, &rssi);
14727
14728 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
14729 hdd_wlan_get_freq(channel, &freq);
14730
14731
14732 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
14733 {
14734 if (NULL == wiphy->bands[i])
14735 {
14736 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
14737 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
14738 continue;
14739 }
14740
14741 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
14742 {
14743 struct ieee80211_supported_band *band = wiphy->bands[i];
14744
14745 if (band->channels[j].center_freq == (v_U16_t)freq)
14746 {
14747 survey->channel = &band->channels[j];
14748 /* The Rx BDs contain SNR values in dB for the received frames
14749 * while the supplicant expects noise. So we calculate and
14750 * return the value of noise (dBm)
14751 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
14752 */
14753 survey->noise = rssi - snr;
14754 survey->filled = SURVEY_INFO_NOISE_DBM;
14755 filled = 1;
14756 }
14757 }
14758 }
14759
14760 if (filled)
14761 pAdapter->survey_idx = 1;
14762 else
14763 {
14764 pAdapter->survey_idx = 0;
14765 return -ENONET;
14766 }
14767
14768 return 0;
14769}
14770
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014771static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
14772 struct net_device *dev,
14773 int idx, struct survey_info *survey)
14774{
14775 int ret;
14776
14777 vos_ssr_protect(__func__);
14778 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
14779 vos_ssr_unprotect(__func__);
14780
14781 return ret;
14782}
14783
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014784/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014785 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014786 * this is called when cfg80211 driver resume
14787 * driver updates latest sched_scan scan result(if any) to cfg80211 database
14788 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014789int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014790{
14791 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14792 hdd_adapter_t *pAdapter;
14793 hdd_adapter_list_node_t *pAdapterNode, *pNext;
14794 VOS_STATUS status = VOS_STATUS_SUCCESS;
14795
14796 ENTER();
14797
14798 if ( NULL == pHddCtx )
14799 {
14800 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14801 "%s: HddCtx validation failed", __func__);
14802 return 0;
14803 }
14804
14805 if (pHddCtx->isLogpInProgress)
14806 {
14807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14808 "%s: LOGP in Progress. Ignore!!!", __func__);
14809 return 0;
14810 }
14811
Mihir Shete18156292014-03-11 15:38:30 +053014812 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014813 {
14814 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14815 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14816 return 0;
14817 }
14818
14819 spin_lock(&pHddCtx->schedScan_lock);
14820 pHddCtx->isWiphySuspended = FALSE;
14821 if (TRUE != pHddCtx->isSchedScanUpdatePending)
14822 {
14823 spin_unlock(&pHddCtx->schedScan_lock);
14824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14825 "%s: Return resume is not due to PNO indication", __func__);
14826 return 0;
14827 }
14828 // Reset flag to avoid updatating cfg80211 data old results again
14829 pHddCtx->isSchedScanUpdatePending = FALSE;
14830 spin_unlock(&pHddCtx->schedScan_lock);
14831
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014832
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014833 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14834
14835 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14836 {
14837 pAdapter = pAdapterNode->pAdapter;
14838 if ( (NULL != pAdapter) &&
14839 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
14840 {
14841 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014842 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14844 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014845 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014846 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014847 {
14848 /* Acquire wakelock to handle the case where APP's tries to
14849 * suspend immediately after updating the scan results. Whis
14850 * results in app's is in suspended state and not able to
14851 * process the connect request to AP
14852 */
14853 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014854 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014855 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014856
14857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14858 "%s : cfg80211 scan result database updated", __func__);
14859
14860 return 0;
14861
14862 }
14863 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14864 pAdapterNode = pNext;
14865 }
14866
14867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14868 "%s: Failed to find Adapter", __func__);
14869 return 0;
14870}
14871
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014872int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
14873{
14874 int ret;
14875
14876 vos_ssr_protect(__func__);
14877 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
14878 vos_ssr_unprotect(__func__);
14879
14880 return ret;
14881}
14882
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014883/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014884 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014885 * this is called when cfg80211 driver suspends
14886 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014887int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014888 struct cfg80211_wowlan *wow)
14889{
14890 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14891
14892 ENTER();
14893 if (NULL == pHddCtx)
14894 {
14895 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14896 "%s: HddCtx validation failed", __func__);
14897 return 0;
14898 }
14899
14900 pHddCtx->isWiphySuspended = TRUE;
14901
14902 EXIT();
14903
14904 return 0;
14905}
14906
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014907int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
14908 struct cfg80211_wowlan *wow)
14909{
14910 int ret;
14911
14912 vos_ssr_protect(__func__);
14913 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
14914 vos_ssr_unprotect(__func__);
14915
14916 return ret;
14917}
Jeff Johnson295189b2012-06-20 16:38:30 -070014918/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014919static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070014920{
14921 .add_virtual_intf = wlan_hdd_add_virtual_intf,
14922 .del_virtual_intf = wlan_hdd_del_virtual_intf,
14923 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
14924 .change_station = wlan_hdd_change_station,
14925#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
14926 .add_beacon = wlan_hdd_cfg80211_add_beacon,
14927 .del_beacon = wlan_hdd_cfg80211_del_beacon,
14928 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014929#else
14930 .start_ap = wlan_hdd_cfg80211_start_ap,
14931 .change_beacon = wlan_hdd_cfg80211_change_beacon,
14932 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070014933#endif
14934 .change_bss = wlan_hdd_cfg80211_change_bss,
14935 .add_key = wlan_hdd_cfg80211_add_key,
14936 .get_key = wlan_hdd_cfg80211_get_key,
14937 .del_key = wlan_hdd_cfg80211_del_key,
14938 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014939#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070014940 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014941#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014942 .scan = wlan_hdd_cfg80211_scan,
14943 .connect = wlan_hdd_cfg80211_connect,
14944 .disconnect = wlan_hdd_cfg80211_disconnect,
14945 .join_ibss = wlan_hdd_cfg80211_join_ibss,
14946 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
14947 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
14948 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
14949 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070014950 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
14951 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053014952 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070014953#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14954 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
14955 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
14956 .set_txq_params = wlan_hdd_set_txq_params,
14957#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014958 .get_station = wlan_hdd_cfg80211_get_station,
14959 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
14960 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014961 .add_station = wlan_hdd_cfg80211_add_station,
14962#ifdef FEATURE_WLAN_LFR
14963 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
14964 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
14965 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
14966#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014967#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
14968 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
14969#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014970#ifdef FEATURE_WLAN_TDLS
14971 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
14972 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
14973#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014974#ifdef WLAN_FEATURE_GTK_OFFLOAD
14975 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
14976#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014977#ifdef FEATURE_WLAN_SCAN_PNO
14978 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
14979 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
14980#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014981 .resume = wlan_hdd_cfg80211_resume_wlan,
14982 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014983 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070014984#ifdef WLAN_NL80211_TESTMODE
14985 .testmode_cmd = wlan_hdd_cfg80211_testmode,
14986#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014987 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070014988};
14989