blob: f6f5a19de6f75cff9e722e63006a0d78882bcd63 [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 {
4972 // Enable Social channels for P2P
4973 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
4974 NV_CHANNEL_ENABLE == channelEnabledState)
4975 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4976 else
4977 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4978 continue;
4979 }
4980 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
4981 {
4982 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4983 continue;
4984 }
4985
4986 if (NV_CHANNEL_DISABLE == channelEnabledState ||
4987 NV_CHANNEL_INVALID == channelEnabledState)
4988 {
4989 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4990 }
4991 else if (NV_CHANNEL_DFS == channelEnabledState)
4992 {
4993 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4994 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
4995 }
4996 else
4997 {
4998 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4999 |IEEE80211_CHAN_RADAR);
5000 }
5001 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005002 }
5003 return 0;
5004}
5005/*
5006 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305007 * This function is called by hdd_wlan_startup()
5008 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005009 * This function is used to initialize and register wiphy structure.
5010 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305011int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005012 struct wiphy *wiphy,
5013 hdd_config_t *pCfg
5014 )
5015{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305016 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305017 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5018
Jeff Johnsone7245742012-09-05 17:12:55 -07005019 ENTER();
5020
Jeff Johnson295189b2012-06-20 16:38:30 -07005021 /* Now bind the underlying wlan device with wiphy */
5022 set_wiphy_dev(wiphy, dev);
5023
5024 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005025
Kiet Lam6c583332013-10-14 05:37:09 +05305026#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005027 /* the flag for the other case would be initialzed in
5028 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005029 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305030#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005031
Amar Singhalfddc28c2013-09-05 13:03:40 -07005032 /* This will disable updating of NL channels from passive to
5033 * active if a beacon is received on passive channel. */
5034 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07005035
Amar Singhalfddc28c2013-09-05 13:03:40 -07005036
Amar Singhala49cbc52013-10-08 18:37:44 -07005037
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005038#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005039 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5040 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5041 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005042 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05305043 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005044#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005045
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005046#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005047 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005048#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005049 || pCfg->isFastRoamIniFeatureEnabled
5050#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005051#ifdef FEATURE_WLAN_ESE
5052 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005053#endif
5054 )
5055 {
5056 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5057 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005058#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005059#ifdef FEATURE_WLAN_TDLS
5060 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5061 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5062#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305063#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305064 if (pCfg->configPNOScanSupport)
5065 {
5066 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5067 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5068 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5069 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5070 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305071#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005072
Amar Singhalfddc28c2013-09-05 13:03:40 -07005073#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005074 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5075 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005076 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005077 driver need to determine what to do with both
5078 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005079
5080 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005081#else
5082 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005083#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005084
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305085 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5086
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05305087 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005088
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305089 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5090
Jeff Johnson295189b2012-06-20 16:38:30 -07005091 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305092 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07005093 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07005094 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5095 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005096 | BIT(NL80211_IFTYPE_AP);
5097
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305098 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005099 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305100#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5101 if( pCfg->enableMCC )
5102 {
5103 /* Currently, supports up to two channels */
5104 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005105
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305106 if( !pCfg->allowMCCGODiffBI )
5107 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005108
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305109 }
5110 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5111 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005112#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305113 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005114
Jeff Johnson295189b2012-06-20 16:38:30 -07005115 /* Before registering we need to update the ht capabilitied based
5116 * on ini values*/
5117 if( !pCfg->ShortGI20MhzEnable )
5118 {
5119 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5120 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5121 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5122 }
5123
5124 if( !pCfg->ShortGI40MhzEnable )
5125 {
5126 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5127 }
5128
5129 if( !pCfg->nChannelBondingMode5GHz )
5130 {
5131 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5132 }
5133
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305134 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305135 if (true == hdd_is_5g_supported(pHddCtx))
5136 {
5137 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5138 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305139
5140 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5141 {
5142
5143 if (NULL == wiphy->bands[i])
5144 {
5145 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5146 __func__, i);
5147 continue;
5148 }
5149
5150 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5151 {
5152 struct ieee80211_supported_band *band = wiphy->bands[i];
5153
5154 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5155 {
5156 // Enable social channels for P2P
5157 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5158 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5159 else
5160 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5161 continue;
5162 }
5163 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5164 {
5165 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5166 continue;
5167 }
5168 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005169 }
5170 /*Initialise the supported cipher suite details*/
5171 wiphy->cipher_suites = hdd_cipher_suites;
5172 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5173
5174 /*signal strength in mBm (100*dBm) */
5175 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5176
5177#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305178 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005179#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005180
Sunil Duttc69bccb2014-05-26 21:30:20 +05305181 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
5182 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005183 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
5184 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
5185
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305186 EXIT();
5187 return 0;
5188}
5189
5190/* In this function we are registering wiphy. */
5191int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
5192{
5193 ENTER();
5194 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005195 if (0 > wiphy_register(wiphy))
5196 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305197 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07005198 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
5199 return -EIO;
5200 }
5201
5202 EXIT();
5203 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305204}
Jeff Johnson295189b2012-06-20 16:38:30 -07005205
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305206/* In this function we are updating channel list when,
5207 regulatory domain is FCC and country code is US.
5208 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
5209 As per FCC smart phone is not a indoor device.
5210 GO should not opeate on indoor channels */
5211void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
5212{
5213 int j;
5214 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5215 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
5216 //Default counrtycode from NV at the time of wiphy initialization.
5217 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
5218 &defaultCountryCode[0]))
5219 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005220 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305221 }
5222 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
5223 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305224 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
5225 {
5226 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
5227 return;
5228 }
5229 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
5230 {
5231 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
5232 // Mark UNII -1 band channel as passive
5233 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
5234 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
5235 }
5236 }
5237}
5238
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305239/* This function registers for all frame which supplicant is interested in */
5240void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005241{
Jeff Johnson295189b2012-06-20 16:38:30 -07005242 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5243 /* Register for all P2P action, public action etc frames */
5244 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5245
Jeff Johnsone7245742012-09-05 17:12:55 -07005246 ENTER();
5247
Jeff Johnson295189b2012-06-20 16:38:30 -07005248 /* Right now we are registering these frame when driver is getting
5249 initialized. Once we will move to 2.6.37 kernel, in which we have
5250 frame register ops, we will move this code as a part of that */
5251 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305252 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07005253 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5254
5255 /* GAS Initial Response */
5256 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5257 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305258
Jeff Johnson295189b2012-06-20 16:38:30 -07005259 /* GAS Comeback Request */
5260 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5261 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5262
5263 /* GAS Comeback Response */
5264 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5265 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5266
5267 /* P2P Public Action */
5268 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305269 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005270 P2P_PUBLIC_ACTION_FRAME_SIZE );
5271
5272 /* P2P Action */
5273 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5274 (v_U8_t*)P2P_ACTION_FRAME,
5275 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07005276
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05305277 /* WNM BSS Transition Request frame */
5278 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5279 (v_U8_t*)WNM_BSS_ACTION_FRAME,
5280 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005281
5282 /* WNM-Notification */
5283 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5284 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5285 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005286}
5287
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305288void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005289{
Jeff Johnson295189b2012-06-20 16:38:30 -07005290 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5291 /* Register for all P2P action, public action etc frames */
5292 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5293
Jeff Johnsone7245742012-09-05 17:12:55 -07005294 ENTER();
5295
Jeff Johnson295189b2012-06-20 16:38:30 -07005296 /* Right now we are registering these frame when driver is getting
5297 initialized. Once we will move to 2.6.37 kernel, in which we have
5298 frame register ops, we will move this code as a part of that */
5299 /* GAS Initial Request */
5300
5301 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5302 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5303
5304 /* GAS Initial Response */
5305 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5306 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305307
Jeff Johnson295189b2012-06-20 16:38:30 -07005308 /* GAS Comeback Request */
5309 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5310 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5311
5312 /* GAS Comeback Response */
5313 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5314 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5315
5316 /* P2P Public Action */
5317 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305318 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005319 P2P_PUBLIC_ACTION_FRAME_SIZE );
5320
5321 /* P2P Action */
5322 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5323 (v_U8_t*)P2P_ACTION_FRAME,
5324 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005325 /* WNM-Notification */
5326 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5327 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5328 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005329}
5330
5331#ifdef FEATURE_WLAN_WAPI
5332void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
5333 const u8 *mac_addr, u8 *key , int key_Len)
5334{
5335 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5336 tCsrRoamSetKey setKey;
5337 v_BOOL_t isConnected = TRUE;
5338 int status = 0;
5339 v_U32_t roamId= 0xFF;
5340 tANI_U8 *pKeyPtr = NULL;
5341 int n = 0;
5342
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305343 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
5344 __func__, hdd_device_modetoString(pAdapter->device_mode),
5345 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005346
Gopichand Nakkalae7480202013-02-11 15:24:22 +05305347 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005348 setKey.keyId = key_index; // Store Key ID
5349 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
5350 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
5351 setKey.paeRole = 0 ; // the PAE role
5352 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
5353 {
5354 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
5355 }
5356 else
5357 {
5358 isConnected = hdd_connIsConnected(pHddStaCtx);
5359 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
5360 }
5361 setKey.keyLength = key_Len;
5362 pKeyPtr = setKey.Key;
5363 memcpy( pKeyPtr, key, key_Len);
5364
Arif Hussain6d2a3322013-11-17 19:50:10 -08005365 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005366 __func__, key_Len);
5367 for (n = 0 ; n < key_Len; n++)
5368 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
5369 __func__,n,setKey.Key[n]);
5370
5371 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
5372 if ( isConnected )
5373 {
5374 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
5375 pAdapter->sessionId, &setKey, &roamId );
5376 }
5377 if ( status != 0 )
5378 {
5379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5380 "[%4d] sme_RoamSetKey returned ERROR status= %d",
5381 __LINE__, status );
5382 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
5383 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05305384 /* Need to clear any trace of key value in the memory.
5385 * Thus zero out the memory even though it is local
5386 * variable.
5387 */
5388 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005389}
5390#endif /* FEATURE_WLAN_WAPI*/
5391
5392#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305393int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005394 beacon_data_t **ppBeacon,
5395 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005396#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305397int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005398 beacon_data_t **ppBeacon,
5399 struct cfg80211_beacon_data *params,
5400 int dtim_period)
5401#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305402{
Jeff Johnson295189b2012-06-20 16:38:30 -07005403 int size;
5404 beacon_data_t *beacon = NULL;
5405 beacon_data_t *old = NULL;
5406 int head_len,tail_len;
5407
Jeff Johnsone7245742012-09-05 17:12:55 -07005408 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005409 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305410 {
5411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5412 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005413 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305414 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005415
5416 old = pAdapter->sessionCtx.ap.beacon;
5417
5418 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305419 {
5420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5421 FL("session(%d) old and new heads points to NULL"),
5422 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005423 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305424 }
5425
5426 if (params->tail && !params->tail_len)
5427 {
5428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5429 FL("tail_len is zero but tail is not NULL"));
5430 return -EINVAL;
5431 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005432
Jeff Johnson295189b2012-06-20 16:38:30 -07005433#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
5434 /* Kernel 3.0 is not updating dtim_period for set beacon */
5435 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305436 {
5437 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5438 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005439 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305440 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005441#endif
5442
5443 if(params->head)
5444 head_len = params->head_len;
5445 else
5446 head_len = old->head_len;
5447
5448 if(params->tail || !old)
5449 tail_len = params->tail_len;
5450 else
5451 tail_len = old->tail_len;
5452
5453 size = sizeof(beacon_data_t) + head_len + tail_len;
5454
5455 beacon = kzalloc(size, GFP_KERNEL);
5456
5457 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305458 {
5459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5460 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005461 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305462 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005463
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005464#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005465 if(params->dtim_period || !old )
5466 beacon->dtim_period = params->dtim_period;
5467 else
5468 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005469#else
5470 if(dtim_period || !old )
5471 beacon->dtim_period = dtim_period;
5472 else
5473 beacon->dtim_period = old->dtim_period;
5474#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305475
Jeff Johnson295189b2012-06-20 16:38:30 -07005476 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
5477 beacon->tail = beacon->head + head_len;
5478 beacon->head_len = head_len;
5479 beacon->tail_len = tail_len;
5480
5481 if(params->head) {
5482 memcpy (beacon->head,params->head,beacon->head_len);
5483 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305484 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07005485 if(old)
5486 memcpy (beacon->head,old->head,beacon->head_len);
5487 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305488
Jeff Johnson295189b2012-06-20 16:38:30 -07005489 if(params->tail) {
5490 memcpy (beacon->tail,params->tail,beacon->tail_len);
5491 }
5492 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305493 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07005494 memcpy (beacon->tail,old->tail,beacon->tail_len);
5495 }
5496
5497 *ppBeacon = beacon;
5498
5499 kfree(old);
5500
5501 return 0;
5502
5503}
Jeff Johnson295189b2012-06-20 16:38:30 -07005504
5505v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
5506{
5507 int left = length;
5508 v_U8_t *ptr = pIes;
5509 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305510
Jeff Johnson295189b2012-06-20 16:38:30 -07005511 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305512 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005513 elem_id = ptr[0];
5514 elem_len = ptr[1];
5515 left -= 2;
5516 if(elem_len > left)
5517 {
5518 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005519 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005520 eid,elem_len,left);
5521 return NULL;
5522 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305523 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005524 {
5525 return ptr;
5526 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305527
Jeff Johnson295189b2012-06-20 16:38:30 -07005528 left -= elem_len;
5529 ptr += (elem_len + 2);
5530 }
5531 return NULL;
5532}
5533
Jeff Johnson295189b2012-06-20 16:38:30 -07005534/* Check if rate is 11g rate or not */
5535static int wlan_hdd_rate_is_11g(u8 rate)
5536{
Sanjay Devnani28322e22013-06-21 16:13:40 -07005537 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005538 u8 i;
5539 for (i = 0; i < 8; i++)
5540 {
5541 if(rate == gRateArray[i])
5542 return TRUE;
5543 }
5544 return FALSE;
5545}
5546
5547/* Check for 11g rate and set proper 11g only mode */
5548static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
5549 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
5550{
5551 u8 i, num_rates = pIe[0];
5552
5553 pIe += 1;
5554 for ( i = 0; i < num_rates; i++)
5555 {
5556 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
5557 {
5558 /* If rate set have 11g rate than change the mode to 11G */
5559 *pSapHw_mode = eSAP_DOT11_MODE_11g;
5560 if (pIe[i] & BASIC_RATE_MASK)
5561 {
5562 /* If we have 11g rate as basic rate, it means mode
5563 is 11g only mode.
5564 */
5565 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
5566 *pCheckRatesfor11g = FALSE;
5567 }
5568 }
5569 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
5570 {
5571 *require_ht = TRUE;
5572 }
5573 }
5574 return;
5575}
5576
5577static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
5578{
5579 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5580 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5581 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5582 u8 checkRatesfor11g = TRUE;
5583 u8 require_ht = FALSE;
5584 u8 *pIe=NULL;
5585
5586 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
5587
5588 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
5589 pBeacon->head_len, WLAN_EID_SUPP_RATES);
5590 if (pIe != NULL)
5591 {
5592 pIe += 1;
5593 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5594 &pConfig->SapHw_mode);
5595 }
5596
5597 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5598 WLAN_EID_EXT_SUPP_RATES);
5599 if (pIe != NULL)
5600 {
5601
5602 pIe += 1;
5603 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5604 &pConfig->SapHw_mode);
5605 }
5606
5607 if( pConfig->channel > 14 )
5608 {
5609 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
5610 }
5611
5612 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5613 WLAN_EID_HT_CAPABILITY);
5614
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305615 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005616 {
5617 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
5618 if(require_ht)
5619 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
5620 }
5621}
5622
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305623static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
5624 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
5625{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005626 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305627 v_U8_t *pIe = NULL;
5628 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5629
5630 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
5631 pBeacon->tail, pBeacon->tail_len);
5632
5633 if (pIe)
5634 {
5635 ielen = pIe[1] + 2;
5636 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5637 {
5638 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
5639 }
5640 else
5641 {
5642 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
5643 return -EINVAL;
5644 }
5645 *total_ielen += ielen;
5646 }
5647 return 0;
5648}
5649
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005650static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
5651 v_U8_t *genie, v_U8_t *total_ielen)
5652{
5653 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5654 int left = pBeacon->tail_len;
5655 v_U8_t *ptr = pBeacon->tail;
5656 v_U8_t elem_id, elem_len;
5657 v_U16_t ielen = 0;
5658
5659 if ( NULL == ptr || 0 == left )
5660 return;
5661
5662 while (left >= 2)
5663 {
5664 elem_id = ptr[0];
5665 elem_len = ptr[1];
5666 left -= 2;
5667 if (elem_len > left)
5668 {
5669 hddLog( VOS_TRACE_LEVEL_ERROR,
5670 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
5671 elem_id, elem_len, left);
5672 return;
5673 }
5674 if (IE_EID_VENDOR == elem_id)
5675 {
5676 /* skipping the VSIE's which we don't want to include or
5677 * it will be included by existing code
5678 */
5679 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
5680#ifdef WLAN_FEATURE_WFD
5681 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
5682#endif
5683 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5684 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5685 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
5686 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5687 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
5688 {
5689 ielen = ptr[1] + 2;
5690 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5691 {
5692 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
5693 *total_ielen += ielen;
5694 }
5695 else
5696 {
5697 hddLog( VOS_TRACE_LEVEL_ERROR,
5698 "IE Length is too big "
5699 "IEs eid=%d elem_len=%d total_ie_lent=%d",
5700 elem_id, elem_len, *total_ielen);
5701 }
5702 }
5703 }
5704
5705 left -= elem_len;
5706 ptr += (elem_len + 2);
5707 }
5708 return;
5709}
5710
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005711#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005712static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5713 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005714#else
5715static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5716 struct cfg80211_beacon_data *params)
5717#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005718{
5719 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305720 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005721 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07005722 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005723
5724 genie = vos_mem_malloc(MAX_GENIE_LEN);
5725
5726 if(genie == NULL) {
5727
5728 return -ENOMEM;
5729 }
5730
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305731 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5732 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005733 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305734 hddLog(LOGE,
5735 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305736 ret = -EINVAL;
5737 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005738 }
5739
5740#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305741 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5742 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
5743 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305744 hddLog(LOGE,
5745 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305746 ret = -EINVAL;
5747 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005748 }
5749#endif
5750
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305751 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5752 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005753 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305754 hddLog(LOGE,
5755 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305756 ret = -EINVAL;
5757 goto done;
5758 }
5759
5760 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
5761 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005762 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07005763 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005764
5765 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5766 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
5767 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
5768 {
5769 hddLog(LOGE,
5770 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005771 ret = -EINVAL;
5772 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005773 }
5774
5775 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5776 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5777 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5778 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5779 ==eHAL_STATUS_FAILURE)
5780 {
5781 hddLog(LOGE,
5782 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005783 ret = -EINVAL;
5784 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005785 }
5786
5787 // Added for ProResp IE
5788 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
5789 {
5790 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
5791 u8 probe_rsp_ie_len[3] = {0};
5792 u8 counter = 0;
5793 /* Check Probe Resp Length if it is greater then 255 then Store
5794 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
5795 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
5796 Store More then 255 bytes into One Variable.
5797 */
5798 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
5799 {
5800 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
5801 {
5802 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
5803 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
5804 }
5805 else
5806 {
5807 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
5808 rem_probe_resp_ie_len = 0;
5809 }
5810 }
5811
5812 rem_probe_resp_ie_len = 0;
5813
5814 if (probe_rsp_ie_len[0] > 0)
5815 {
5816 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5817 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
5818 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5819 probe_rsp_ie_len[0], NULL,
5820 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5821 {
5822 hddLog(LOGE,
5823 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005824 ret = -EINVAL;
5825 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005826 }
5827 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
5828 }
5829
5830 if (probe_rsp_ie_len[1] > 0)
5831 {
5832 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5833 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
5834 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5835 probe_rsp_ie_len[1], NULL,
5836 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5837 {
5838 hddLog(LOGE,
5839 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005840 ret = -EINVAL;
5841 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005842 }
5843 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
5844 }
5845
5846 if (probe_rsp_ie_len[2] > 0)
5847 {
5848 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5849 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
5850 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5851 probe_rsp_ie_len[2], NULL,
5852 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5853 {
5854 hddLog(LOGE,
5855 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005856 ret = -EINVAL;
5857 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005858 }
5859 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
5860 }
5861
5862 if (probe_rsp_ie_len[1] == 0 )
5863 {
5864 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5865 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
5866 eANI_BOOLEAN_FALSE) )
5867 {
5868 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005869 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005870 }
5871 }
5872
5873 if (probe_rsp_ie_len[2] == 0 )
5874 {
5875 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5876 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
5877 eANI_BOOLEAN_FALSE) )
5878 {
5879 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005880 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005881 }
5882 }
5883
5884 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5885 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5886 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5887 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5888 == eHAL_STATUS_FAILURE)
5889 {
5890 hddLog(LOGE,
5891 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005892 ret = -EINVAL;
5893 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005894 }
5895 }
5896 else
5897 {
5898 // Reset WNI_CFG_PROBE_RSP Flags
5899 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
5900
5901 hddLog(VOS_TRACE_LEVEL_INFO,
5902 "%s: No Probe Response IE received in set beacon",
5903 __func__);
5904 }
5905
5906 // Added for AssocResp IE
5907 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
5908 {
5909 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5910 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
5911 params->assocresp_ies_len, NULL,
5912 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5913 {
5914 hddLog(LOGE,
5915 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005916 ret = -EINVAL;
5917 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005918 }
5919
5920 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5921 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
5922 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5923 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5924 == eHAL_STATUS_FAILURE)
5925 {
5926 hddLog(LOGE,
5927 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005928 ret = -EINVAL;
5929 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005930 }
5931 }
5932 else
5933 {
5934 hddLog(VOS_TRACE_LEVEL_INFO,
5935 "%s: No Assoc Response IE received in set beacon",
5936 __func__);
5937
5938 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5939 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5940 eANI_BOOLEAN_FALSE) )
5941 {
5942 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005943 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005944 }
5945 }
5946
Jeff Johnsone7245742012-09-05 17:12:55 -07005947done:
Jeff Johnson295189b2012-06-20 16:38:30 -07005948 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305949 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005950}
Jeff Johnson295189b2012-06-20 16:38:30 -07005951
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305952/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005953 * FUNCTION: wlan_hdd_validate_operation_channel
5954 * called by wlan_hdd_cfg80211_start_bss() and
5955 * wlan_hdd_cfg80211_set_channel()
5956 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305957 * channel list.
5958 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005959VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005960{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305961
Jeff Johnson295189b2012-06-20 16:38:30 -07005962 v_U32_t num_ch = 0;
5963 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5964 u32 indx = 0;
5965 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305966 v_U8_t fValidChannel = FALSE, count = 0;
5967 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305968
Jeff Johnson295189b2012-06-20 16:38:30 -07005969 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5970
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305971 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005972 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305973 /* Validate the channel */
5974 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005975 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305976 if ( channel == rfChannels[count].channelNum )
5977 {
5978 fValidChannel = TRUE;
5979 break;
5980 }
5981 }
5982 if (fValidChannel != TRUE)
5983 {
5984 hddLog(VOS_TRACE_LEVEL_ERROR,
5985 "%s: Invalid Channel [%d]", __func__, channel);
5986 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005987 }
5988 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305989 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005990 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305991 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5992 valid_ch, &num_ch))
5993 {
5994 hddLog(VOS_TRACE_LEVEL_ERROR,
5995 "%s: failed to get valid channel list", __func__);
5996 return VOS_STATUS_E_FAILURE;
5997 }
5998 for (indx = 0; indx < num_ch; indx++)
5999 {
6000 if (channel == valid_ch[indx])
6001 {
6002 break;
6003 }
6004 }
6005
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306006 if (indx >= num_ch)
6007 {
6008 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6009 {
6010 eCsrBand band;
6011 unsigned int freq;
6012
6013 sme_GetFreqBand(hHal, &band);
6014
6015 if (eCSR_BAND_5G == band)
6016 {
6017#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6018 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6019 {
6020 freq = ieee80211_channel_to_frequency(channel,
6021 IEEE80211_BAND_2GHZ);
6022 }
6023 else
6024 {
6025 freq = ieee80211_channel_to_frequency(channel,
6026 IEEE80211_BAND_5GHZ);
6027 }
6028#else
6029 freq = ieee80211_channel_to_frequency(channel);
6030#endif
6031 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6032 return VOS_STATUS_SUCCESS;
6033 }
6034 }
6035
6036 hddLog(VOS_TRACE_LEVEL_ERROR,
6037 "%s: Invalid Channel [%d]", __func__, channel);
6038 return VOS_STATUS_E_FAILURE;
6039 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006040 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306041
Jeff Johnson295189b2012-06-20 16:38:30 -07006042 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306043
Jeff Johnson295189b2012-06-20 16:38:30 -07006044}
6045
Viral Modi3a32cc52013-02-08 11:14:52 -08006046/**
6047 * FUNCTION: wlan_hdd_cfg80211_set_channel
6048 * This function is used to set the channel number
6049 */
6050static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
6051 struct ieee80211_channel *chan,
6052 enum nl80211_channel_type channel_type
6053 )
6054{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306055 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006056 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006057 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006058 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306059 hdd_context_t *pHddCtx;
6060 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006061
6062 ENTER();
6063
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306064
Viral Modi3a32cc52013-02-08 11:14:52 -08006065 if( NULL == dev )
6066 {
6067 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006068 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006069 return -ENODEV;
6070 }
6071 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306072
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306073 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6074 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6075 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006076 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306077 "%s: device_mode = %s (%d) freq = %d", __func__,
6078 hdd_device_modetoString(pAdapter->device_mode),
6079 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306080
6081 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6082 status = wlan_hdd_validate_context(pHddCtx);
6083
6084 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006085 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6087 "%s: HDD context is not valid", __func__);
6088 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006089 }
6090
6091 /*
6092 * Do freq to chan conversion
6093 * TODO: for 11a
6094 */
6095
6096 channel = ieee80211_frequency_to_channel(freq);
6097
6098 /* Check freq range */
6099 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6100 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6101 {
6102 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006103 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006104 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6105 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6106 return -EINVAL;
6107 }
6108
6109 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6110
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306111 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6112 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006113 {
6114 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6115 {
6116 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006117 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006118 return -EINVAL;
6119 }
6120 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6121 "%s: set channel to [%d] for device mode =%d",
6122 __func__, channel,pAdapter->device_mode);
6123 }
6124 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006125 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006126 )
6127 {
6128 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6129 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6130 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6131
6132 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6133 {
6134 /* Link is up then return cant set channel*/
6135 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006136 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006137 return -EINVAL;
6138 }
6139
6140 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6141 pHddStaCtx->conn_info.operationChannel = channel;
6142 pRoamProfile->ChannelInfo.ChannelList =
6143 &pHddStaCtx->conn_info.operationChannel;
6144 }
6145 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006146 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006147 )
6148 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306149 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6150 {
6151 if(VOS_STATUS_SUCCESS !=
6152 wlan_hdd_validate_operation_channel(pAdapter,channel))
6153 {
6154 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006155 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306156 return -EINVAL;
6157 }
6158 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6159 }
6160 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006161 {
6162 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6163
6164 /* If auto channel selection is configured as enable/ 1 then ignore
6165 channel set by supplicant
6166 */
6167 if ( cfg_param->apAutoChannelSelection )
6168 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306169 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6170 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006171 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306172 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6173 __func__, hdd_device_modetoString(pAdapter->device_mode),
6174 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006175 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306176 else
6177 {
6178 if(VOS_STATUS_SUCCESS !=
6179 wlan_hdd_validate_operation_channel(pAdapter,channel))
6180 {
6181 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006182 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306183 return -EINVAL;
6184 }
6185 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6186 }
Viral Modi3a32cc52013-02-08 11:14:52 -08006187 }
6188 }
6189 else
6190 {
6191 hddLog(VOS_TRACE_LEVEL_FATAL,
6192 "%s: Invalid device mode failed to set valid channel", __func__);
6193 return -EINVAL;
6194 }
6195 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306196 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006197}
6198
Jeff Johnson295189b2012-06-20 16:38:30 -07006199#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6200static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6201 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006202#else
6203static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6204 struct cfg80211_beacon_data *params,
6205 const u8 *ssid, size_t ssid_len,
6206 enum nl80211_hidden_ssid hidden_ssid)
6207#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006208{
6209 tsap_Config_t *pConfig;
6210 beacon_data_t *pBeacon = NULL;
6211 struct ieee80211_mgmt *pMgmt_frame;
6212 v_U8_t *pIe=NULL;
6213 v_U16_t capab_info;
6214 eCsrAuthType RSNAuthType;
6215 eCsrEncryptionType RSNEncryptType;
6216 eCsrEncryptionType mcRSNEncryptType;
6217 int status = VOS_STATUS_SUCCESS;
6218 tpWLAN_SAPEventCB pSapEventCallback;
6219 hdd_hostapd_state_t *pHostapdState;
6220 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
6221 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306222 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006223 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306224 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07006225 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08006226 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05306227 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07006228 v_BOOL_t MFPCapable = VOS_FALSE;
6229 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306230 eHddDot11Mode sapDot11Mode =
6231 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07006232
6233 ENTER();
6234
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306235 iniConfig = pHddCtx->cfg_ini;
6236
Jeff Johnson295189b2012-06-20 16:38:30 -07006237 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
6238
6239 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6240
6241 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6242
6243 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6244
6245 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
6246
6247 //channel is already set in the set_channel Call back
6248 //pConfig->channel = pCommitConfig->channel;
6249
6250 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306251 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07006252 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
6253
6254 pConfig->dtim_period = pBeacon->dtim_period;
6255
Arif Hussain6d2a3322013-11-17 19:50:10 -08006256 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07006257 pConfig->dtim_period);
6258
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08006259 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07006260 {
6261 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006262 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05306263 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
6264 {
6265 tANI_BOOLEAN restartNeeded;
6266 pConfig->ieee80211d = 1;
6267 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
6268 sme_setRegInfo(hHal, pConfig->countryCode);
6269 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
6270 }
6271 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006272 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07006273 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07006274 pConfig->ieee80211d = 1;
6275 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
6276 sme_setRegInfo(hHal, pConfig->countryCode);
6277 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07006278 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006279 else
6280 {
6281 pConfig->ieee80211d = 0;
6282 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306283 /*
6284 * If auto channel is configured i.e. channel is 0,
6285 * so skip channel validation.
6286 */
6287 if( AUTO_CHANNEL_SELECT != pConfig->channel )
6288 {
6289 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
6290 {
6291 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006292 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306293 return -EINVAL;
6294 }
6295 }
6296 else
6297 {
6298 if(1 != pHddCtx->is_dynamic_channel_range_set)
6299 {
6300 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
6301 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
6302 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
6303 }
6304 pHddCtx->is_dynamic_channel_range_set = 0;
6305 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006306 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006307 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006308 {
6309 pConfig->ieee80211d = 0;
6310 }
6311 pConfig->authType = eSAP_AUTO_SWITCH;
6312
6313 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306314
6315 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07006316 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
6317
6318 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
6319
6320 /*Set wps station to configured*/
6321 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
6322
6323 if(pIe)
6324 {
6325 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
6326 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006327 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07006328 return -EINVAL;
6329 }
6330 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
6331 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006332 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07006333 /* Check 15 bit of WPS IE as it contain information for wps state
6334 * WPS state
6335 */
6336 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
6337 {
6338 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
6339 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
6340 {
6341 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
6342 }
6343 }
6344 }
6345 else
6346 {
6347 pConfig->wps_state = SAP_WPS_DISABLED;
6348 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306349 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07006350
c_hpothufe599e92014-06-16 11:38:55 +05306351 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6352 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6353 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
6354 eCSR_ENCRYPT_TYPE_NONE;
6355
Jeff Johnson295189b2012-06-20 16:38:30 -07006356 pConfig->RSNWPAReqIELength = 0;
6357 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306358 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006359 WLAN_EID_RSN);
6360 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306361 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006362 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6363 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6364 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306365 /* The actual processing may eventually be more extensive than
6366 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07006367 * by the app.
6368 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306369 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006370 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6371 &RSNEncryptType,
6372 &mcRSNEncryptType,
6373 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006374 &MFPCapable,
6375 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006376 pConfig->pRSNWPAReqIE[1]+2,
6377 pConfig->pRSNWPAReqIE );
6378
6379 if( VOS_STATUS_SUCCESS == status )
6380 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306381 /* Now copy over all the security attributes you have
6382 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006383 * */
6384 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6385 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6386 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6387 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306388 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006389 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006390 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6391 }
6392 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306393
Jeff Johnson295189b2012-06-20 16:38:30 -07006394 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6395 pBeacon->tail, pBeacon->tail_len);
6396
6397 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
6398 {
6399 if (pConfig->pRSNWPAReqIE)
6400 {
6401 /*Mixed mode WPA/WPA2*/
6402 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
6403 pConfig->RSNWPAReqIELength += pIe[1] + 2;
6404 }
6405 else
6406 {
6407 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6408 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6409 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306410 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006411 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6412 &RSNEncryptType,
6413 &mcRSNEncryptType,
6414 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006415 &MFPCapable,
6416 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006417 pConfig->pRSNWPAReqIE[1]+2,
6418 pConfig->pRSNWPAReqIE );
6419
6420 if( VOS_STATUS_SUCCESS == status )
6421 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306422 /* Now copy over all the security attributes you have
6423 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006424 * */
6425 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6426 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6427 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6428 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306429 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006430 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006431 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6432 }
6433 }
6434 }
6435
Jeff Johnson4416a782013-03-25 14:17:50 -07006436 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
6437 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
6438 return -EINVAL;
6439 }
6440
Jeff Johnson295189b2012-06-20 16:38:30 -07006441 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
6442
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006443#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006444 if (params->ssid != NULL)
6445 {
6446 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
6447 pConfig->SSIDinfo.ssid.length = params->ssid_len;
6448 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6449 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6450 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006451#else
6452 if (ssid != NULL)
6453 {
6454 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
6455 pConfig->SSIDinfo.ssid.length = ssid_len;
6456 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6457 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6458 }
6459#endif
6460
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306461 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07006462 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306463
Jeff Johnson295189b2012-06-20 16:38:30 -07006464 /* default value */
6465 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
6466 pConfig->num_accept_mac = 0;
6467 pConfig->num_deny_mac = 0;
6468
6469 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6470 pBeacon->tail, pBeacon->tail_len);
6471
6472 /* pIe for black list is following form:
6473 type : 1 byte
6474 length : 1 byte
6475 OUI : 4 bytes
6476 acl type : 1 byte
6477 no of mac addr in black list: 1 byte
6478 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306479 */
6480 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006481 {
6482 pConfig->SapMacaddr_acl = pIe[6];
6483 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006484 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006485 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306486 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
6487 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006488 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6489 for (i = 0; i < pConfig->num_deny_mac; i++)
6490 {
6491 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6492 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306493 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006494 }
6495 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6496 pBeacon->tail, pBeacon->tail_len);
6497
6498 /* pIe for white list is following form:
6499 type : 1 byte
6500 length : 1 byte
6501 OUI : 4 bytes
6502 acl type : 1 byte
6503 no of mac addr in white list: 1 byte
6504 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306505 */
6506 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006507 {
6508 pConfig->SapMacaddr_acl = pIe[6];
6509 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006510 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006511 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306512 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
6513 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006514 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6515 for (i = 0; i < pConfig->num_accept_mac; i++)
6516 {
6517 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6518 acl_entry++;
6519 }
6520 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306521
Jeff Johnson295189b2012-06-20 16:38:30 -07006522 wlan_hdd_set_sapHwmode(pHostapdAdapter);
6523
Jeff Johnsone7245742012-09-05 17:12:55 -07006524#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006525 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05306526 * This is valid only if mode is set to 11n in hostapd, either AUTO or
6527 * 11ac in .ini and 11ac is supported by both host and firmware.
6528 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
6529 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006530 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
6531 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306532 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
6533 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
6534 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
6535 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
6536 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07006537 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306538 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07006539 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306540 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006541
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306542 /* If ACS disable and selected channel <= 14
6543 * OR
6544 * ACS enabled and ACS operating band is choosen as 2.4
6545 * AND
6546 * VHT in 2.4G Disabled
6547 * THEN
6548 * Fallback to 11N mode
6549 */
6550 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
6551 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05306552 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306553 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006554 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306555 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
6556 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006557 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
6558 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006559 }
6560#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306561
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07006562 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
6563 {
6564 sme_SelectCBMode(hHal,
6565 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
6566 pConfig->channel);
6567 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006568 // ht_capab is not what the name conveys,this is used for protection bitmap
6569 pConfig->ht_capab =
6570 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
6571
6572 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
6573 {
6574 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
6575 return -EINVAL;
6576 }
6577
6578 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306579 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07006580 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
6581 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306582 pConfig->obssProtEnabled =
6583 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07006584
Chet Lanctot8cecea22014-02-11 19:09:36 -08006585#ifdef WLAN_FEATURE_11W
6586 pConfig->mfpCapable = MFPCapable;
6587 pConfig->mfpRequired = MFPRequired;
6588 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
6589 pConfig->mfpCapable, pConfig->mfpRequired);
6590#endif
6591
Arif Hussain6d2a3322013-11-17 19:50:10 -08006592 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07006593 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006594 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
6595 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
6596 (int)pConfig->channel);
6597 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
6598 pConfig->SapHw_mode, pConfig->privacy,
6599 pConfig->authType);
6600 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
6601 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
6602 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
6603 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07006604
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306605 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006606 {
6607 //Bss already started. just return.
6608 //TODO Probably it should update some beacon params.
6609 hddLog( LOGE, "Bss Already started...Ignore the request");
6610 EXIT();
6611 return 0;
6612 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306613
Agarwal Ashish51325b52014-06-16 16:50:49 +05306614 if (vos_max_concurrent_connections_reached()) {
6615 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6616 return -EINVAL;
6617 }
6618
Jeff Johnson295189b2012-06-20 16:38:30 -07006619 pConfig->persona = pHostapdAdapter->device_mode;
6620
Peng Xu2446a892014-09-05 17:21:18 +05306621 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
6622 if ( NULL != psmeConfig)
6623 {
6624 sme_GetConfigParam(hHal, psmeConfig);
6625 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
6626 vos_mem_free(psmeConfig);
6627 }
Peng Xuafc34e32014-09-25 13:23:55 +05306628 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05306629
Jeff Johnson295189b2012-06-20 16:38:30 -07006630 pSapEventCallback = hdd_hostapd_SAPEventCB;
6631 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
6632 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
6633 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006634 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006635 return -EINVAL;
6636 }
6637
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306638 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07006639 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
6640
6641 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306642
Jeff Johnson295189b2012-06-20 16:38:30 -07006643 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306644 {
6645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006646 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07006647 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07006648 VOS_ASSERT(0);
6649 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306650
Jeff Johnson295189b2012-06-20 16:38:30 -07006651 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05306652 /* Initialize WMM configuation */
6653 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306654 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006655
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006656#ifdef WLAN_FEATURE_P2P_DEBUG
6657 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
6658 {
6659 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
6660 {
6661 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6662 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006663 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006664 }
6665 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
6666 {
6667 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6668 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006669 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006670 }
6671 }
6672#endif
6673
Jeff Johnson295189b2012-06-20 16:38:30 -07006674 pHostapdState->bCommit = TRUE;
6675 EXIT();
6676
6677 return 0;
6678}
6679
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006680#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306681static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
6682 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006683 struct beacon_parameters *params)
6684{
6685 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306686 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306687 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006688
6689 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306690
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306691 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6692 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
6693 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306694 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
6695 hdd_device_modetoString(pAdapter->device_mode),
6696 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006697
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306698 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6699 status = wlan_hdd_validate_context(pHddCtx);
6700
6701 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006702 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6704 "%s: HDD context is not valid", __func__);
6705 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006706 }
6707
Agarwal Ashish51325b52014-06-16 16:50:49 +05306708 if (vos_max_concurrent_connections_reached()) {
6709 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6710 return -EINVAL;
6711 }
6712
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306713 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006714 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006715 )
6716 {
6717 beacon_data_t *old,*new;
6718
6719 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306720
Jeff Johnson295189b2012-06-20 16:38:30 -07006721 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306722 {
6723 hddLog(VOS_TRACE_LEVEL_WARN,
6724 FL("already beacon info added to session(%d)"),
6725 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006726 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306727 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006728
6729 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6730
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306731 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07006732 {
6733 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006734 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006735 return -EINVAL;
6736 }
6737
6738 pAdapter->sessionCtx.ap.beacon = new;
6739
6740 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6741 }
6742
6743 EXIT();
6744 return status;
6745}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306746
6747static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006748 struct net_device *dev,
6749 struct beacon_parameters *params)
6750{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306751 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306752 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6753 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306754 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006755
6756 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306757 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6758 TRACE_CODE_HDD_CFG80211_SET_BEACON,
6759 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
6760 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6761 __func__, hdd_device_modetoString(pAdapter->device_mode),
6762 pAdapter->device_mode);
6763
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306764 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6765 status = wlan_hdd_validate_context(pHddCtx);
6766
6767 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006768 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6770 "%s: HDD context is not valid", __func__);
6771 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006772 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306773
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306774 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006775 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306776 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006777 {
6778 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306779
Jeff Johnson295189b2012-06-20 16:38:30 -07006780 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306781
Jeff Johnson295189b2012-06-20 16:38:30 -07006782 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306783 {
6784 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6785 FL("session(%d) old and new heads points to NULL"),
6786 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006787 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306788 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006789
6790 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6791
6792 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306793 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006794 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006795 return -EINVAL;
6796 }
6797
6798 pAdapter->sessionCtx.ap.beacon = new;
6799
6800 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6801 }
6802
6803 EXIT();
6804 return status;
6805}
6806
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006807#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6808
6809#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006810static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
6811 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006812#else
6813static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
6814 struct net_device *dev)
6815#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006816{
6817 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07006818 hdd_context_t *pHddCtx = NULL;
6819 hdd_scaninfo_t *pScanInfo = NULL;
6820 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306821 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306822 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006823
6824 ENTER();
6825
6826 if (NULL == pAdapter)
6827 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306828 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006829 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006830 return -ENODEV;
6831 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006832
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306833 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6834 TRACE_CODE_HDD_CFG80211_STOP_AP,
6835 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306836 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6837 status = wlan_hdd_validate_context(pHddCtx);
6838
6839 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006840 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6842 "%s: HDD context is not valid", __func__);
6843 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07006844 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006845
6846 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
6847 if (NULL == staAdapter)
6848 {
6849 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
6850 if (NULL == staAdapter)
6851 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07006852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6853 "%s: HDD adapter context for STA/P2P-CLI is Null",
6854 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006855 }
6856 }
6857
6858 pScanInfo = &pHddCtx->scan_info;
6859
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306860 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6861 __func__, hdd_device_modetoString(pAdapter->device_mode),
6862 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006863
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306864 ret = wlan_hdd_scan_abort(pAdapter);
6865
Girish Gowli4bf7a632014-06-12 13:42:11 +05306866 if (ret < 0)
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 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306870
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306871 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07006872 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306873 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6874 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08006875
Jeff Johnsone7245742012-09-05 17:12:55 -07006876 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306877 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07006878 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306879 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07006880 }
6881
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05306882 /* Delete all associated STAs before stopping AP/P2P GO */
6883 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05306884 hdd_hostapd_stop(dev);
6885
Jeff Johnson295189b2012-06-20 16:38:30 -07006886 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006887 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006888 )
6889 {
6890 beacon_data_t *old;
6891
6892 old = pAdapter->sessionCtx.ap.beacon;
6893
6894 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306895 {
6896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6897 FL("session(%d) beacon data points to NULL"),
6898 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006899 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306900 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006901
Jeff Johnson295189b2012-06-20 16:38:30 -07006902 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006903
6904 mutex_lock(&pHddCtx->sap_lock);
6905 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6906 {
Jeff Johnson4416a782013-03-25 14:17:50 -07006907 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006908 {
6909 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6910
6911 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6912
6913 if (!VOS_IS_STATUS_SUCCESS(status))
6914 {
6915 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006916 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006917 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306918 }
6919 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006920 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306921 /* BSS stopped, clear the active sessions for this device mode */
6922 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006923 }
6924 mutex_unlock(&pHddCtx->sap_lock);
6925
6926 if(status != VOS_STATUS_SUCCESS)
6927 {
6928 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006929 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006930 return -EINVAL;
6931 }
6932
Jeff Johnson4416a782013-03-25 14:17:50 -07006933 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006934 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
6935 ==eHAL_STATUS_FAILURE)
6936 {
6937 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006938 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006939 }
6940
Jeff Johnson4416a782013-03-25 14:17:50 -07006941 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006942 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6943 eANI_BOOLEAN_FALSE) )
6944 {
6945 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006946 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006947 }
6948
6949 // Reset WNI_CFG_PROBE_RSP Flags
6950 wlan_hdd_reset_prob_rspies(pAdapter);
6951
6952 pAdapter->sessionCtx.ap.beacon = NULL;
6953 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006954#ifdef WLAN_FEATURE_P2P_DEBUG
6955 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
6956 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
6957 {
6958 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
6959 "GO got removed");
6960 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
6961 }
6962#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006963 }
6964 EXIT();
6965 return status;
6966}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006967
6968#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6969
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306970static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
6971 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006972 struct cfg80211_ap_settings *params)
6973{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306974 hdd_adapter_t *pAdapter;
6975 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306976 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006977
6978 ENTER();
6979
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306980 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006981 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306982 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306983 "%s: Device is Null", __func__);
6984 return -ENODEV;
6985 }
6986
6987 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6988 if (NULL == pAdapter)
6989 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306990 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306991 "%s: HDD adapter is Null", __func__);
6992 return -ENODEV;
6993 }
6994
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306995 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6996 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
6997 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306998 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6999 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307001 "%s: HDD adapter magic is invalid", __func__);
7002 return -ENODEV;
7003 }
7004
7005 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307006 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307007
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307008 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307009 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307010 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7011 "%s: HDD context is not valid", __func__);
7012 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307013 }
7014
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307015 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7016 __func__, hdd_device_modetoString(pAdapter->device_mode),
7017 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307018
7019 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007020 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007021 )
7022 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307023 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007024
7025 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307026
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007027 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307028 {
7029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7030 FL("already beacon info added to session(%d)"),
7031 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007032 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307033 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007034
7035 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
7036
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307037 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007038 {
7039 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307040 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007041 return -EINVAL;
7042 }
7043 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007044#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007045 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7046#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7047 params->channel, params->channel_type);
7048#else
7049 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7050#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007051#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007052 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
7053 params->ssid_len, params->hidden_ssid);
7054 }
7055
7056 EXIT();
7057 return status;
7058}
7059
7060
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307061static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007062 struct net_device *dev,
7063 struct cfg80211_beacon_data *params)
7064{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307065 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307066 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307067 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007068
7069 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307070
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307071 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7072 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7073 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007074 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007075 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307076
7077 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7078 status = wlan_hdd_validate_context(pHddCtx);
7079
7080 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007081 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7083 "%s: HDD context is not valid", __func__);
7084 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007085 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007086
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307087 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007088 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307089 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007090 {
7091 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307092
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007093 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307094
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007095 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307096 {
7097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7098 FL("session(%d) beacon data points to NULL"),
7099 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007100 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307101 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007102
7103 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
7104
7105 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307106 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007107 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007108 return -EINVAL;
7109 }
7110
7111 pAdapter->sessionCtx.ap.beacon = new;
7112
7113 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
7114 }
7115
7116 EXIT();
7117 return status;
7118}
7119
7120#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7121
Jeff Johnson295189b2012-06-20 16:38:30 -07007122
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307123static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007124 struct net_device *dev,
7125 struct bss_parameters *params)
7126{
7127 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7128
7129 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307130
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307131 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7132 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
7133 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307134 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7135 __func__, hdd_device_modetoString(pAdapter->device_mode),
7136 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007137
7138 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007139 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307140 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007141 {
7142 /* ap_isolate == -1 means that in change bss, upper layer doesn't
7143 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307144 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07007145 {
7146 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307147 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007148 }
7149
7150 EXIT();
7151 return 0;
7152}
7153
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307154static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
7155 struct net_device *dev,
7156 struct bss_parameters *params)
7157{
7158 int ret;
7159
7160 vos_ssr_protect(__func__);
7161 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
7162 vos_ssr_unprotect(__func__);
7163
7164 return ret;
7165}
Kiet Lam10841362013-11-01 11:36:50 +05307166/* FUNCTION: wlan_hdd_change_country_code_cd
7167* to wait for contry code completion
7168*/
7169void* wlan_hdd_change_country_code_cb(void *pAdapter)
7170{
7171 hdd_adapter_t *call_back_pAdapter = pAdapter;
7172 complete(&call_back_pAdapter->change_country_code);
7173 return NULL;
7174}
7175
Jeff Johnson295189b2012-06-20 16:38:30 -07007176/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307177 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07007178 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
7179 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307180int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007181 struct net_device *ndev,
7182 enum nl80211_iftype type,
7183 u32 *flags,
7184 struct vif_params *params
7185 )
7186{
7187 struct wireless_dev *wdev;
7188 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007189 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07007190 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007191 tCsrRoamProfile *pRoamProfile = NULL;
7192 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307193 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007194 eMib_dot11DesiredBssType connectedBssType;
7195 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307196 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007197
7198 ENTER();
7199
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307200 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007201 {
7202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7203 "%s: Adapter context is null", __func__);
7204 return VOS_STATUS_E_FAILURE;
7205 }
7206
7207 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7208 if (!pHddCtx)
7209 {
7210 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7211 "%s: HDD context is null", __func__);
7212 return VOS_STATUS_E_FAILURE;
7213 }
7214
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307215 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7216 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
7217 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307218 status = wlan_hdd_validate_context(pHddCtx);
7219
7220 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007221 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307222 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7223 "%s: HDD context is not valid", __func__);
7224 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007225 }
7226
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307227 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7228 __func__, hdd_device_modetoString(pAdapter->device_mode),
7229 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007230
Agarwal Ashish51325b52014-06-16 16:50:49 +05307231 if (vos_max_concurrent_connections_reached()) {
7232 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7233 return -EINVAL;
7234 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307235 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007236 wdev = ndev->ieee80211_ptr;
7237
7238#ifdef WLAN_BTAMP_FEATURE
7239 if((NL80211_IFTYPE_P2P_CLIENT == type)||
7240 (NL80211_IFTYPE_ADHOC == type)||
7241 (NL80211_IFTYPE_AP == type)||
7242 (NL80211_IFTYPE_P2P_GO == type))
7243 {
7244 pHddCtx->isAmpAllowed = VOS_FALSE;
7245 // stop AMP traffic
7246 status = WLANBAP_StopAmp();
7247 if(VOS_STATUS_SUCCESS != status )
7248 {
7249 pHddCtx->isAmpAllowed = VOS_TRUE;
7250 hddLog(VOS_TRACE_LEVEL_FATAL,
7251 "%s: Failed to stop AMP", __func__);
7252 return -EINVAL;
7253 }
7254 }
7255#endif //WLAN_BTAMP_FEATURE
7256 /* Reset the current device mode bit mask*/
7257 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7258
7259 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007260 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07007261 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07007262 )
7263 {
7264 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007265 if (!pWextState)
7266 {
7267 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7268 "%s: pWextState is null", __func__);
7269 return VOS_STATUS_E_FAILURE;
7270 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007271 pRoamProfile = &pWextState->roamProfile;
7272 LastBSSType = pRoamProfile->BSSType;
7273
7274 switch (type)
7275 {
7276 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007277 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007278 hddLog(VOS_TRACE_LEVEL_INFO,
7279 "%s: setting interface Type to INFRASTRUCTURE", __func__);
7280 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07007281#ifdef WLAN_FEATURE_11AC
7282 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
7283 {
7284 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
7285 }
7286#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307287 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07007288 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007289 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007290 //Check for sub-string p2p to confirm its a p2p interface
7291 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307292 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007293 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7294 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7295 }
7296 else
7297 {
7298 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007299 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007300 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05307301#ifdef FEATURE_WLAN_TDLS
7302 /* The open adapter for the p2p shall skip initializations in
7303 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
7304 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
7305 * tdls_init when the change_iface sets the device mode to
7306 * WLAN_HDD_P2P_CLIENT.
7307 */
7308
7309 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
7310 {
Agarwal Ashish4b87f922014-06-18 03:03:21 +05307311 if (0 != wlan_hdd_sta_tdls_init (pAdapter))
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05307312 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307313 hddLog(VOS_TRACE_LEVEL_ERROR,
7314 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05307315 return -EINVAL;
7316 }
7317 }
7318#endif
7319
Jeff Johnson295189b2012-06-20 16:38:30 -07007320 break;
7321 case NL80211_IFTYPE_ADHOC:
7322 hddLog(VOS_TRACE_LEVEL_INFO,
7323 "%s: setting interface Type to ADHOC", __func__);
7324 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
7325 pRoamProfile->phyMode =
7326 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07007327 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007328 wdev->iftype = type;
7329 break;
7330
7331 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007332 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007333 {
7334 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7335 "%s: setting interface Type to %s", __func__,
7336 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
7337
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007338 //Cancel any remain on channel for GO mode
7339 if (NL80211_IFTYPE_P2P_GO == type)
7340 {
7341 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
7342 }
Mohit Khanna0f232092012-09-11 14:46:08 -07007343 if (NL80211_IFTYPE_AP == type)
7344 {
7345 /* As Loading WLAN Driver one interface being created for p2p device
7346 * address. This will take one HW STA and the max number of clients
7347 * that can connect to softAP will be reduced by one. so while changing
7348 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
7349 * interface as it is not required in SoftAP mode.
7350 */
7351
7352 // Get P2P Adapter
7353 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
7354
7355 if (pP2pAdapter)
7356 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307357 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07007358 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
7359 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
7360 }
7361 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05307362 //Disable IMPS & BMPS for SAP/GO
7363 if(VOS_STATUS_E_FAILURE ==
7364 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
7365 {
7366 //Fail to Exit BMPS
7367 VOS_ASSERT(0);
7368 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05307369
7370 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
7371
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307372#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07007373
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307374 /* A Mutex Lock is introduced while changing the mode to
7375 * protect the concurrent access for the Adapters by TDLS
7376 * module.
7377 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307378 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307379#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007380 //De-init the adapter.
Jeff Johnson295189b2012-06-20 16:38:30 -07007381 hdd_deinit_adapter( pHddCtx, pAdapter );
7382 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07007383 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7384 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307385#ifdef FEATURE_WLAN_TDLS
7386 mutex_unlock(&pHddCtx->tdls_lock);
7387#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007388 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
7389 (pConfig->apRandomBssidEnabled))
7390 {
7391 /* To meet Android requirements create a randomized
7392 MAC address of the form 02:1A:11:Fx:xx:xx */
7393 get_random_bytes(&ndev->dev_addr[3], 3);
7394 ndev->dev_addr[0] = 0x02;
7395 ndev->dev_addr[1] = 0x1A;
7396 ndev->dev_addr[2] = 0x11;
7397 ndev->dev_addr[3] |= 0xF0;
7398 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
7399 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08007400 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
7401 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007402 }
7403
Jeff Johnson295189b2012-06-20 16:38:30 -07007404 hdd_set_ap_ops( pAdapter->dev );
7405
Kiet Lam10841362013-11-01 11:36:50 +05307406 /* This is for only SAP mode where users can
7407 * control country through ini.
7408 * P2P GO follows station country code
7409 * acquired during the STA scanning. */
7410 if((NL80211_IFTYPE_AP == type) &&
7411 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
7412 {
7413 int status = 0;
7414 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
7415 "%s: setting country code from INI ", __func__);
7416 init_completion(&pAdapter->change_country_code);
7417 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
7418 (void *)(tSmeChangeCountryCallback)
7419 wlan_hdd_change_country_code_cb,
7420 pConfig->apCntryCode, pAdapter,
7421 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05307422 eSIR_FALSE,
7423 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05307424 if (eHAL_STATUS_SUCCESS == status)
7425 {
7426 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307427 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05307428 &pAdapter->change_country_code,
7429 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307430 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05307431 {
7432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307433 FL("SME Timed out while setting country code %ld"),
7434 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08007435
7436 if (pHddCtx->isLogpInProgress)
7437 {
7438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7439 "%s: LOGP in Progress. Ignore!!!", __func__);
7440 return -EAGAIN;
7441 }
Kiet Lam10841362013-11-01 11:36:50 +05307442 }
7443 }
7444 else
7445 {
7446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007447 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05307448 return -EINVAL;
7449 }
7450 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007451 status = hdd_init_ap_mode(pAdapter);
7452 if(status != VOS_STATUS_SUCCESS)
7453 {
7454 hddLog(VOS_TRACE_LEVEL_FATAL,
7455 "%s: Error initializing the ap mode", __func__);
7456 return -EINVAL;
7457 }
7458 hdd_set_conparam(1);
7459
Jeff Johnson295189b2012-06-20 16:38:30 -07007460 /*interface type changed update in wiphy structure*/
7461 if(wdev)
7462 {
7463 wdev->iftype = type;
7464 pHddCtx->change_iface = type;
7465 }
7466 else
7467 {
7468 hddLog(VOS_TRACE_LEVEL_ERROR,
7469 "%s: ERROR !!!! Wireless dev is NULL", __func__);
7470 return -EINVAL;
7471 }
7472 goto done;
7473 }
7474
7475 default:
7476 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7477 __func__);
7478 return -EOPNOTSUPP;
7479 }
7480 }
7481 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007482 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007483 )
7484 {
7485 switch(type)
7486 {
7487 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007488 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007489 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05307490
7491 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307492#ifdef FEATURE_WLAN_TDLS
7493
7494 /* A Mutex Lock is introduced while changing the mode to
7495 * protect the concurrent access for the Adapters by TDLS
7496 * module.
7497 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307498 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307499#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07007500 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007501 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007502 //Check for sub-string p2p to confirm its a p2p interface
7503 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007504 {
7505 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7506 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7507 }
7508 else
7509 {
7510 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007511 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007512 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007513 hdd_set_conparam(0);
7514 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007515 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
7516 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307517#ifdef FEATURE_WLAN_TDLS
7518 mutex_unlock(&pHddCtx->tdls_lock);
7519#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05307520 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007521 if( VOS_STATUS_SUCCESS != status )
7522 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07007523 /* In case of JB, for P2P-GO, only change interface will be called,
7524 * This is the right place to enable back bmps_imps()
7525 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307526 if (pHddCtx->hdd_wlan_suspended)
7527 {
7528 hdd_set_pwrparams(pHddCtx);
7529 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007530 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007531 goto done;
7532 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007533 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007534 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007535 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7536 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007537 goto done;
7538 default:
7539 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7540 __func__);
7541 return -EOPNOTSUPP;
7542
7543 }
7544
7545 }
7546 else
7547 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307548 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
7549 __func__, hdd_device_modetoString(pAdapter->device_mode),
7550 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007551 return -EOPNOTSUPP;
7552 }
7553
7554
7555 if(pRoamProfile)
7556 {
7557 if ( LastBSSType != pRoamProfile->BSSType )
7558 {
7559 /*interface type changed update in wiphy structure*/
7560 wdev->iftype = type;
7561
7562 /*the BSS mode changed, We need to issue disconnect
7563 if connected or in IBSS disconnect state*/
7564 if ( hdd_connGetConnectedBssType(
7565 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
7566 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
7567 {
7568 /*need to issue a disconnect to CSR.*/
7569 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7570 if( eHAL_STATUS_SUCCESS ==
7571 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
7572 pAdapter->sessionId,
7573 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
7574 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307575 ret = wait_for_completion_interruptible_timeout(
7576 &pAdapter->disconnect_comp_var,
7577 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7578 if (ret <= 0)
7579 {
7580 hddLog(VOS_TRACE_LEVEL_ERROR,
7581 FL("wait on disconnect_comp_var failed %ld"), ret);
7582 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007583 }
7584 }
7585 }
7586 }
7587
7588done:
7589 /*set bitmask based on updated value*/
7590 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07007591
7592 /* Only STA mode support TM now
7593 * all other mode, TM feature should be disabled */
7594 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
7595 (~VOS_STA & pHddCtx->concurrency_mode) )
7596 {
7597 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
7598 }
7599
Jeff Johnson295189b2012-06-20 16:38:30 -07007600#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307601 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05307602 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07007603 {
7604 //we are ok to do AMP
7605 pHddCtx->isAmpAllowed = VOS_TRUE;
7606 }
7607#endif //WLAN_BTAMP_FEATURE
7608 EXIT();
7609 return 0;
7610}
7611
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307612/*
7613 * FUNCTION: wlan_hdd_cfg80211_change_iface
7614 * wrapper function to protect the actual implementation from SSR.
7615 */
7616int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
7617 struct net_device *ndev,
7618 enum nl80211_iftype type,
7619 u32 *flags,
7620 struct vif_params *params
7621 )
7622{
7623 int ret;
7624
7625 vos_ssr_protect(__func__);
7626 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
7627 vos_ssr_unprotect(__func__);
7628
7629 return ret;
7630}
7631
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007632#ifdef FEATURE_WLAN_TDLS
7633static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
7634 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
7635{
7636 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7637 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7638 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007639 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307640 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307641 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007642
7643 ENTER();
7644
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307645 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007646 {
7647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7648 "Invalid arguments");
7649 return -EINVAL;
7650 }
Hoonki Lee27511902013-03-14 18:19:06 -07007651
7652 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
7653 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
7654 {
7655 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7656 "%s: TDLS mode is disabled OR not enabled in FW."
7657 MAC_ADDRESS_STR " Request declined.",
7658 __func__, MAC_ADDR_ARRAY(mac));
7659 return -ENOTSUPP;
7660 }
7661
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007662 if (pHddCtx->isLogpInProgress)
7663 {
7664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7665 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05307666 wlan_hdd_tdls_set_link_status(pAdapter,
7667 mac,
7668 eTDLS_LINK_IDLE,
7669 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007670 return -EBUSY;
7671 }
7672
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05307673 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007674
7675 if ( NULL == pTdlsPeer ) {
7676 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7677 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
7678 __func__, MAC_ADDR_ARRAY(mac), update);
7679 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007680 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007681
7682 /* in add station, we accept existing valid staId if there is */
7683 if ((0 == update) &&
7684 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
7685 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007686 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007687 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007688 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007689 " link_status %d. staId %d. add station ignored.",
7690 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
7691 return 0;
7692 }
7693 /* in change station, we accept only when staId is valid */
7694 if ((1 == update) &&
7695 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
7696 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
7697 {
7698 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7699 "%s: " MAC_ADDRESS_STR
7700 " link status %d. staId %d. change station %s.",
7701 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
7702 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
7703 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007704 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007705
7706 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307707 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007708 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007709 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7710 "%s: " MAC_ADDRESS_STR
7711 " TDLS setup is ongoing. Request declined.",
7712 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07007713 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007714 }
7715
7716 /* first to check if we reached to maximum supported TDLS peer.
7717 TODO: for now, return -EPERM looks working fine,
7718 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307719 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
7720 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007721 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007722 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7723 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307724 " TDLS Max peer already connected. Request declined."
7725 " Num of peers (%d), Max allowed (%d).",
7726 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
7727 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007728 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007729 }
7730 else
7731 {
7732 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307733 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007734 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007735 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007736 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7737 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
7738 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007739 return -EPERM;
7740 }
7741 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007742 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05307743 wlan_hdd_tdls_set_link_status(pAdapter,
7744 mac,
7745 eTDLS_LINK_CONNECTING,
7746 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007747
Jeff Johnsond75fe012013-04-06 10:53:06 -07007748 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307749 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007750 {
7751 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7752 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007753 if(StaParams->htcap_present)
7754 {
7755 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7756 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
7757 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7758 "ht_capa->extended_capabilities: %0x",
7759 StaParams->HTCap.extendedHtCapInfo);
7760 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007761 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7762 "params->capability: %0x",StaParams->capability);
7763 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007764 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007765 if(StaParams->vhtcap_present)
7766 {
7767 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7768 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
7769 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
7770 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
7771 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007772 {
7773 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007774 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007775 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
7776 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7777 "[%d]: %x ", i, StaParams->supported_rates[i]);
7778 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07007779 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307780 else if ((1 == update) && (NULL == StaParams))
7781 {
7782 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7783 "%s : update is true, but staParams is NULL. Error!", __func__);
7784 return -EPERM;
7785 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007786
7787 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
7788
7789 if (!update)
7790 {
7791 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7792 pAdapter->sessionId, mac);
7793 }
7794 else
7795 {
7796 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7797 pAdapter->sessionId, mac, StaParams);
7798 }
7799
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307800 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007801 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
7802
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307803 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007804 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007805 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307806 "%s: timeout waiting for tdls add station indication %ld",
7807 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007808 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007809 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307810
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007811 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
7812 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007814 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007815 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007816 }
7817
7818 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007819
7820error:
Atul Mittal115287b2014-07-08 13:26:33 +05307821 wlan_hdd_tdls_set_link_status(pAdapter,
7822 mac,
7823 eTDLS_LINK_IDLE,
7824 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007825 return -EPERM;
7826
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007827}
7828#endif
7829
Jeff Johnson295189b2012-06-20 16:38:30 -07007830static int wlan_hdd_change_station(struct wiphy *wiphy,
7831 struct net_device *dev,
7832 u8 *mac,
7833 struct station_parameters *params)
7834{
7835 VOS_STATUS status = VOS_STATUS_SUCCESS;
7836 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05307837 hdd_context_t *pHddCtx;
7838 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007839 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007840#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007841 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007842 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307843 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007844#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007845 ENTER();
7846
Gopichand Nakkala29149562013-05-10 21:43:41 +05307847 if ((NULL == pAdapter))
7848 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05307850 "invalid adapter ");
7851 return -EINVAL;
7852 }
7853
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307854 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7855 TRACE_CODE_HDD_CHANGE_STATION,
7856 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05307857 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7858 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7859
7860 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
7861 {
7862 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7863 "invalid HDD state or HDD station context");
7864 return -EINVAL;
7865 }
7866
7867 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007868 {
7869 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7870 "%s:LOGP in Progress. Ignore!!!", __func__);
7871 return -EAGAIN;
7872 }
7873
Jeff Johnson295189b2012-06-20 16:38:30 -07007874 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
7875
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007876 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
7877 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07007878 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007879 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07007880 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307881 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07007882 WLANTL_STA_AUTHENTICATED);
7883
Gopichand Nakkala29149562013-05-10 21:43:41 +05307884 if (status != VOS_STATUS_SUCCESS)
7885 {
7886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7887 "%s: Not able to change TL state to AUTHENTICATED", __func__);
7888 return -EINVAL;
7889 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007890 }
7891 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07007892 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
7893 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05307894#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007895 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
7896 StaParams.capability = params->capability;
7897 StaParams.uapsd_queues = params->uapsd_queues;
7898 StaParams.max_sp = params->max_sp;
7899
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307900 /* Convert (first channel , number of channels) tuple to
7901 * the total list of channels. This goes with the assumption
7902 * that if the first channel is < 14, then the next channels
7903 * are an incremental of 1 else an incremental of 4 till the number
7904 * of channels.
7905 */
7906 if (0 != params->supported_channels_len) {
7907 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
7908 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
7909 {
7910 int wifi_chan_index;
7911 StaParams.supported_channels[j] = params->supported_channels[i];
7912 wifi_chan_index =
7913 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
7914 no_of_channels = params->supported_channels[i+1];
7915 for(k=1; k <= no_of_channels; k++)
7916 {
7917 StaParams.supported_channels[j+1] =
7918 StaParams.supported_channels[j] + wifi_chan_index;
7919 j+=1;
7920 }
7921 }
7922 StaParams.supported_channels_len = j;
7923 }
7924 vos_mem_copy(StaParams.supported_oper_classes,
7925 params->supported_oper_classes,
7926 params->supported_oper_classes_len);
7927 StaParams.supported_oper_classes_len =
7928 params->supported_oper_classes_len;
7929
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007930 if (0 != params->ext_capab_len)
7931 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
7932 sizeof(StaParams.extn_capability));
7933
7934 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007935 {
7936 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007937 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007938 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007939
7940 StaParams.supported_rates_len = params->supported_rates_len;
7941
7942 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
7943 * The supported_rates array , for all the structures propogating till Add Sta
7944 * to the firmware has to be modified , if the supplicant (ieee80211) is
7945 * modified to send more rates.
7946 */
7947
7948 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
7949 */
7950 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
7951 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
7952
7953 if (0 != StaParams.supported_rates_len) {
7954 int i = 0;
7955 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
7956 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007958 "Supported Rates with Length %d", StaParams.supported_rates_len);
7959 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007960 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007961 "[%d]: %0x", i, StaParams.supported_rates[i]);
7962 }
7963
7964 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007965 {
7966 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007967 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007968 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007969
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007970 if (0 != params->ext_capab_len ) {
7971 /*Define A Macro : TODO Sunil*/
7972 if ((1<<4) & StaParams.extn_capability[3]) {
7973 isBufSta = 1;
7974 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307975 /* TDLS Channel Switching Support */
7976 if ((1<<6) & StaParams.extn_capability[3]) {
7977 isOffChannelSupported = 1;
7978 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007979 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307980 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
7981 &StaParams, isBufSta,
7982 isOffChannelSupported);
7983
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307984 if (VOS_STATUS_SUCCESS != status) {
7985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7986 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
7987 return -EINVAL;
7988 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007989 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
7990
7991 if (VOS_STATUS_SUCCESS != status) {
7992 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7993 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
7994 return -EINVAL;
7995 }
7996 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007997#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05307998 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007999 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008000 return status;
8001}
8002
8003/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308004 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008005 * This function is used to initialize the key information
8006 */
8007#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308008static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008009 struct net_device *ndev,
8010 u8 key_index, bool pairwise,
8011 const u8 *mac_addr,
8012 struct key_params *params
8013 )
8014#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308015static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008016 struct net_device *ndev,
8017 u8 key_index, const u8 *mac_addr,
8018 struct key_params *params
8019 )
8020#endif
8021{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008022 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07008023 tCsrRoamSetKey setKey;
8024 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308025 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008026 v_U32_t roamId= 0xFF;
8027 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008028 hdd_hostapd_state_t *pHostapdState;
8029 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008030 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308031 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008032
8033 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308034
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308035 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8036 TRACE_CODE_HDD_CFG80211_ADD_KEY,
8037 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308038 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8039 status = wlan_hdd_validate_context(pHddCtx);
8040
8041 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008042 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8044 "%s: HDD context is not valid", __func__);
8045 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008046 }
8047
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308048 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8049 __func__, hdd_device_modetoString(pAdapter->device_mode),
8050 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008051
8052 if (CSR_MAX_NUM_KEY <= key_index)
8053 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008054 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008055 key_index);
8056
8057 return -EINVAL;
8058 }
8059
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008060 if (CSR_MAX_KEY_LEN < params->key_len)
8061 {
8062 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
8063 params->key_len);
8064
8065 return -EINVAL;
8066 }
8067
8068 hddLog(VOS_TRACE_LEVEL_INFO,
8069 "%s: called with key index = %d & key length %d",
8070 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008071
8072 /*extract key idx, key len and key*/
8073 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8074 setKey.keyId = key_index;
8075 setKey.keyLength = params->key_len;
8076 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
8077
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008078 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07008079 {
8080 case WLAN_CIPHER_SUITE_WEP40:
8081 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
8082 break;
8083
8084 case WLAN_CIPHER_SUITE_WEP104:
8085 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
8086 break;
8087
8088 case WLAN_CIPHER_SUITE_TKIP:
8089 {
8090 u8 *pKey = &setKey.Key[0];
8091 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
8092
8093 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
8094
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008095 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07008096
8097 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008098 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008099 |--------------|----------|----------|
8100 <---16bytes---><--8bytes--><--8bytes-->
8101
8102 */
8103 /*Sme expects the 32 bytes key to be in the below order
8104
8105 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008106 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008107 |--------------|----------|----------|
8108 <---16bytes---><--8bytes--><--8bytes-->
8109 */
8110 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008111 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07008112
8113 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008114 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008115
8116 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008117 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008118
8119
8120 break;
8121 }
8122
8123 case WLAN_CIPHER_SUITE_CCMP:
8124 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
8125 break;
8126
8127#ifdef FEATURE_WLAN_WAPI
8128 case WLAN_CIPHER_SUITE_SMS4:
8129 {
8130 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8131 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
8132 params->key, params->key_len);
8133 return 0;
8134 }
8135#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008136
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008137#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07008138 case WLAN_CIPHER_SUITE_KRK:
8139 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
8140 break;
8141#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008142
8143#ifdef WLAN_FEATURE_11W
8144 case WLAN_CIPHER_SUITE_AES_CMAC:
8145 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07008146 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07008147#endif
8148
Jeff Johnson295189b2012-06-20 16:38:30 -07008149 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008150 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07008151 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308152 status = -EOPNOTSUPP;
8153 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008154 }
8155
8156 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
8157 __func__, setKey.encType);
8158
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008159 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07008160#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8161 (!pairwise)
8162#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008163 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07008164#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008165 )
8166 {
8167 /* set group key*/
8168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8169 "%s- %d: setting Broadcast key",
8170 __func__, __LINE__);
8171 setKey.keyDirection = eSIR_RX_ONLY;
8172 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8173 }
8174 else
8175 {
8176 /* set pairwise key*/
8177 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8178 "%s- %d: setting pairwise key",
8179 __func__, __LINE__);
8180 setKey.keyDirection = eSIR_TX_RX;
8181 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8182 }
8183 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
8184 {
8185 setKey.keyDirection = eSIR_TX_RX;
8186 /*Set the group key*/
8187 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8188 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07008189
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008190 if ( 0 != status )
8191 {
8192 hddLog(VOS_TRACE_LEVEL_ERROR,
8193 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308194 status = -EINVAL;
8195 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008196 }
8197 /*Save the keys here and call sme_RoamSetKey for setting
8198 the PTK after peer joins the IBSS network*/
8199 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
8200 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308201 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008202 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05308203 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
8204 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
8205 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008206 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008207 if( pHostapdState->bssState == BSS_START )
8208 {
c_hpothu7c55da62014-01-23 18:34:02 +05308209 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8210 vos_status = wlan_hdd_check_ula_done(pAdapter);
8211
8212 if ( vos_status != VOS_STATUS_SUCCESS )
8213 {
8214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8215 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8216 __LINE__, vos_status );
8217
8218 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8219
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308220 status = -EINVAL;
8221 goto end;
c_hpothu7c55da62014-01-23 18:34:02 +05308222 }
8223
Jeff Johnson295189b2012-06-20 16:38:30 -07008224 status = WLANSAP_SetKeySta( pVosContext, &setKey);
8225
8226 if ( status != eHAL_STATUS_SUCCESS )
8227 {
8228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8229 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8230 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308231 status = -EINVAL;
8232 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008233 }
8234 }
8235
8236 /* Saving WEP keys */
8237 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
8238 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
8239 {
8240 //Save the wep key in ap context. Issue setkey after the BSS is started.
8241 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8242 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
8243 }
8244 else
8245 {
8246 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008247 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008248 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
8249 }
8250 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008251 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
8252 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008253 {
8254 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8255 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8256
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308257#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8258 if (!pairwise)
8259#else
8260 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8261#endif
8262 {
8263 /* set group key*/
8264 if (pHddStaCtx->roam_info.deferKeyComplete)
8265 {
8266 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8267 "%s- %d: Perform Set key Complete",
8268 __func__, __LINE__);
8269 hdd_PerformRoamSetKeyComplete(pAdapter);
8270 }
8271 }
8272
Jeff Johnson295189b2012-06-20 16:38:30 -07008273 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
8274
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08008275 pWextState->roamProfile.Keys.defaultIndex = key_index;
8276
8277
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008278 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008279 params->key, params->key_len);
8280
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308281
Jeff Johnson295189b2012-06-20 16:38:30 -07008282 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8283
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308284 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008285 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308286 __func__, setKey.peerMac[0], setKey.peerMac[1],
8287 setKey.peerMac[2], setKey.peerMac[3],
8288 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008289 setKey.keyDirection);
8290
8291 vos_status = wlan_hdd_check_ula_done(pAdapter);
8292
8293 if ( vos_status != VOS_STATUS_SUCCESS )
8294 {
8295 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8296 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8297 __LINE__, vos_status );
8298
8299 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8300
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308301 status = -EINVAL;
8302 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008303
8304 }
8305
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008306#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308307 /* The supplicant may attempt to set the PTK once pre-authentication
8308 is done. Save the key in the UMAC and include it in the ADD BSS
8309 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008310 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308311 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008312 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308313 hddLog(VOS_TRACE_LEVEL_INFO_MED,
8314 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308315 status = 0;
8316 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308317 }
8318 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
8319 {
8320 hddLog(VOS_TRACE_LEVEL_ERROR,
8321 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308322 status = -EINVAL;
8323 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008324 }
8325#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07008326
8327 /* issue set key request to SME*/
8328 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8329 pAdapter->sessionId, &setKey, &roamId );
8330
8331 if ( 0 != status )
8332 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308333 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008334 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
8335 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308336 status = -EINVAL;
8337 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008338 }
8339
8340
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308341 /* in case of IBSS as there was no information available about WEP keys during
8342 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07008343 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308344 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
8345 !( ( IW_AUTH_KEY_MGMT_802_1X
8346 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07008347 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
8348 )
8349 &&
8350 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
8351 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
8352 )
8353 )
8354 {
8355 setKey.keyDirection = eSIR_RX_ONLY;
8356 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8357
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308358 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008359 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308360 __func__, setKey.peerMac[0], setKey.peerMac[1],
8361 setKey.peerMac[2], setKey.peerMac[3],
8362 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008363 setKey.keyDirection);
8364
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308365 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008366 pAdapter->sessionId, &setKey, &roamId );
8367
8368 if ( 0 != status )
8369 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308370 hddLog(VOS_TRACE_LEVEL_ERROR,
8371 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008372 __func__, status);
8373 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308374 status = -EINVAL;
8375 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008376 }
8377 }
8378 }
8379
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308380end:
8381 /* Need to clear any trace of key value in the memory.
8382 * Thus zero out the memory even though it is local
8383 * variable.
8384 */
8385 vos_mem_zero(&setKey, sizeof(setKey));
8386
8387 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008388}
8389
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308390#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8391static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8392 struct net_device *ndev,
8393 u8 key_index, bool pairwise,
8394 const u8 *mac_addr,
8395 struct key_params *params
8396 )
8397#else
8398static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8399 struct net_device *ndev,
8400 u8 key_index, const u8 *mac_addr,
8401 struct key_params *params
8402 )
8403#endif
8404{
8405 int ret;
8406 vos_ssr_protect(__func__);
8407#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8408 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
8409 mac_addr, params);
8410#else
8411 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
8412 params);
8413#endif
8414 vos_ssr_unprotect(__func__);
8415
8416 return ret;
8417}
8418
Jeff Johnson295189b2012-06-20 16:38:30 -07008419/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308420 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008421 * This function is used to get the key information
8422 */
8423#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308424static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308425 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008426 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308427 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008428 const u8 *mac_addr, void *cookie,
8429 void (*callback)(void *cookie, struct key_params*)
8430 )
8431#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308432static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308433 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008434 struct net_device *ndev,
8435 u8 key_index, const u8 *mac_addr, void *cookie,
8436 void (*callback)(void *cookie, struct key_params*)
8437 )
8438#endif
8439{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308440 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308441 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8442 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Jeff Johnson295189b2012-06-20 16:38:30 -07008443 struct key_params params;
8444
8445 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308446
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308447 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8448 __func__, hdd_device_modetoString(pAdapter->device_mode),
8449 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308450
Jeff Johnson295189b2012-06-20 16:38:30 -07008451 memset(&params, 0, sizeof(params));
8452
8453 if (CSR_MAX_NUM_KEY <= key_index)
8454 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308455 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07008456 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308457 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008458
8459 switch(pRoamProfile->EncryptionType.encryptionType[0])
8460 {
8461 case eCSR_ENCRYPT_TYPE_NONE:
8462 params.cipher = IW_AUTH_CIPHER_NONE;
8463 break;
8464
8465 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
8466 case eCSR_ENCRYPT_TYPE_WEP40:
8467 params.cipher = WLAN_CIPHER_SUITE_WEP40;
8468 break;
8469
8470 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
8471 case eCSR_ENCRYPT_TYPE_WEP104:
8472 params.cipher = WLAN_CIPHER_SUITE_WEP104;
8473 break;
8474
8475 case eCSR_ENCRYPT_TYPE_TKIP:
8476 params.cipher = WLAN_CIPHER_SUITE_TKIP;
8477 break;
8478
8479 case eCSR_ENCRYPT_TYPE_AES:
8480 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
8481 break;
8482
8483 default:
8484 params.cipher = IW_AUTH_CIPHER_NONE;
8485 break;
8486 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308487
c_hpothuaaf19692014-05-17 17:01:48 +05308488 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8489 TRACE_CODE_HDD_CFG80211_GET_KEY,
8490 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308491
Jeff Johnson295189b2012-06-20 16:38:30 -07008492 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
8493 params.seq_len = 0;
8494 params.seq = NULL;
8495 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
8496 callback(cookie, &params);
8497 return 0;
8498}
8499
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308500#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8501static int wlan_hdd_cfg80211_get_key(
8502 struct wiphy *wiphy,
8503 struct net_device *ndev,
8504 u8 key_index, bool pairwise,
8505 const u8 *mac_addr, void *cookie,
8506 void (*callback)(void *cookie, struct key_params*)
8507 )
8508#else
8509static int wlan_hdd_cfg80211_get_key(
8510 struct wiphy *wiphy,
8511 struct net_device *ndev,
8512 u8 key_index, const u8 *mac_addr, void *cookie,
8513 void (*callback)(void *cookie, struct key_params*)
8514 )
8515#endif
8516{
8517 int ret;
8518
8519 vos_ssr_protect(__func__);
8520#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8521 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
8522 mac_addr, cookie, callback);
8523#else
8524 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
8525 callback);
8526#endif
8527 vos_ssr_unprotect(__func__);
8528
8529 return ret;
8530}
8531
Jeff Johnson295189b2012-06-20 16:38:30 -07008532/*
8533 * FUNCTION: wlan_hdd_cfg80211_del_key
8534 * This function is used to delete the key information
8535 */
8536#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308537static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008538 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308539 u8 key_index,
8540 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008541 const u8 *mac_addr
8542 )
8543#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308544static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008545 struct net_device *ndev,
8546 u8 key_index,
8547 const u8 *mac_addr
8548 )
8549#endif
8550{
8551 int status = 0;
8552
8553 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308554 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07008555 //it is observed that this is invalidating peer
8556 //key index whenever re-key is done. This is affecting data link.
8557 //It should be ok to ignore del_key.
8558#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308559 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
8560 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008561 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
8562 tCsrRoamSetKey setKey;
8563 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308564
Jeff Johnson295189b2012-06-20 16:38:30 -07008565 ENTER();
8566
8567 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
8568 __func__,pAdapter->device_mode);
8569
8570 if (CSR_MAX_NUM_KEY <= key_index)
8571 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308572 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008573 key_index);
8574
8575 return -EINVAL;
8576 }
8577
8578 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8579 setKey.keyId = key_index;
8580
8581 if (mac_addr)
8582 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8583 else
8584 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
8585
8586 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
8587
8588 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008589 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308590 )
8591 {
8592
8593 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07008594 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8595 if( pHostapdState->bssState == BSS_START)
8596 {
8597 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308598
Jeff Johnson295189b2012-06-20 16:38:30 -07008599 if ( status != eHAL_STATUS_SUCCESS )
8600 {
8601 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8602 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8603 __LINE__, status );
8604 }
8605 }
8606 }
8607 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308608 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07008609 )
8610 {
8611 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8612
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308613 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8614
8615 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008616 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308617 __func__, setKey.peerMac[0], setKey.peerMac[1],
8618 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07008619 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308620 if(pAdapter->sessionCtx.station.conn_info.connState ==
8621 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07008622 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308623 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008624 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308625
Jeff Johnson295189b2012-06-20 16:38:30 -07008626 if ( 0 != status )
8627 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308628 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008629 "%s: sme_RoamSetKey failure, returned %d",
8630 __func__, status);
8631 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8632 return -EINVAL;
8633 }
8634 }
8635 }
8636#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008637 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008638 return status;
8639}
8640
8641/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308642 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008643 * This function is used to set the default tx key index
8644 */
8645#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
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 bool unicast, bool multicast)
8650#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308651static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008652 struct net_device *ndev,
8653 u8 key_index)
8654#endif
8655{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308656 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308657 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308658 hdd_wext_state_t *pWextState;
8659 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308660 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008661
8662 ENTER();
8663
Gopichand Nakkala29149562013-05-10 21:43:41 +05308664 if ((NULL == pAdapter))
8665 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308667 "invalid adapter");
8668 return -EINVAL;
8669 }
8670
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308671 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8672 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
8673 pAdapter->sessionId, key_index));
8674
Gopichand Nakkala29149562013-05-10 21:43:41 +05308675 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8676 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8677
8678 if ((NULL == pWextState) || (NULL == pHddStaCtx))
8679 {
8680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8681 "invalid Wext state or HDD context");
8682 return -EINVAL;
8683 }
8684
Arif Hussain6d2a3322013-11-17 19:50:10 -08008685 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008686 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308687
Jeff Johnson295189b2012-06-20 16:38:30 -07008688 if (CSR_MAX_NUM_KEY <= key_index)
8689 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308690 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008691 key_index);
8692
8693 return -EINVAL;
8694 }
8695
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308696 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8697 status = wlan_hdd_validate_context(pHddCtx);
8698
8699 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008700 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8702 "%s: HDD context is not valid", __func__);
8703 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008704 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308705
Jeff Johnson295189b2012-06-20 16:38:30 -07008706 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008707 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308708 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008709 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308710 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08008711 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308712 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08008713 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07008714 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308715 {
8716 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07008717 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308718
Jeff Johnson295189b2012-06-20 16:38:30 -07008719 tCsrRoamSetKey setKey;
8720 v_U32_t roamId= 0xFF;
8721 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308722
8723 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008724 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308725
Jeff Johnson295189b2012-06-20 16:38:30 -07008726 Keys->defaultIndex = (u8)key_index;
8727 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8728 setKey.keyId = key_index;
8729 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308730
8731 vos_mem_copy(&setKey.Key[0],
8732 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008733 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308734
Gopichand Nakkala29149562013-05-10 21:43:41 +05308735 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308736
8737 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07008738 &pHddStaCtx->conn_info.bssId[0],
8739 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308740
Gopichand Nakkala29149562013-05-10 21:43:41 +05308741 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
8742 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
8743 eCSR_ENCRYPT_TYPE_WEP104)
8744 {
8745 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
8746 even though ap is configured for WEP-40 encryption. In this canse the key length
8747 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
8748 type(104) and switching encryption type to 40*/
8749 pWextState->roamProfile.EncryptionType.encryptionType[0] =
8750 eCSR_ENCRYPT_TYPE_WEP40;
8751 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
8752 eCSR_ENCRYPT_TYPE_WEP40;
8753 }
8754
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308755 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07008756 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308757
Jeff Johnson295189b2012-06-20 16:38:30 -07008758 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308759 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008760 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308761
Jeff Johnson295189b2012-06-20 16:38:30 -07008762 if ( 0 != status )
8763 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308764 hddLog(VOS_TRACE_LEVEL_ERROR,
8765 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008766 status);
8767 return -EINVAL;
8768 }
8769 }
8770 }
8771
8772 /* In SoftAp mode setting key direction for default mode */
8773 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
8774 {
8775 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
8776 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
8777 (eCSR_ENCRYPT_TYPE_AES !=
8778 pWextState->roamProfile.EncryptionType.encryptionType[0])
8779 )
8780 {
8781 /* Saving key direction for default key index to TX default */
8782 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8783 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
8784 }
8785 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308786
Jeff Johnson295189b2012-06-20 16:38:30 -07008787 return status;
8788}
8789
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308790#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8791static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8792 struct net_device *ndev,
8793 u8 key_index,
8794 bool unicast, bool multicast)
8795#else
8796static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8797 struct net_device *ndev,
8798 u8 key_index)
8799#endif
8800{
8801 int ret;
8802 vos_ssr_protect(__func__);
8803#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8804 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
8805 multicast);
8806#else
8807 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
8808#endif
8809 vos_ssr_unprotect(__func__);
8810
8811 return ret;
8812}
8813
Jeff Johnson295189b2012-06-20 16:38:30 -07008814/*
8815 * FUNCTION: wlan_hdd_cfg80211_inform_bss
8816 * This function is used to inform the BSS details to nl80211 interface.
8817 */
8818static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
8819 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
8820{
8821 struct net_device *dev = pAdapter->dev;
8822 struct wireless_dev *wdev = dev->ieee80211_ptr;
8823 struct wiphy *wiphy = wdev->wiphy;
8824 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
8825 int chan_no;
8826 int ie_length;
8827 const char *ie;
8828 unsigned int freq;
8829 struct ieee80211_channel *chan;
8830 int rssi = 0;
8831 struct cfg80211_bss *bss = NULL;
8832
8833 ENTER();
8834
8835 if( NULL == pBssDesc )
8836 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008837 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008838 return bss;
8839 }
8840
8841 chan_no = pBssDesc->channelId;
8842 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
8843 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
8844
8845 if( NULL == ie )
8846 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008847 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008848 return bss;
8849 }
8850
8851#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8852 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8853 {
8854 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8855 }
8856 else
8857 {
8858 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8859 }
8860#else
8861 freq = ieee80211_channel_to_frequency(chan_no);
8862#endif
8863
8864 chan = __ieee80211_get_channel(wiphy, freq);
8865
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05308866 if (!chan) {
8867 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
8868 return NULL;
8869 }
8870
Abhishek Singhaee43942014-06-16 18:55:47 +05308871 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07008872
Abhishek Singhaee43942014-06-16 18:55:47 +05308873 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308874 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07008875 pBssDesc->capabilityInfo,
8876 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05308877 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07008878}
8879
8880
8881
8882/*
8883 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
8884 * This function is used to inform the BSS details to nl80211 interface.
8885 */
8886struct cfg80211_bss*
8887wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
8888 tSirBssDescription *bss_desc
8889 )
8890{
8891 /*
8892 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
8893 already exists in bss data base of cfg80211 for that particular BSS ID.
8894 Using cfg80211_inform_bss_frame to update the bss entry instead of
8895 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
8896 now there is no possibility to get the mgmt(probe response) frame from PE,
8897 converting bss_desc to ieee80211_mgmt(probe response) and passing to
8898 cfg80211_inform_bss_frame.
8899 */
8900 struct net_device *dev = pAdapter->dev;
8901 struct wireless_dev *wdev = dev->ieee80211_ptr;
8902 struct wiphy *wiphy = wdev->wiphy;
8903 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008904#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8905 qcom_ie_age *qie_age = NULL;
8906 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
8907#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008908 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008909#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008910 const char *ie =
8911 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
8912 unsigned int freq;
8913 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05308914 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008915 struct cfg80211_bss *bss_status = NULL;
8916 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
8917 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07008918 hdd_context_t *pHddCtx;
8919 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07008920#ifdef WLAN_OPEN_SOURCE
8921 struct timespec ts;
8922#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008923
Wilson Yangf80a0542013-10-07 13:02:37 -07008924 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8925 status = wlan_hdd_validate_context(pHddCtx);
8926
8927 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308928 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008929 {
8930 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8931 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8932 return NULL;
8933 }
8934
8935
8936 if (0 != status)
8937 {
8938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8939 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008940 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008941 }
8942
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05308943 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07008944 if (!mgmt)
8945 {
8946 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8947 "%s: memory allocation failed ", __func__);
8948 return NULL;
8949 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008950
Jeff Johnson295189b2012-06-20 16:38:30 -07008951 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07008952
8953#ifdef WLAN_OPEN_SOURCE
8954 /* Android does not want the timestamp from the frame.
8955 Instead it wants a monotonic increasing value */
8956 get_monotonic_boottime(&ts);
8957 mgmt->u.probe_resp.timestamp =
8958 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
8959#else
8960 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07008961 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
8962 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07008963
8964#endif
8965
Jeff Johnson295189b2012-06-20 16:38:30 -07008966 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
8967 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008968
8969#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8970 /* GPS Requirement: need age ie per entry. Using vendor specific. */
8971 /* Assuming this is the last IE, copy at the end */
8972 ie_length -=sizeof(qcom_ie_age);
8973 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
8974 qie_age->element_id = QCOM_VENDOR_IE_ID;
8975 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
8976 qie_age->oui_1 = QCOM_OUI1;
8977 qie_age->oui_2 = QCOM_OUI2;
8978 qie_age->oui_3 = QCOM_OUI3;
8979 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
8980 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
8981#endif
8982
Jeff Johnson295189b2012-06-20 16:38:30 -07008983 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05308984 if (bss_desc->fProbeRsp)
8985 {
8986 mgmt->frame_control |=
8987 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
8988 }
8989 else
8990 {
8991 mgmt->frame_control |=
8992 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
8993 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008994
8995#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308996 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008997 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
8998 {
8999 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9000 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309001 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009002 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
9003
9004 {
9005 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9006 }
9007 else
9008 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309009 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
9010 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07009011 kfree(mgmt);
9012 return NULL;
9013 }
9014#else
9015 freq = ieee80211_channel_to_frequency(chan_no);
9016#endif
9017 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009018 /*when the band is changed on the fly using the GUI, three things are done
9019 * 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)
9020 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
9021 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
9022 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
9023 * and discards the channels correponding to previous band and calls back with zero bss results.
9024 * 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
9025 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
9026 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
9027 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
9028 * So drop the bss and continue to next bss.
9029 */
9030 if(chan == NULL)
9031 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309032 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07009033 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009034 return NULL;
9035 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009036 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309037 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07009038 * */
9039 if (( eConnectionState_Associated ==
9040 pAdapter->sessionCtx.station.conn_info.connState ) &&
9041 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
9042 pAdapter->sessionCtx.station.conn_info.bssId,
9043 WNI_CFG_BSSID_LEN)))
9044 {
9045 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
9046 rssi = (pAdapter->rssi * 100);
9047 }
9048 else
9049 {
9050 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
9051 }
9052
Nirav Shah20ac06f2013-12-12 18:14:06 +05309053 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
9054 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
9055 chan->center_freq, (int)(rssi/100));
9056
Jeff Johnson295189b2012-06-20 16:38:30 -07009057 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
9058 frame_len, rssi, GFP_KERNEL);
9059 kfree(mgmt);
9060 return bss_status;
9061}
9062
9063/*
9064 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
9065 * This function is used to update the BSS data base of CFG8011
9066 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309067struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009068 tCsrRoamInfo *pRoamInfo
9069 )
9070{
9071 tCsrRoamConnectedProfile roamProfile;
9072 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9073 struct cfg80211_bss *bss = NULL;
9074
9075 ENTER();
9076
9077 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
9078 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
9079
9080 if (NULL != roamProfile.pBssDesc)
9081 {
Girish Gowlif4b68022014-08-28 23:18:57 +05309082 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9083 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009084
9085 if (NULL == bss)
9086 {
9087 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
9088 __func__);
9089 }
9090
9091 sme_RoamFreeConnectProfile(hHal, &roamProfile);
9092 }
9093 else
9094 {
9095 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
9096 __func__);
9097 }
9098 return bss;
9099}
9100
9101/*
9102 * FUNCTION: wlan_hdd_cfg80211_update_bss
9103 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309104static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
9105 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07009106 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309107{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309108 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009109 tCsrScanResultInfo *pScanResult;
9110 eHalStatus status = 0;
9111 tScanResultHandle pResult;
9112 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009113 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009114
9115 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309116
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309117 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9118 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
9119 NO_SESSION, pAdapter->sessionId));
9120
Wilson Yangf80a0542013-10-07 13:02:37 -07009121 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9122
9123 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009124 {
Wilson Yangf80a0542013-10-07 13:02:37 -07009125 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9126 "%s:LOGP in Progress. Ignore!!!",__func__);
9127 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009128 }
9129
Wilson Yangf80a0542013-10-07 13:02:37 -07009130
9131 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309132 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009133 {
9134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9135 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9136 return VOS_STATUS_E_PERM;
9137 }
9138
9139
Jeff Johnson295189b2012-06-20 16:38:30 -07009140 /*
9141 * start getting scan results and populate cgf80211 BSS database
9142 */
9143 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
9144
9145 /* no scan results */
9146 if (NULL == pResult)
9147 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309148 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
9149 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009150 return status;
9151 }
9152
9153 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
9154
9155 while (pScanResult)
9156 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309157 /*
9158 * cfg80211_inform_bss() is not updating ie field of bss entry, if
9159 * entry already exists in bss data base of cfg80211 for that
9160 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
9161 * bss entry instead of cfg80211_inform_bss, But this call expects
9162 * mgmt packet as input. As of now there is no possibility to get
9163 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07009164 * ieee80211_mgmt(probe response) and passing to c
9165 * fg80211_inform_bss_frame.
9166 * */
9167
9168 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9169 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309170
Jeff Johnson295189b2012-06-20 16:38:30 -07009171
9172 if (NULL == bss_status)
9173 {
9174 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009175 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009176 }
9177 else
9178 {
Yue Maf49ba872013-08-19 12:04:25 -07009179 cfg80211_put_bss(
9180#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
9181 wiphy,
9182#endif
9183 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009184 }
9185
9186 pScanResult = sme_ScanResultGetNext(hHal, pResult);
9187 }
9188
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309189 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07009190
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309191 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009192}
9193
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009194void
9195hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
9196{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309197 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08009198 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009199} /****** end hddPrintMacAddr() ******/
9200
9201void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009202hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009203{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309204 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009205 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009206 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
9207 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
9208 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009209} /****** end hddPrintPmkId() ******/
9210
9211//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
9212//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
9213
9214//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
9215//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
9216
9217#define dump_bssid(bssid) \
9218 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009219 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
9220 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009221 }
9222
9223#define dump_pmkid(pMac, pmkid) \
9224 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009225 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
9226 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009227 }
9228
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009229#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009230/*
9231 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
9232 * This function is used to notify the supplicant of a new PMKSA candidate.
9233 */
9234int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309235 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009236 int index, bool preauth )
9237{
Jeff Johnsone7245742012-09-05 17:12:55 -07009238#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009239 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009240 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009241
9242 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07009243 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009244
9245 if( NULL == pRoamInfo )
9246 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009247 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009248 return -EINVAL;
9249 }
9250
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009251 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
9252 {
9253 dump_bssid(pRoamInfo->bssid);
9254 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009255 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009256 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009257#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309258 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009259}
9260#endif //FEATURE_WLAN_LFR
9261
Yue Maef608272013-04-08 23:09:17 -07009262#ifdef FEATURE_WLAN_LFR_METRICS
9263/*
9264 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
9265 * 802.11r/LFR metrics reporting function to report preauth initiation
9266 *
9267 */
9268#define MAX_LFR_METRICS_EVENT_LENGTH 100
9269VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
9270 tCsrRoamInfo *pRoamInfo)
9271{
9272 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9273 union iwreq_data wrqu;
9274
9275 ENTER();
9276
9277 if (NULL == pAdapter)
9278 {
9279 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9280 return VOS_STATUS_E_FAILURE;
9281 }
9282
9283 /* create the event */
9284 memset(&wrqu, 0, sizeof(wrqu));
9285 memset(metrics_notification, 0, sizeof(metrics_notification));
9286
9287 wrqu.data.pointer = metrics_notification;
9288 wrqu.data.length = scnprintf(metrics_notification,
9289 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
9290 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9291
9292 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9293
9294 EXIT();
9295
9296 return VOS_STATUS_SUCCESS;
9297}
9298
9299/*
9300 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
9301 * 802.11r/LFR metrics reporting function to report preauth completion
9302 * or failure
9303 */
9304VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
9305 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
9306{
9307 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9308 union iwreq_data wrqu;
9309
9310 ENTER();
9311
9312 if (NULL == pAdapter)
9313 {
9314 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9315 return VOS_STATUS_E_FAILURE;
9316 }
9317
9318 /* create the event */
9319 memset(&wrqu, 0, sizeof(wrqu));
9320 memset(metrics_notification, 0, sizeof(metrics_notification));
9321
9322 scnprintf(metrics_notification, sizeof(metrics_notification),
9323 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
9324 MAC_ADDR_ARRAY(pRoamInfo->bssid));
9325
9326 if (1 == preauth_status)
9327 strncat(metrics_notification, " TRUE", 5);
9328 else
9329 strncat(metrics_notification, " FALSE", 6);
9330
9331 wrqu.data.pointer = metrics_notification;
9332 wrqu.data.length = strlen(metrics_notification);
9333
9334 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9335
9336 EXIT();
9337
9338 return VOS_STATUS_SUCCESS;
9339}
9340
9341/*
9342 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
9343 * 802.11r/LFR metrics reporting function to report handover initiation
9344 *
9345 */
9346VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
9347 tCsrRoamInfo *pRoamInfo)
9348{
9349 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9350 union iwreq_data wrqu;
9351
9352 ENTER();
9353
9354 if (NULL == pAdapter)
9355 {
9356 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9357 return VOS_STATUS_E_FAILURE;
9358 }
9359
9360 /* create the event */
9361 memset(&wrqu, 0, sizeof(wrqu));
9362 memset(metrics_notification, 0, sizeof(metrics_notification));
9363
9364 wrqu.data.pointer = metrics_notification;
9365 wrqu.data.length = scnprintf(metrics_notification,
9366 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
9367 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9368
9369 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9370
9371 EXIT();
9372
9373 return VOS_STATUS_SUCCESS;
9374}
9375#endif
9376
Jeff Johnson295189b2012-06-20 16:38:30 -07009377/*
9378 * FUNCTION: hdd_cfg80211_scan_done_callback
9379 * scanning callback function, called after finishing scan
9380 *
9381 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309382static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07009383 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
9384{
9385 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309386 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009387 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009388 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9389 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07009390 struct cfg80211_scan_request *req = NULL;
9391 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309392 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309393 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009394
9395 ENTER();
9396
9397 hddLog(VOS_TRACE_LEVEL_INFO,
9398 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08009399 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009400 __func__, halHandle, pContext, (int) scanId, (int) status);
9401
Kiet Lamac06e2c2013-10-23 16:25:07 +05309402 pScanInfo->mScanPendingCounter = 0;
9403
Jeff Johnson295189b2012-06-20 16:38:30 -07009404 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309405 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009406 &pScanInfo->scan_req_completion_event,
9407 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309408 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009409 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309410 hddLog(VOS_TRACE_LEVEL_ERROR,
9411 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07009412 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009413 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009414 }
9415
Yue Maef608272013-04-08 23:09:17 -07009416 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07009417 {
9418 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009419 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009420 }
9421
9422 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309423 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07009424 {
9425 hddLog(VOS_TRACE_LEVEL_INFO,
9426 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009427 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07009428 (int) scanId);
9429 }
9430
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309431 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009432 pAdapter);
9433
9434 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309435 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009436
9437
9438 /* If any client wait scan result through WEXT
9439 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009440 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07009441 {
9442 /* The other scan request waiting for current scan finish
9443 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009444 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009445 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009446 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07009447 }
9448 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009449 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009450 {
9451 struct net_device *dev = pAdapter->dev;
9452 union iwreq_data wrqu;
9453 int we_event;
9454 char *msg;
9455
9456 memset(&wrqu, '\0', sizeof(wrqu));
9457 we_event = SIOCGIWSCAN;
9458 msg = NULL;
9459 wireless_send_event(dev, we_event, &wrqu, msg);
9460 }
9461 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009462 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009463
9464 /* Get the Scan Req */
9465 req = pAdapter->request;
9466
9467 if (!req)
9468 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009469 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009470 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07009471 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009472 }
9473
9474 /*
9475 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309476 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009477 req->n_ssids = 0;
9478 req->n_channels = 0;
9479 req->ie = 0;
9480
Jeff Johnson295189b2012-06-20 16:38:30 -07009481 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009482 /* Scan is no longer pending */
9483 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009484
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07009485 /*
9486 * cfg80211_scan_done informing NL80211 about completion
9487 * of scanning
9488 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309489 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
9490 {
9491 aborted = true;
9492 }
9493 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009494 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07009495
Siddharth Bhal76972212014-10-15 16:22:51 +05309496 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
9497 /* Generate new random mac addr for next scan */
9498 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
9499 hdd_processSpoofMacAddrRequest(pHddCtx);
9500 }
9501
Jeff Johnsone7245742012-09-05 17:12:55 -07009502allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009503 /* release the wake lock at the end of the scan*/
9504 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009505
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009506 /* Acquire wakelock to handle the case where APP's tries to suspend
9507 * immediatly after the driver gets connect request(i.e after scan)
9508 * from supplicant, this result in app's is suspending and not able
9509 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309510 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009511
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009512#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05309513 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
9514 {
9515 wlan_hdd_tdls_scan_done_callback(pAdapter);
9516 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009517#endif
9518
Jeff Johnson295189b2012-06-20 16:38:30 -07009519 EXIT();
9520 return 0;
9521}
9522
9523/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05309524 * FUNCTION: hdd_isConnectionInProgress
9525 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009526 *
9527 */
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309528v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx, v_BOOL_t isRoC )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009529{
9530 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9531 hdd_station_ctx_t *pHddStaCtx = NULL;
9532 hdd_adapter_t *pAdapter = NULL;
9533 VOS_STATUS status = 0;
9534 v_U8_t staId = 0;
9535 v_U8_t *staMac = NULL;
9536
c_hpothu9b781ba2013-12-30 20:57:45 +05309537 if (TRUE == pHddCtx->btCoexModeSet)
9538 {
9539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05309540 FL("BTCoex Mode operation in progress"));
9541 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05309542 }
9543
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009544 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9545
9546 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9547 {
9548 pAdapter = pAdapterNode->pAdapter;
9549
9550 if( pAdapter )
9551 {
9552 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309553 "%s: Adapter with device mode %s (%d) exists",
9554 __func__, hdd_device_modetoString(pAdapter->device_mode),
9555 pAdapter->device_mode);
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309556 if ((((!isRoC) && (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +05309557 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9558 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
9559 (eConnectionState_Connecting ==
9560 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
9561 {
9562 hddLog(VOS_TRACE_LEVEL_ERROR,
9563 "%s: %p(%d) Connection is in progress", __func__,
9564 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
9565 return VOS_TRUE;
9566 }
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309567 if (((!isRoC) && (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309568 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9569 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009570 {
9571 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9572 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309573 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009574 {
9575 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
9576 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009577 "%s: client " MAC_ADDRESS_STR
9578 " is in the middle of WPS/EAPOL exchange.", __func__,
9579 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309580 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009581 }
9582 }
9583 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
9584 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
9585 {
9586 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
9587 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309588 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009589 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
9590 {
9591 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
9592
9593 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009594 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
9595 "middle of WPS/EAPOL exchange.", __func__,
9596 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309597 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009598 }
9599 }
9600 }
9601 }
9602 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9603 pAdapterNode = pNext;
9604 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05309605 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309606}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009607
9608/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309609 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07009610 * this scan respond to scan trigger and update cfg80211 scan database
9611 * later, scan dump command can be used to recieve scan results
9612 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309613int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009614#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9615 struct net_device *dev,
9616#endif
9617 struct cfg80211_scan_request *request)
9618{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309619 hdd_adapter_t *pAdapter = NULL;
9620 hdd_context_t *pHddCtx = NULL;
9621 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309622 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009623 tCsrScanRequest scanRequest;
9624 tANI_U8 *channelList = NULL, i;
9625 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309626 int status;
9627 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009628 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009629
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309630#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
9631 struct net_device *dev = NULL;
9632 if (NULL == request)
9633 {
9634 hddLog(VOS_TRACE_LEVEL_ERROR,
9635 "%s: scan req param null", __func__);
9636 return -EINVAL;
9637 }
9638 dev = request->wdev->netdev;
9639#endif
9640
9641 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
9642 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9643 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9644
Jeff Johnson295189b2012-06-20 16:38:30 -07009645 ENTER();
9646
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309647
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309648 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9649 __func__, hdd_device_modetoString(pAdapter->device_mode),
9650 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309651
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309652 status = wlan_hdd_validate_context(pHddCtx);
9653
9654 if (0 != status)
9655 {
9656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9657 "%s: HDD context is not valid", __func__);
9658 return status;
9659 }
9660
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309661 if (NULL == pwextBuf)
9662 {
9663 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
9664 __func__);
9665 return -EIO;
9666 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309667 cfg_param = pHddCtx->cfg_ini;
9668 pScanInfo = &pHddCtx->scan_info;
9669
Jeff Johnson295189b2012-06-20 16:38:30 -07009670#ifdef WLAN_BTAMP_FEATURE
9671 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009672 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07009673 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009674 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009675 "%s: No scanning when AMP is on", __func__);
9676 return -EOPNOTSUPP;
9677 }
9678#endif
9679 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009680 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009681 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009682 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309683 "%s: Not scanning on device_mode = %s (%d)",
9684 __func__, hdd_device_modetoString(pAdapter->device_mode),
9685 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009686 return -EOPNOTSUPP;
9687 }
9688
9689 if (TRUE == pScanInfo->mScanPending)
9690 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309691 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
9692 {
9693 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
9694 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009695 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009696 }
9697
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309698 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07009699 //Channel and action frame is pending
9700 //Otherwise Cancel Remain On Channel and allow Scan
9701 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009702 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07009703 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309704 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009705 return -EBUSY;
9706 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009707#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009708 /* if tdls disagree scan right now, return immediately.
9709 tdls will schedule the scan when scan is allowed. (return SUCCESS)
9710 or will reject the scan if any TDLS is in progress. (return -EBUSY)
9711 */
9712 status = wlan_hdd_tdls_scan_callback (pAdapter,
9713 wiphy,
9714#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9715 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07009716#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009717 request);
9718 if(status <= 0)
9719 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309720 if(!status)
9721 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
9722 "scan rejected %d", __func__, status);
9723 else
9724 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
9725 __func__, status);
9726
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009727 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009728 }
9729#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07009730
Jeff Johnson295189b2012-06-20 16:38:30 -07009731 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
9732 {
9733 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08009734 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009735 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309736 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009737 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
9738 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309739 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009740 "%s: MAX TM Level Scan not allowed", __func__);
9741 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309742 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009743 }
9744 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
9745
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009746 /* Check if scan is allowed at this point of time.
9747 */
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309748 if (hdd_isConnectionInProgress(pHddCtx, VOS_FALSE))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009749 {
9750 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
9751 return -EBUSY;
9752 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309753
Jeff Johnson295189b2012-06-20 16:38:30 -07009754 vos_mem_zero( &scanRequest, sizeof(scanRequest));
9755
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309756 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
9757 (int)request->n_ssids);
9758
9759 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
9760 * Becasue of this, driver is assuming that this is not wildcard scan and so
9761 * is not aging out the scan results.
9762 */
9763 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07009764 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309765 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009766 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309767
9768 if ((request->ssids) && (0 < request->n_ssids))
9769 {
9770 tCsrSSIDInfo *SsidInfo;
9771 int j;
9772 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
9773 /* Allocate num_ssid tCsrSSIDInfo structure */
9774 SsidInfo = scanRequest.SSIDs.SSIDList =
9775 ( tCsrSSIDInfo *)vos_mem_malloc(
9776 request->n_ssids*sizeof(tCsrSSIDInfo));
9777
9778 if(NULL == scanRequest.SSIDs.SSIDList)
9779 {
9780 hddLog(VOS_TRACE_LEVEL_ERROR,
9781 "%s: memory alloc failed SSIDInfo buffer", __func__);
9782 return -ENOMEM;
9783 }
9784
9785 /* copy all the ssid's and their length */
9786 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
9787 {
9788 /* get the ssid length */
9789 SsidInfo->SSID.length = request->ssids[j].ssid_len;
9790 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
9791 SsidInfo->SSID.length);
9792 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
9793 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
9794 j, SsidInfo->SSID.ssId);
9795 }
9796 /* set the scan type to active */
9797 scanRequest.scanType = eSIR_ACTIVE_SCAN;
9798 }
9799 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07009800 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309801 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9802 TRACE_CODE_HDD_CFG80211_SCAN,
9803 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07009804 /* set the scan type to active */
9805 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009806 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309807 else
9808 {
9809 /*Set the scan type to default type, in this case it is ACTIVE*/
9810 scanRequest.scanType = pScanInfo->scan_mode;
9811 }
9812 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
9813 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07009814
9815 /* set BSSType to default type */
9816 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
9817
9818 /*TODO: scan the requested channels only*/
9819
9820 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309821 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -07009822 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309823 hddLog(VOS_TRACE_LEVEL_WARN,
9824 "No of Scan Channels exceeded limit: %d", request->n_channels);
9825 request->n_channels = MAX_CHANNEL;
9826 }
9827
9828 hddLog(VOS_TRACE_LEVEL_INFO,
9829 "No of Scan Channels: %d", request->n_channels);
9830
9831
9832 if( request->n_channels )
9833 {
9834 char chList [(request->n_channels*5)+1];
9835 int len;
9836 channelList = vos_mem_malloc( request->n_channels );
9837 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +05309838 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309839 hddLog(VOS_TRACE_LEVEL_ERROR,
9840 "%s: memory alloc failed channelList", __func__);
9841 status = -ENOMEM;
9842 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +05309843 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309844
9845 for( i = 0, len = 0; i < request->n_channels ; i++ )
9846 {
9847 channelList[i] = request->channels[i]->hw_value;
9848 len += snprintf(chList+len, 5, "%d ", channelList[i]);
9849 }
9850
Nirav Shah20ac06f2013-12-12 18:14:06 +05309851 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309852 "Channel-List: %s ", chList);
9853 }
c_hpothu53512302014-04-15 18:49:53 +05309854
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309855 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
9856 scanRequest.ChannelInfo.ChannelList = channelList;
9857
9858 /* set requestType to full scan */
9859 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
9860
9861 /* Flush the scan results(only p2p beacons) for STA scan and P2P
9862 * search (Flush on both full scan and social scan but not on single
9863 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
9864 */
9865
9866 /* Supplicant does single channel scan after 8-way handshake
9867 * and in that case driver shoudnt flush scan results. If
9868 * driver flushes the scan results here and unfortunately if
9869 * the AP doesnt respond to our probe req then association
9870 * fails which is not desired
9871 */
9872
9873 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
9874 {
9875 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
9876 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
9877 pAdapter->sessionId );
9878 }
9879
9880 if( request->ie_len )
9881 {
9882 /* save this for future association (join requires this) */
9883 /*TODO: Array needs to be converted to dynamic allocation,
9884 * as multiple ie.s can be sent in cfg80211_scan_request structure
9885 * CR 597966
9886 */
9887 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
9888 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
9889 pScanInfo->scanAddIE.length = request->ie_len;
9890
9891 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9892 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9893 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07009894 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309895 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -07009896 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309897 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
9898 memcpy( pwextBuf->roamProfile.addIEScan,
9899 request->ie, request->ie_len);
9900 }
9901 else
9902 {
9903 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
9904 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009905 }
9906
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309907 }
9908 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
9909 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
9910
9911 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
9912 request->ie_len);
9913 if (pP2pIe != NULL)
9914 {
9915#ifdef WLAN_FEATURE_P2P_DEBUG
9916 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
9917 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
9918 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +05309919 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309920 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
9921 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9922 "Go nego completed to Connection is started");
9923 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9924 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +05309925 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309926 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
9927 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07009928 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309929 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
9930 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9931 "Disconnected state to Connection is started");
9932 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9933 "for 4way Handshake");
9934 }
9935#endif
9936
9937 /* no_cck will be set during p2p find to disable 11b rates */
9938 if(TRUE == request->no_cck)
9939 {
9940 hddLog(VOS_TRACE_LEVEL_INFO,
9941 "%s: This is a P2P Search", __func__);
9942 scanRequest.p2pSearch = 1;
9943
9944 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +05309945 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309946 /* set requestType to P2P Discovery */
9947 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
9948 }
9949
9950 /*
9951 Skip Dfs Channel in case of P2P Search
9952 if it is set in ini file
9953 */
9954 if(cfg_param->skipDfsChnlInP2pSearch)
9955 {
9956 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309957 }
9958 else
9959 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309960 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309961 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009962
Agarwal Ashish4f616132013-12-30 23:32:50 +05309963 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009964 }
9965 }
9966
9967 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
9968
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009969 /* acquire the wakelock to avoid the apps suspend during the scan. To
9970 * address the following issues.
9971 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
9972 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
9973 * for long time, this result in apps running at full power for long time.
9974 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
9975 * be stuck in full power because of resume BMPS
9976 */
9977 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009978
Nirav Shah20ac06f2013-12-12 18:14:06 +05309979 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9980 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309981 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
9982 scanRequest.requestType, scanRequest.scanType,
9983 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05309984 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
9985
Siddharth Bhal76972212014-10-15 16:22:51 +05309986 if (pHddCtx->spoofMacAddr.isEnabled)
9987 {
9988 hddLog(VOS_TRACE_LEVEL_INFO,
9989 "%s: MAC Spoofing enabled for current scan", __func__);
9990 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
9991 * to fill TxBds for probe request during current scan
9992 */
9993 WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
9994 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
9995 }
9996
Jeff Johnsone7245742012-09-05 17:12:55 -07009997 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009998 pAdapter->sessionId, &scanRequest, &scanId,
9999 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070010000
Jeff Johnson295189b2012-06-20 16:38:30 -070010001 if (eHAL_STATUS_SUCCESS != status)
10002 {
10003 hddLog(VOS_TRACE_LEVEL_ERROR,
10004 "%s: sme_ScanRequest returned error %d", __func__, status);
10005 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010006 if(eHAL_STATUS_RESOURCES == status)
10007 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010008 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
10009 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010010 status = -EBUSY;
10011 } else {
10012 status = -EIO;
10013 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010014 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -070010015 goto free_mem;
10016 }
10017
10018 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010019 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070010020 pAdapter->request = request;
10021 pScanInfo->scanId = scanId;
10022
10023 complete(&pScanInfo->scan_req_completion_event);
10024
10025free_mem:
10026 if( scanRequest.SSIDs.SSIDList )
10027 {
10028 vos_mem_free(scanRequest.SSIDs.SSIDList);
10029 }
10030
10031 if( channelList )
10032 vos_mem_free( channelList );
10033
10034 EXIT();
10035
10036 return status;
10037}
10038
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010039int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
10040#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10041 struct net_device *dev,
10042#endif
10043 struct cfg80211_scan_request *request)
10044{
10045 int ret;
10046
10047 vos_ssr_protect(__func__);
10048 ret = __wlan_hdd_cfg80211_scan(wiphy,
10049#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10050 dev,
10051#endif
10052 request);
10053 vos_ssr_unprotect(__func__);
10054
10055 return ret;
10056}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010057
10058void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
10059{
10060 v_U8_t iniDot11Mode =
10061 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
10062 eHddDot11Mode hddDot11Mode = iniDot11Mode;
10063
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010064 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
10065 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010066 switch ( iniDot11Mode )
10067 {
10068 case eHDD_DOT11_MODE_AUTO:
10069 case eHDD_DOT11_MODE_11ac:
10070 case eHDD_DOT11_MODE_11ac_ONLY:
10071#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053010072 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
10073 sme_IsFeatureSupportedByFW(DOT11AC) )
10074 hddDot11Mode = eHDD_DOT11_MODE_11ac;
10075 else
10076 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010077#else
10078 hddDot11Mode = eHDD_DOT11_MODE_11n;
10079#endif
10080 break;
10081 case eHDD_DOT11_MODE_11n:
10082 case eHDD_DOT11_MODE_11n_ONLY:
10083 hddDot11Mode = eHDD_DOT11_MODE_11n;
10084 break;
10085 default:
10086 hddDot11Mode = iniDot11Mode;
10087 break;
10088 }
10089 /* This call decides required channel bonding mode */
10090 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
10091 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
10092 operationChannel);
10093}
10094
Jeff Johnson295189b2012-06-20 16:38:30 -070010095/*
10096 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010097 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010098 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010099int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010100 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010101{
10102 int status = 0;
10103 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080010104 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010105 v_U32_t roamId;
10106 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070010107 eCsrAuthType RSNAuthType;
10108
10109 ENTER();
10110
10111 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080010112 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10113
10114 status = wlan_hdd_validate_context(pHddCtx);
10115 if (status)
10116 {
10117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10118 "%s: HDD context is not valid!", __func__);
10119 return status;
10120 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010121
Jeff Johnson295189b2012-06-20 16:38:30 -070010122 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
10123 {
10124 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
10125 return -EINVAL;
10126 }
10127
10128 pRoamProfile = &pWextState->roamProfile;
10129
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010130 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070010131 {
Jeff Johnsone7245742012-09-05 17:12:55 -070010132 hdd_station_ctx_t *pHddStaCtx;
10133 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010134
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010135 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070010136 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
10137 {
10138 /*QoS not enabled in cfg file*/
10139 pRoamProfile->uapsd_mask = 0;
10140 }
10141 else
10142 {
10143 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010144 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070010145 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
10146 }
10147
10148 pRoamProfile->SSIDs.numOfSSIDs = 1;
10149 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
10150 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010151 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070010152 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
10153 ssid, ssid_len);
10154
10155 if (bssid)
10156 {
10157 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
10158 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
10159 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010160 /* Save BSSID in seperate variable as well, as RoamProfile
10161 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070010162 case of join failure we should send valid BSSID to supplicant
10163 */
10164 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
10165 WNI_CFG_BSSID_LEN);
10166 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070010167 else
10168 {
10169 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
10170 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010171
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010172 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
10173 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010174 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
10175 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010176 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010177 /*set gen ie*/
10178 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
10179 /*set auth*/
10180 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
10181 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010182#ifdef FEATURE_WLAN_WAPI
10183 if (pAdapter->wapi_info.nWapiMode)
10184 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010185 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010186 switch (pAdapter->wapi_info.wapiAuthMode)
10187 {
10188 case WAPI_AUTH_MODE_PSK:
10189 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010190 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010191 pAdapter->wapi_info.wapiAuthMode);
10192 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
10193 break;
10194 }
10195 case WAPI_AUTH_MODE_CERT:
10196 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010197 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010198 pAdapter->wapi_info.wapiAuthMode);
10199 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
10200 break;
10201 }
10202 } // End of switch
10203 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
10204 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
10205 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010206 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010207 pRoamProfile->AuthType.numEntries = 1;
10208 pRoamProfile->EncryptionType.numEntries = 1;
10209 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10210 pRoamProfile->mcEncryptionType.numEntries = 1;
10211 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10212 }
10213 }
10214#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010215#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010216 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010217 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10218 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
10219 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010220 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
10221 sizeof (tSirGtkOffloadParams));
10222 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010223 }
10224#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010225 pRoamProfile->csrPersona = pAdapter->device_mode;
10226
Jeff Johnson32d95a32012-09-10 13:15:23 -070010227 if( operatingChannel )
10228 {
10229 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
10230 pRoamProfile->ChannelInfo.numOfChannels = 1;
10231 }
Chet Lanctot186b5732013-03-18 10:26:30 -070010232 else
10233 {
10234 pRoamProfile->ChannelInfo.ChannelList = NULL;
10235 pRoamProfile->ChannelInfo.numOfChannels = 0;
10236 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010237 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
10238 {
10239 hdd_select_cbmode(pAdapter,operatingChannel);
10240 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010241
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010242 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
10243 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010244 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010245 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010246 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
10247 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010248 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10249 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053010250 {
10251 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10252 "%s: Set HDD connState to eConnectionState_Connecting",
10253 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010254 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
10255 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053010256 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010257 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010258 pAdapter->sessionId, pRoamProfile, &roamId);
10259
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010260 if ((eHAL_STATUS_SUCCESS != status) &&
10261 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10262 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010263
10264 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010265 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
10266 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
10267 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010268 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010269 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010270 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010271
10272 pRoamProfile->ChannelInfo.ChannelList = NULL;
10273 pRoamProfile->ChannelInfo.numOfChannels = 0;
10274
Jeff Johnson295189b2012-06-20 16:38:30 -070010275 }
10276 else
10277 {
10278 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
10279 return -EINVAL;
10280 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010281 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010282 return status;
10283}
10284
10285/*
10286 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
10287 * This function is used to set the authentication type (OPEN/SHARED).
10288 *
10289 */
10290static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
10291 enum nl80211_auth_type auth_type)
10292{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010293 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010294 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10295
10296 ENTER();
10297
10298 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010299 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070010300 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010301 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010302 hddLog(VOS_TRACE_LEVEL_INFO,
10303 "%s: set authentication type to AUTOSWITCH", __func__);
10304 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
10305 break;
10306
10307 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010308#ifdef WLAN_FEATURE_VOWIFI_11R
10309 case NL80211_AUTHTYPE_FT:
10310#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010311 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010312 "%s: set authentication type to OPEN", __func__);
10313 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
10314 break;
10315
10316 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010317 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010318 "%s: set authentication type to SHARED", __func__);
10319 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
10320 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010321#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010322 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010323 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010324 "%s: set authentication type to CCKM WPA", __func__);
10325 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
10326 break;
10327#endif
10328
10329
10330 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010331 hddLog(VOS_TRACE_LEVEL_ERROR,
10332 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010333 auth_type);
10334 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
10335 return -EINVAL;
10336 }
10337
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010338 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010339 pHddStaCtx->conn_info.authType;
10340 return 0;
10341}
10342
10343/*
10344 * FUNCTION: wlan_hdd_set_akm_suite
10345 * This function is used to set the key mgmt type(PSK/8021x).
10346 *
10347 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010348static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010349 u32 key_mgmt
10350 )
10351{
10352 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10353 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053010354 /* Should be in ieee802_11_defs.h */
10355#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
10356#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070010357 /*set key mgmt type*/
10358 switch(key_mgmt)
10359 {
10360 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053010361 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010362#ifdef WLAN_FEATURE_VOWIFI_11R
10363 case WLAN_AKM_SUITE_FT_PSK:
10364#endif
10365 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070010366 __func__);
10367 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
10368 break;
10369
10370 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053010371 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010372#ifdef WLAN_FEATURE_VOWIFI_11R
10373 case WLAN_AKM_SUITE_FT_8021X:
10374#endif
10375 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070010376 __func__);
10377 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10378 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010379#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010380#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
10381#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
10382 case WLAN_AKM_SUITE_CCKM:
10383 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
10384 __func__);
10385 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
10386 break;
10387#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070010388#ifndef WLAN_AKM_SUITE_OSEN
10389#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
10390 case WLAN_AKM_SUITE_OSEN:
10391 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
10392 __func__);
10393 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10394 break;
10395#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010396
10397 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010398 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010399 __func__, key_mgmt);
10400 return -EINVAL;
10401
10402 }
10403 return 0;
10404}
10405
10406/*
10407 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010408 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070010409 * (NONE/WEP40/WEP104/TKIP/CCMP).
10410 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010411static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
10412 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070010413 bool ucast
10414 )
10415{
10416 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010417 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010418 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10419
10420 ENTER();
10421
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010422 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010423 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010424 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070010425 __func__, cipher);
10426 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10427 }
10428 else
10429 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010430
Jeff Johnson295189b2012-06-20 16:38:30 -070010431 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010432 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010433 {
10434 case IW_AUTH_CIPHER_NONE:
10435 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10436 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010437
Jeff Johnson295189b2012-06-20 16:38:30 -070010438 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010439 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070010440 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010441
Jeff Johnson295189b2012-06-20 16:38:30 -070010442 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010443 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070010444 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010445
Jeff Johnson295189b2012-06-20 16:38:30 -070010446 case WLAN_CIPHER_SUITE_TKIP:
10447 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
10448 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010449
Jeff Johnson295189b2012-06-20 16:38:30 -070010450 case WLAN_CIPHER_SUITE_CCMP:
10451 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10452 break;
10453#ifdef FEATURE_WLAN_WAPI
10454 case WLAN_CIPHER_SUITE_SMS4:
10455 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
10456 break;
10457#endif
10458
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010459#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010460 case WLAN_CIPHER_SUITE_KRK:
10461 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
10462 break;
10463#endif
10464 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010465 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010466 __func__, cipher);
10467 return -EOPNOTSUPP;
10468 }
10469 }
10470
10471 if (ucast)
10472 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010473 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010474 __func__, encryptionType);
10475 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10476 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010477 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010478 encryptionType;
10479 }
10480 else
10481 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010482 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010483 __func__, encryptionType);
10484 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
10485 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
10486 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
10487 }
10488
10489 return 0;
10490}
10491
10492
10493/*
10494 * FUNCTION: wlan_hdd_cfg80211_set_ie
10495 * This function is used to parse WPA/RSN IE's.
10496 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010497int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
10498 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070010499 size_t ie_len
10500 )
10501{
10502 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10503 u8 *genie = ie;
10504 v_U16_t remLen = ie_len;
10505#ifdef FEATURE_WLAN_WAPI
10506 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
10507 u16 *tmp;
10508 v_U16_t akmsuiteCount;
10509 int *akmlist;
10510#endif
10511 ENTER();
10512
10513 /* clear previous assocAddIE */
10514 pWextState->assocAddIE.length = 0;
10515 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010516 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010517
10518 while (remLen >= 2)
10519 {
10520 v_U16_t eLen = 0;
10521 v_U8_t elementId;
10522 elementId = *genie++;
10523 eLen = *genie++;
10524 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010525
Arif Hussain6d2a3322013-11-17 19:50:10 -080010526 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070010527 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010528
10529 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070010530 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010531 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010532 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 -070010533 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010534 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010535 "%s: Invalid WPA IE", __func__);
10536 return -EINVAL;
10537 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010538 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070010539 {
10540 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010541 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010542 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010543
Jeff Johnson295189b2012-06-20 16:38:30 -070010544 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10545 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010546 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
10547 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010548 VOS_ASSERT(0);
10549 return -ENOMEM;
10550 }
10551 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10552 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10553 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010554
Jeff Johnson295189b2012-06-20 16:38:30 -070010555 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
10556 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10557 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10558 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010559 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
10560 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010561 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
10562 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10563 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
10564 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
10565 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
10566 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010567 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053010568 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010569 {
10570 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010571 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010572 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010573
Jeff Johnson295189b2012-06-20 16:38:30 -070010574 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10575 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010576 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10577 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010578 VOS_ASSERT(0);
10579 return -ENOMEM;
10580 }
10581 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10582 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10583 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010584
Jeff Johnson295189b2012-06-20 16:38:30 -070010585 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10586 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10587 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010588#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010589 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
10590 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010591 /*Consider WFD IE, only for P2P Client */
10592 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10593 {
10594 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010595 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010596 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010597
Jeff Johnson295189b2012-06-20 16:38:30 -070010598 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10599 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010600 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10601 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010602 VOS_ASSERT(0);
10603 return -ENOMEM;
10604 }
10605 // WFD IE is saved to Additional IE ; it should be accumulated to handle
10606 // WPS IE + P2P IE + WFD IE
10607 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10608 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010609
Jeff Johnson295189b2012-06-20 16:38:30 -070010610 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10611 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10612 }
10613#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010614 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010615 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010616 HS20_OUI_TYPE_SIZE)) )
10617 {
10618 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010619 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010620 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010621
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010622 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10623 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010624 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10625 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010626 VOS_ASSERT(0);
10627 return -ENOMEM;
10628 }
10629 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10630 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010631
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010632 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10633 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10634 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010635 /* Appending OSEN Information Element in Assiciation Request */
10636 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
10637 OSEN_OUI_TYPE_SIZE)) )
10638 {
10639 v_U16_t curAddIELen = pWextState->assocAddIE.length;
10640 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
10641 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010642
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010643 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10644 {
10645 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10646 "Need bigger buffer space");
10647 VOS_ASSERT(0);
10648 return -ENOMEM;
10649 }
10650 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10651 pWextState->assocAddIE.length += eLen + 2;
10652
10653 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
10654 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10655 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10656 }
10657
10658 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070010659 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
10660
10661 /* populating as ADDIE in beacon frames */
10662 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10663 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
10664 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
10665 {
10666 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10667 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10668 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10669 {
10670 hddLog(LOGE,
10671 "Coldn't pass "
10672 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
10673 }
10674 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
10675 else
10676 hddLog(LOGE,
10677 "Could not pass on "
10678 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
10679
10680 /* IBSS mode doesn't contain params->proberesp_ies still
10681 beaconIE's need to be populated in probe response frames */
10682 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
10683 {
10684 u16 rem_probe_resp_ie_len = eLen + 2;
10685 u8 probe_rsp_ie_len[3] = {0};
10686 u8 counter = 0;
10687
10688 /* Check Probe Resp Length if it is greater then 255 then
10689 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
10690 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
10691 not able Store More then 255 bytes into One Variable */
10692
10693 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
10694 {
10695 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
10696 {
10697 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
10698 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
10699 }
10700 else
10701 {
10702 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
10703 rem_probe_resp_ie_len = 0;
10704 }
10705 }
10706
10707 rem_probe_resp_ie_len = 0;
10708
10709 if (probe_rsp_ie_len[0] > 0)
10710 {
10711 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10712 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
10713 (tANI_U8*)(genie - 2),
10714 probe_rsp_ie_len[0], NULL,
10715 eANI_BOOLEAN_FALSE)
10716 == eHAL_STATUS_FAILURE)
10717 {
10718 hddLog(LOGE,
10719 "Could not pass"
10720 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
10721 }
10722 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10723 }
10724
10725 if (probe_rsp_ie_len[1] > 0)
10726 {
10727 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10728 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
10729 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10730 probe_rsp_ie_len[1], NULL,
10731 eANI_BOOLEAN_FALSE)
10732 == eHAL_STATUS_FAILURE)
10733 {
10734 hddLog(LOGE,
10735 "Could not pass"
10736 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
10737 }
10738 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10739 }
10740
10741 if (probe_rsp_ie_len[2] > 0)
10742 {
10743 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10744 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
10745 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10746 probe_rsp_ie_len[2], NULL,
10747 eANI_BOOLEAN_FALSE)
10748 == eHAL_STATUS_FAILURE)
10749 {
10750 hddLog(LOGE,
10751 "Could not pass"
10752 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
10753 }
10754 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10755 }
10756
10757 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10758 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10759 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10760 {
10761 hddLog(LOGE,
10762 "Could not pass"
10763 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
10764 }
10765 }
10766 else
10767 {
10768 // Reset WNI_CFG_PROBE_RSP Flags
10769 wlan_hdd_reset_prob_rspies(pAdapter);
10770
10771 hddLog(VOS_TRACE_LEVEL_INFO,
10772 "%s: No Probe Response IE received in set beacon",
10773 __func__);
10774 }
10775 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010776 break;
10777 case DOT11F_EID_RSN:
10778 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
10779 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10780 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
10781 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
10782 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
10783 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010784 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
10785 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010786 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010787 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010788 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010789 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010790
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010791 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10792 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010793 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10794 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010795 VOS_ASSERT(0);
10796 return -ENOMEM;
10797 }
10798 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10799 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010800
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010801 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10802 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10803 break;
10804 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010805#ifdef FEATURE_WLAN_WAPI
10806 case WLAN_EID_WAPI:
10807 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010808 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070010809 pAdapter->wapi_info.nWapiMode);
10810 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010811 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070010812 akmsuiteCount = WPA_GET_LE16(tmp);
10813 tmp = tmp + 1;
10814 akmlist = (int *)(tmp);
10815 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
10816 {
10817 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
10818 }
10819 else
10820 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010821 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070010822 VOS_ASSERT(0);
10823 return -EINVAL;
10824 }
10825
10826 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
10827 {
10828 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010829 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010830 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010831 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010832 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010833 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010834 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010835 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010836 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
10837 }
10838 break;
10839#endif
10840 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010841 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010842 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010843 /* when Unknown IE is received we should break and continue
10844 * to the next IE in the buffer instead we were returning
10845 * so changing this to break */
10846 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010847 }
10848 genie += eLen;
10849 remLen -= eLen;
10850 }
10851 EXIT();
10852 return 0;
10853}
10854
10855/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053010856 * FUNCTION: hdd_isWPAIEPresent
10857 * Parse the received IE to find the WPA IE
10858 *
10859 */
10860static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
10861{
10862 v_U8_t eLen = 0;
10863 v_U16_t remLen = ie_len;
10864 v_U8_t elementId = 0;
10865
10866 while (remLen >= 2)
10867 {
10868 elementId = *ie++;
10869 eLen = *ie++;
10870 remLen -= 2;
10871 if (eLen > remLen)
10872 {
10873 hddLog(VOS_TRACE_LEVEL_ERROR,
10874 "%s: IE length is wrong %d", __func__, eLen);
10875 return FALSE;
10876 }
10877 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
10878 {
10879 /* OUI - 0x00 0X50 0XF2
10880 WPA Information Element - 0x01
10881 WPA version - 0x01*/
10882 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
10883 return TRUE;
10884 }
10885 ie += eLen;
10886 remLen -= eLen;
10887 }
10888 return FALSE;
10889}
10890
10891/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010892 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010893 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010894 * parameters during connect operation.
10895 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010896int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010897 struct cfg80211_connect_params *req
10898 )
10899{
10900 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010901 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010902 ENTER();
10903
10904 /*set wpa version*/
10905 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
10906
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010907 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070010908 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053010909 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070010910 {
10911 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
10912 }
10913 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
10914 {
10915 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
10916 }
10917 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010918
10919 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010920 pWextState->wpaVersion);
10921
10922 /*set authentication type*/
10923 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
10924
10925 if (0 > status)
10926 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010927 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010928 "%s: failed to set authentication type ", __func__);
10929 return status;
10930 }
10931
10932 /*set key mgmt type*/
10933 if (req->crypto.n_akm_suites)
10934 {
10935 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
10936 if (0 > status)
10937 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010938 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070010939 __func__);
10940 return status;
10941 }
10942 }
10943
10944 /*set pairwise cipher type*/
10945 if (req->crypto.n_ciphers_pairwise)
10946 {
10947 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
10948 req->crypto.ciphers_pairwise[0], true);
10949 if (0 > status)
10950 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010951 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010952 "%s: failed to set unicast cipher type", __func__);
10953 return status;
10954 }
10955 }
10956 else
10957 {
10958 /*Reset previous cipher suite to none*/
10959 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
10960 if (0 > status)
10961 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010962 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010963 "%s: failed to set unicast cipher type", __func__);
10964 return status;
10965 }
10966 }
10967
10968 /*set group cipher type*/
10969 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
10970 false);
10971
10972 if (0 > status)
10973 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010974 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070010975 __func__);
10976 return status;
10977 }
10978
Chet Lanctot186b5732013-03-18 10:26:30 -070010979#ifdef WLAN_FEATURE_11W
10980 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
10981#endif
10982
Jeff Johnson295189b2012-06-20 16:38:30 -070010983 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
10984 if (req->ie_len)
10985 {
10986 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
10987 if ( 0 > status)
10988 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010989 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010990 __func__);
10991 return status;
10992 }
10993 }
10994
10995 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010996 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010997 {
10998 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
10999 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
11000 )
11001 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011002 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070011003 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
11004 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011005 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011006 __func__);
11007 return -EOPNOTSUPP;
11008 }
11009 else
11010 {
11011 u8 key_len = req->key_len;
11012 u8 key_idx = req->key_idx;
11013
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011014 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011015 && (CSR_MAX_NUM_KEY > key_idx)
11016 )
11017 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011018 hddLog(VOS_TRACE_LEVEL_INFO,
11019 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011020 __func__, key_idx, key_len);
11021 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011022 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011023 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011024 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011025 (u8)key_len;
11026 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
11027 }
11028 }
11029 }
11030 }
11031
11032 return status;
11033}
11034
11035/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011036 * FUNCTION: wlan_hdd_try_disconnect
11037 * This function is used to disconnect from previous
11038 * connection
11039 */
11040static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
11041{
11042 long ret = 0;
11043 hdd_station_ctx_t *pHddStaCtx;
11044 eMib_dot11DesiredBssType connectedBssType;
11045
11046 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11047
11048 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
11049
11050 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
11051 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
11052 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
11053 {
11054 /* Issue disconnect to CSR */
11055 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11056 if( eHAL_STATUS_SUCCESS ==
11057 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11058 pAdapter->sessionId,
11059 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11060 {
11061 ret = wait_for_completion_interruptible_timeout(
11062 &pAdapter->disconnect_comp_var,
11063 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11064 if (0 >= ret)
11065 {
11066 hddLog(LOGE, FL("Failed to receive disconnect event"));
11067 return -EALREADY;
11068 }
11069 }
11070 }
11071 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
11072 {
11073 ret = wait_for_completion_interruptible_timeout(
11074 &pAdapter->disconnect_comp_var,
11075 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11076 if (0 >= ret)
11077 {
11078 hddLog(LOGE, FL("Failed to receive disconnect event"));
11079 return -EALREADY;
11080 }
11081 }
11082
11083 return 0;
11084}
11085
11086/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053011087 * FUNCTION: __wlan_hdd_cfg80211_connect
11088 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011089 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011090static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011091 struct net_device *ndev,
11092 struct cfg80211_connect_params *req
11093 )
11094{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011095 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011096 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011097 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053011098 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011099
11100 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011101
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011102 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11103 TRACE_CODE_HDD_CFG80211_CONNECT,
11104 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011105 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011106 "%s: device_mode = %s (%d)", __func__,
11107 hdd_device_modetoString(pAdapter->device_mode),
11108 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011109
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011110 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011111 if (!pHddCtx)
11112 {
11113 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11114 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011115 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011116 }
11117
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011118 status = wlan_hdd_validate_context(pHddCtx);
11119
11120 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011121 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11123 "%s: HDD context is not valid", __func__);
11124 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011125 }
11126
Agarwal Ashish51325b52014-06-16 16:50:49 +053011127 if (vos_max_concurrent_connections_reached()) {
11128 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11129 return -ECONNREFUSED;
11130 }
11131
Jeff Johnson295189b2012-06-20 16:38:30 -070011132#ifdef WLAN_BTAMP_FEATURE
11133 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011134 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070011135 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011136 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011137 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011138 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070011139 }
11140#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011141
11142 //If Device Mode is Station Concurrent Sessions Exit BMps
11143 //P2P Mode will be taken care in Open/close adapter
11144 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011145 (vos_concurrent_open_sessions_running())) {
11146 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
11147 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011148 }
11149
11150 /*Try disconnecting if already in connected state*/
11151 status = wlan_hdd_try_disconnect(pAdapter);
11152 if ( 0 > status)
11153 {
11154 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11155 " connection"));
11156 return -EALREADY;
11157 }
11158
Jeff Johnson295189b2012-06-20 16:38:30 -070011159 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011160 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070011161
11162 if ( 0 > status)
11163 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011164 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070011165 __func__);
11166 return status;
11167 }
Mohit Khanna765234a2012-09-11 15:08:35 -070011168 if ( req->channel )
11169 {
11170 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
11171 req->ssid_len, req->bssid,
11172 req->channel->hw_value);
11173 }
11174 else
11175 {
11176 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011177 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070011178 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011179
11180 if (0 > status)
11181 {
11182 //ReEnable BMPS if disabled
11183 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
11184 (NULL != pHddCtx))
11185 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011186 if (pHddCtx->hdd_wlan_suspended)
11187 {
11188 hdd_set_pwrparams(pHddCtx);
11189 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011190 //ReEnable Bmps and Imps back
11191 hdd_enable_bmps_imps(pHddCtx);
11192 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011193 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011194 return status;
11195 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011196 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011197 EXIT();
11198 return status;
11199}
11200
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011201static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
11202 struct net_device *ndev,
11203 struct cfg80211_connect_params *req)
11204{
11205 int ret;
11206 vos_ssr_protect(__func__);
11207 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
11208 vos_ssr_unprotect(__func__);
11209
11210 return ret;
11211}
Jeff Johnson295189b2012-06-20 16:38:30 -070011212
11213/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011214 * FUNCTION: wlan_hdd_disconnect
11215 * This function is used to issue a disconnect request to SME
11216 */
11217int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
11218{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011219 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011220 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011221 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011222 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011223
11224 status = wlan_hdd_validate_context(pHddCtx);
11225
11226 if (0 != status)
11227 {
11228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11229 "%s: HDD context is not valid", __func__);
11230 return status;
11231 }
11232
11233 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011234
Agarwal Ashish47d18112014-08-04 19:55:07 +053011235 /* Need to apply spin lock before decreasing active sessions
11236 * as there can be chance for double decrement if context switch
11237 * Calls hdd_DisConnectHandler.
11238 */
11239
11240 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011241 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11242 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011243 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11244 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053011245 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
11246 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011247
Abhishek Singhf4669da2014-05-26 15:07:49 +053011248 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053011249 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
11250
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011251 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011252
Mihir Shete182a0b22014-08-18 16:08:48 +053011253 /*
11254 * stop tx queues before deleting STA/BSS context from the firmware.
11255 * tx has to be disabled because the firmware can get busy dropping
11256 * the tx frames after BSS/STA has been deleted and will not send
11257 * back a response resulting in WDI timeout
11258 */
11259 netif_tx_disable(pAdapter->dev);
11260 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011261
Mihir Shete182a0b22014-08-18 16:08:48 +053011262 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011263 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11264 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011265 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
11266 {
11267 hddLog(VOS_TRACE_LEVEL_INFO,
11268 FL("status = %d, already disconnected"),
11269 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011270
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011271 }
11272 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011273 {
11274 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011275 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011276 __func__, (int)status );
11277 return -EINVAL;
11278 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011279 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011280 &pAdapter->disconnect_comp_var,
11281 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011282 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011283 {
11284 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011285 "%s: Failed to disconnect, timed out", __func__);
11286 return -ETIMEDOUT;
11287 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011288 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011289 {
11290 hddLog(VOS_TRACE_LEVEL_ERROR,
11291 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011292 return ret;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011293 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11295 FL("Set HDD connState to eConnectionState_NotConnected"));
11296 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
11297
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011298 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011299}
11300
11301
11302/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011303 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070011304 * This function is used to issue a disconnect request to SME
11305 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011306static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011307 struct net_device *dev,
11308 u16 reason
11309 )
11310{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011311 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011312 tCsrRoamProfile *pRoamProfile =
11313 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011314 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011315 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11316 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011317#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011318 tANI_U8 staIdx;
11319#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011320
Jeff Johnson295189b2012-06-20 16:38:30 -070011321 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011322
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011323 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11324 TRACE_CODE_HDD_CFG80211_DISCONNECT,
11325 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011326 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
11327 __func__, hdd_device_modetoString(pAdapter->device_mode),
11328 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011329
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011330 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
11331 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070011332
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011333 status = wlan_hdd_validate_context(pHddCtx);
11334
11335 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011336 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11338 "%s: HDD context is not valid", __func__);
11339 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011340 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011341
Jeff Johnson295189b2012-06-20 16:38:30 -070011342 if (NULL != pRoamProfile)
11343 {
11344 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011345 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
11346 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070011347 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011348 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070011349 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011350 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070011351 switch(reason)
11352 {
11353 case WLAN_REASON_MIC_FAILURE:
11354 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
11355 break;
11356
11357 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
11358 case WLAN_REASON_DISASSOC_AP_BUSY:
11359 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
11360 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
11361 break;
11362
11363 case WLAN_REASON_PREV_AUTH_NOT_VALID:
11364 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053011365 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070011366 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
11367 break;
11368
Jeff Johnson295189b2012-06-20 16:38:30 -070011369 default:
11370 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
11371 break;
11372 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011373 pScanInfo = &pHddCtx->scan_info;
11374 if (pScanInfo->mScanPending)
11375 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011376 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011377 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011378 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011379 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011380 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011381
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011382#ifdef FEATURE_WLAN_TDLS
11383 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011384 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011385 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011386 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
11387 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011388 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011389 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011390 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011391 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011392 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011393 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011394 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011395 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011396 pAdapter->sessionId,
11397 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011398 }
11399 }
11400#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011401 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011402 status = wlan_hdd_disconnect(pAdapter, reasonCode);
11403 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070011404 {
11405 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011406 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011407 __func__, (int)status );
11408 return -EINVAL;
11409 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011410 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011411 else
11412 {
11413 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
11414 "called while in %d state", __func__,
11415 pHddStaCtx->conn_info.connState);
11416 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011417 }
11418 else
11419 {
11420 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
11421 }
11422
11423 return status;
11424}
11425
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011426static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
11427 struct net_device *dev,
11428 u16 reason
11429 )
11430{
11431 int ret;
11432 vos_ssr_protect(__func__);
11433 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
11434 vos_ssr_unprotect(__func__);
11435
11436 return ret;
11437}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011438
Jeff Johnson295189b2012-06-20 16:38:30 -070011439/*
11440 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011441 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011442 * settings in IBSS mode.
11443 */
11444static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011445 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011446 struct cfg80211_ibss_params *params
11447 )
11448{
11449 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011450 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011451 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11452 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011453
Jeff Johnson295189b2012-06-20 16:38:30 -070011454 ENTER();
11455
11456 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070011457 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070011458
11459 if (params->ie_len && ( NULL != params->ie) )
11460 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011461 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11462 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011463 {
11464 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11465 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11466 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011467 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011468 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011469 tDot11fIEWPA dot11WPAIE;
11470 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011471 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011472
Wilson Yang00256342013-10-10 23:13:38 -070011473 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011474 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11475 params->ie_len, DOT11F_EID_WPA);
11476 if ( NULL != ie )
11477 {
11478 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11479 // Unpack the WPA IE
11480 //Skip past the EID byte and length byte - and four byte WiFi OUI
11481 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
11482 &ie[2+4],
11483 ie[1] - 4,
11484 &dot11WPAIE);
11485 /*Extract the multicast cipher, the encType for unicast
11486 cipher for wpa-none is none*/
11487 encryptionType =
11488 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
11489 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011490 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011491
Jeff Johnson295189b2012-06-20 16:38:30 -070011492 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
11493
11494 if (0 > status)
11495 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011496 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011497 __func__);
11498 return status;
11499 }
11500 }
11501
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011502 pWextState->roamProfile.AuthType.authType[0] =
11503 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011504 eCSR_AUTH_TYPE_OPEN_SYSTEM;
11505
11506 if (params->privacy)
11507 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011508 /* Security enabled IBSS, At this time there is no information available
11509 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070011510 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011511 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070011512 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011513 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070011514 *enable privacy bit in beacons */
11515
11516 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11517 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011518 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
11519 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070011520 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11521 pWextState->roamProfile.EncryptionType.numEntries = 1;
11522 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070011523 return status;
11524}
11525
11526/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011527 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011528 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011529 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011530static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011531 struct net_device *dev,
11532 struct cfg80211_ibss_params *params
11533 )
11534{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011535 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011536 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11537 tCsrRoamProfile *pRoamProfile;
11538 int status;
krunal sonie9002db2013-11-25 14:24:17 -080011539 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011540 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11541 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011542
11543 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011544
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011545 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11546 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
11547 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011548 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011549 "%s: device_mode = %s (%d)", __func__,
11550 hdd_device_modetoString(pAdapter->device_mode),
11551 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011552
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011553 status = wlan_hdd_validate_context(pHddCtx);
11554
11555 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011556 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11558 "%s: HDD context is not valid", __func__);
11559 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011560 }
11561
11562 if (NULL == pWextState)
11563 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011564 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011565 __func__);
11566 return -EIO;
11567 }
11568
Agarwal Ashish51325b52014-06-16 16:50:49 +053011569 if (vos_max_concurrent_connections_reached()) {
11570 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11571 return -ECONNREFUSED;
11572 }
11573
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011574 /*Try disconnecting if already in connected state*/
11575 status = wlan_hdd_try_disconnect(pAdapter);
11576 if ( 0 > status)
11577 {
11578 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11579 " IBSS connection"));
11580 return -EALREADY;
11581 }
11582
Jeff Johnson295189b2012-06-20 16:38:30 -070011583 pRoamProfile = &pWextState->roamProfile;
11584
11585 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
11586 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011587 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011588 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011589 return -EINVAL;
11590 }
11591
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011592 /* BSSID is provided by upper layers hence no need to AUTO generate */
11593 if (NULL != params->bssid) {
11594 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11595 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
11596 hddLog (VOS_TRACE_LEVEL_ERROR,
11597 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11598 return -EIO;
11599 }
11600 }
krunal sonie9002db2013-11-25 14:24:17 -080011601 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
11602 {
11603 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11604 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
11605 {
11606 hddLog (VOS_TRACE_LEVEL_ERROR,
11607 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11608 return -EIO;
11609 }
11610 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
11611 if (!params->bssid)
11612 {
11613 hddLog (VOS_TRACE_LEVEL_ERROR,
11614 "%s:Failed memory allocation", __func__);
11615 return -EIO;
11616 }
11617 vos_mem_copy((v_U8_t *)params->bssid,
11618 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
11619 VOS_MAC_ADDR_SIZE);
11620 alloc_bssid = VOS_TRUE;
11621 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011622
Jeff Johnson295189b2012-06-20 16:38:30 -070011623 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070011624 if (NULL !=
11625#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11626 params->chandef.chan)
11627#else
11628 params->channel)
11629#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011630 {
11631 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011632 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
11633 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
11634 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
11635 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011636
11637 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011638 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070011639 ieee80211_frequency_to_channel(
11640#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11641 params->chandef.chan->center_freq);
11642#else
11643 params->channel->center_freq);
11644#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011645
11646 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
11647 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070011648 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011649 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
11650 __func__);
11651 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070011652 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011653
11654 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011655 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011656 if (channelNum == validChan[indx])
11657 {
11658 break;
11659 }
11660 }
11661 if (indx >= numChans)
11662 {
11663 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011664 __func__, channelNum);
11665 return -EINVAL;
11666 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011667 /* Set the Operational Channel */
11668 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
11669 channelNum);
11670 pRoamProfile->ChannelInfo.numOfChannels = 1;
11671 pHddStaCtx->conn_info.operationChannel = channelNum;
11672 pRoamProfile->ChannelInfo.ChannelList =
11673 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070011674 }
11675
11676 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011677 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070011678 if (status < 0)
11679 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011680 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070011681 __func__);
11682 return status;
11683 }
11684
11685 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011686 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011687 params->ssid_len, params->bssid,
11688 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011689
11690 if (0 > status)
11691 {
11692 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
11693 return status;
11694 }
11695
krunal sonie9002db2013-11-25 14:24:17 -080011696 if (NULL != params->bssid &&
11697 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
11698 alloc_bssid == VOS_TRUE)
11699 {
11700 vos_mem_free(params->bssid);
11701 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011702 return 0;
11703}
11704
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011705static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
11706 struct net_device *dev,
11707 struct cfg80211_ibss_params *params
11708 )
11709{
11710 int ret = 0;
11711
11712 vos_ssr_protect(__func__);
11713 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
11714 vos_ssr_unprotect(__func__);
11715
11716 return ret;
11717}
11718
Jeff Johnson295189b2012-06-20 16:38:30 -070011719/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011720 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011721 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011722 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011723static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011724 struct net_device *dev
11725 )
11726{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011727 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011728 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11729 tCsrRoamProfile *pRoamProfile;
11730 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011731 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011732
11733 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011734
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011735 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11736 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
11737 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011738 status = wlan_hdd_validate_context(pHddCtx);
11739
11740 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011741 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11743 "%s: HDD context is not valid", __func__);
11744 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011745 }
11746
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011747 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
11748 hdd_device_modetoString(pAdapter->device_mode),
11749 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011750 if (NULL == pWextState)
11751 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011752 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011753 __func__);
11754 return -EIO;
11755 }
11756
11757 pRoamProfile = &pWextState->roamProfile;
11758
11759 /* Issue disconnect only if interface type is set to IBSS */
11760 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
11761 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011762 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070011763 __func__);
11764 return -EINVAL;
11765 }
11766
11767 /* Issue Disconnect request */
11768 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11769 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
11770 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
11771
11772 return 0;
11773}
11774
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011775static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
11776 struct net_device *dev
11777 )
11778{
11779 int ret = 0;
11780
11781 vos_ssr_protect(__func__);
11782 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
11783 vos_ssr_unprotect(__func__);
11784
11785 return ret;
11786}
11787
Jeff Johnson295189b2012-06-20 16:38:30 -070011788/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011789 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070011790 * This function is used to set the phy parameters
11791 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
11792 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011793static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011794 u32 changed)
11795{
11796 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
11797 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011798 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011799
11800 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011801 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11802 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
11803 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011804 status = wlan_hdd_validate_context(pHddCtx);
11805
11806 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011807 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11809 "%s: HDD context is not valid", __func__);
11810 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011811 }
11812
Jeff Johnson295189b2012-06-20 16:38:30 -070011813 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
11814 {
11815 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
11816 WNI_CFG_RTS_THRESHOLD_STAMAX :
11817 wiphy->rts_threshold;
11818
11819 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011820 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070011821 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011822 hddLog(VOS_TRACE_LEVEL_ERROR,
11823 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011824 __func__, rts_threshold);
11825 return -EINVAL;
11826 }
11827
11828 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
11829 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011830 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011831 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011832 hddLog(VOS_TRACE_LEVEL_ERROR,
11833 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011834 __func__, rts_threshold);
11835 return -EIO;
11836 }
11837
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011838 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011839 rts_threshold);
11840 }
11841
11842 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
11843 {
11844 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
11845 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
11846 wiphy->frag_threshold;
11847
11848 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011849 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011850 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011851 hddLog(VOS_TRACE_LEVEL_ERROR,
11852 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011853 frag_threshold);
11854 return -EINVAL;
11855 }
11856
11857 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
11858 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011859 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011860 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011861 hddLog(VOS_TRACE_LEVEL_ERROR,
11862 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011863 __func__, frag_threshold);
11864 return -EIO;
11865 }
11866
11867 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
11868 frag_threshold);
11869 }
11870
11871 if ((changed & WIPHY_PARAM_RETRY_SHORT)
11872 || (changed & WIPHY_PARAM_RETRY_LONG))
11873 {
11874 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
11875 wiphy->retry_short :
11876 wiphy->retry_long;
11877
11878 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
11879 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
11880 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011881 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011882 __func__, retry_value);
11883 return -EINVAL;
11884 }
11885
11886 if (changed & WIPHY_PARAM_RETRY_SHORT)
11887 {
11888 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
11889 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011890 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011891 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011892 hddLog(VOS_TRACE_LEVEL_ERROR,
11893 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011894 __func__, retry_value);
11895 return -EIO;
11896 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011897 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011898 __func__, retry_value);
11899 }
11900 else if (changed & WIPHY_PARAM_RETRY_SHORT)
11901 {
11902 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
11903 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011904 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011905 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011906 hddLog(VOS_TRACE_LEVEL_ERROR,
11907 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011908 __func__, retry_value);
11909 return -EIO;
11910 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011911 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011912 __func__, retry_value);
11913 }
11914 }
11915
11916 return 0;
11917}
11918
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011919static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
11920 u32 changed)
11921{
11922 int ret;
11923
11924 vos_ssr_protect(__func__);
11925 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
11926 vos_ssr_unprotect(__func__);
11927
11928 return ret;
11929}
11930
Jeff Johnson295189b2012-06-20 16:38:30 -070011931/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011932 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070011933 * This function is used to set the txpower
11934 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011935static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070011936#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11937 struct wireless_dev *wdev,
11938#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011939#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011940 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070011941#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011942 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070011943#endif
11944 int dbm)
11945{
11946 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011947 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011948 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11949 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011950 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011951
11952 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011953 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11954 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
11955 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011956 status = wlan_hdd_validate_context(pHddCtx);
11957
11958 if (0 != status)
11959 {
11960 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11961 "%s: HDD context is not valid", __func__);
11962 return status;
11963 }
11964
11965 hHal = pHddCtx->hHal;
11966
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011967 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
11968 dbm, ccmCfgSetCallback,
11969 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011970 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011971 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011972 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
11973 return -EIO;
11974 }
11975
11976 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
11977 dbm);
11978
11979 switch(type)
11980 {
11981 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
11982 /* Fall through */
11983 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
11984 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
11985 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011986 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
11987 __func__);
11988 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011989 }
11990 break;
11991 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011992 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011993 __func__);
11994 return -EOPNOTSUPP;
11995 break;
11996 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011997 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
11998 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070011999 return -EIO;
12000 }
12001
12002 return 0;
12003}
12004
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012005static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
12006#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12007 struct wireless_dev *wdev,
12008#endif
12009#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12010 enum tx_power_setting type,
12011#else
12012 enum nl80211_tx_power_setting type,
12013#endif
12014 int dbm)
12015{
12016 int ret;
12017 vos_ssr_protect(__func__);
12018 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
12019#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12020 wdev,
12021#endif
12022#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12023 type,
12024#else
12025 type,
12026#endif
12027 dbm);
12028 vos_ssr_unprotect(__func__);
12029
12030 return ret;
12031}
12032
Jeff Johnson295189b2012-06-20 16:38:30 -070012033/*
12034 * FUNCTION: wlan_hdd_cfg80211_get_txpower
12035 * This function is used to read the txpower
12036 */
Yue Maf49ba872013-08-19 12:04:25 -070012037static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
12038#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12039 struct wireless_dev *wdev,
12040#endif
12041 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070012042{
12043
12044 hdd_adapter_t *pAdapter;
12045 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012046 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012047
Jeff Johnsone7245742012-09-05 17:12:55 -070012048 ENTER();
12049
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012050 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012051
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012052 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012053 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012054 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12055 "%s: HDD context is not valid", __func__);
12056 *dbm = 0;
12057 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012058 }
12059
Jeff Johnson295189b2012-06-20 16:38:30 -070012060 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
12061 if (NULL == pAdapter)
12062 {
12063 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
12064 return -ENOENT;
12065 }
12066
12067 wlan_hdd_get_classAstats(pAdapter);
12068 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
12069
Jeff Johnsone7245742012-09-05 17:12:55 -070012070 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012071 return 0;
12072}
12073
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012074static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070012075 u8* mac, struct station_info *sinfo)
12076{
12077 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12078 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12079 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053012080 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070012081
12082 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
12083 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012084
12085 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
12086 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
12087 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
12088 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
12089 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
12090 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
12091 tANI_U16 maxRate = 0;
12092 tANI_U16 myRate;
12093 tANI_U16 currentRate = 0;
12094 tANI_U8 maxSpeedMCS = 0;
12095 tANI_U8 maxMCSIdx = 0;
12096 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053012097 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012098 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012099 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012100
Leo Chang6f8870f2013-03-26 18:11:36 -070012101#ifdef WLAN_FEATURE_11AC
12102 tANI_U32 vht_mcs_map;
12103 eDataRate11ACMaxMcs vhtMaxMcs;
12104#endif /* WLAN_FEATURE_11AC */
12105
Jeff Johnsone7245742012-09-05 17:12:55 -070012106 ENTER();
12107
Jeff Johnson295189b2012-06-20 16:38:30 -070012108 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
12109 (0 == ssidlen))
12110 {
12111 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
12112 " Invalid ssidlen, %d", __func__, ssidlen);
12113 /*To keep GUI happy*/
12114 return 0;
12115 }
12116
Mukul Sharma811205f2014-07-09 21:07:30 +053012117 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
12118 {
12119 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12120 "%s: Roaming in progress, so unable to proceed this request", __func__);
12121 return 0;
12122 }
12123
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012124 status = wlan_hdd_validate_context(pHddCtx);
12125
12126 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012127 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12129 "%s: HDD context is not valid", __func__);
12130 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012131 }
12132
Jeff Johnson295189b2012-06-20 16:38:30 -070012133
Kiet Lam3b17fc82013-09-27 05:24:08 +053012134 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
12135 sinfo->filled |= STATION_INFO_SIGNAL;
12136
c_hpothu09f19542014-05-30 21:53:31 +053012137 wlan_hdd_get_station_stats(pAdapter);
12138 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
12139
12140 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053012141 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
12142 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053012143 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053012144 {
12145 rate_flags = pAdapter->maxRateFlags;
12146 }
c_hpothu44ff4e02014-05-08 00:13:57 +053012147
Jeff Johnson295189b2012-06-20 16:38:30 -070012148 //convert to the UI units of 100kbps
12149 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
12150
12151#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070012152 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 -070012153 sinfo->signal,
12154 pCfg->reportMaxLinkSpeed,
12155 myRate,
12156 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012157 (int) pCfg->linkSpeedRssiMid,
12158 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070012159 (int) rate_flags,
12160 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012161#endif //LINKSPEED_DEBUG_ENABLED
12162
12163 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
12164 {
12165 // we do not want to necessarily report the current speed
12166 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
12167 {
12168 // report the max possible speed
12169 rssidx = 0;
12170 }
12171 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
12172 {
12173 // report the max possible speed with RSSI scaling
12174 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
12175 {
12176 // report the max possible speed
12177 rssidx = 0;
12178 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012179 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070012180 {
12181 // report middle speed
12182 rssidx = 1;
12183 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012184 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
12185 {
12186 // report middle speed
12187 rssidx = 2;
12188 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012189 else
12190 {
12191 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012192 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070012193 }
12194 }
12195 else
12196 {
12197 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
12198 hddLog(VOS_TRACE_LEVEL_ERROR,
12199 "%s: Invalid value for reportMaxLinkSpeed: %u",
12200 __func__, pCfg->reportMaxLinkSpeed);
12201 rssidx = 0;
12202 }
12203
12204 maxRate = 0;
12205
12206 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012207 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
12208 OperationalRates, &ORLeng))
12209 {
12210 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12211 /*To keep GUI happy*/
12212 return 0;
12213 }
12214
Jeff Johnson295189b2012-06-20 16:38:30 -070012215 for (i = 0; i < ORLeng; i++)
12216 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012217 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012218 {
12219 /* Validate Rate Set */
12220 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
12221 {
12222 currentRate = supported_data_rate[j].supported_rate[rssidx];
12223 break;
12224 }
12225 }
12226 /* Update MAX rate */
12227 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12228 }
12229
12230 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012231 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
12232 ExtendedRates, &ERLeng))
12233 {
12234 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12235 /*To keep GUI happy*/
12236 return 0;
12237 }
12238
Jeff Johnson295189b2012-06-20 16:38:30 -070012239 for (i = 0; i < ERLeng; i++)
12240 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012241 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012242 {
12243 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
12244 {
12245 currentRate = supported_data_rate[j].supported_rate[rssidx];
12246 break;
12247 }
12248 }
12249 /* Update MAX rate */
12250 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12251 }
c_hpothu79aab322014-07-14 21:11:01 +053012252
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012253 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053012254 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012255 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053012256 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070012257 {
c_hpothu79aab322014-07-14 21:11:01 +053012258 if (rate_flags & eHAL_TX_RATE_VHT80)
12259 mode = 2;
12260 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
12261 mode = 1;
12262 else
12263 mode = 0;
12264
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012265 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
12266 MCSRates, &MCSLeng))
12267 {
12268 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12269 /*To keep GUI happy*/
12270 return 0;
12271 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012272 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070012273#ifdef WLAN_FEATURE_11AC
12274 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012275 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070012276 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012277 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012278 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070012279 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070012280 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012281 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070012282 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012283 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070012284 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012285 maxMCSIdx = 7;
12286 }
12287 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
12288 {
12289 maxMCSIdx = 8;
12290 }
12291 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
12292 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012293 //VHT20 is supporting 0~8
12294 if (rate_flags & eHAL_TX_RATE_VHT20)
12295 maxMCSIdx = 8;
12296 else
12297 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070012298 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012299
c_hpothu79aab322014-07-14 21:11:01 +053012300 if (0 != rssidx)/*check for scaled */
12301 {
12302 //get middle rate MCS index if rssi=1/2
12303 for (i=0; i <= maxMCSIdx; i++)
12304 {
12305 if (sinfo->signal <= rssiMcsTbl[mode][i])
12306 {
12307 maxMCSIdx = i;
12308 break;
12309 }
12310 }
12311 }
12312
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012313 if (rate_flags & eHAL_TX_RATE_VHT80)
12314 {
12315 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
12316 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
12317 }
12318 else if (rate_flags & eHAL_TX_RATE_VHT40)
12319 {
12320 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
12321 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
12322 }
12323 else if (rate_flags & eHAL_TX_RATE_VHT20)
12324 {
12325 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
12326 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
12327 }
12328
Leo Chang6f8870f2013-03-26 18:11:36 -070012329 maxSpeedMCS = 1;
12330 if (currentRate > maxRate)
12331 {
12332 maxRate = currentRate;
12333 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012334
Leo Chang6f8870f2013-03-26 18:11:36 -070012335 }
12336 else
12337#endif /* WLAN_FEATURE_11AC */
12338 {
12339 if (rate_flags & eHAL_TX_RATE_HT40)
12340 {
12341 rateFlag |= 1;
12342 }
12343 if (rate_flags & eHAL_TX_RATE_SGI)
12344 {
12345 rateFlag |= 2;
12346 }
12347
Girish Gowli01abcee2014-07-31 20:18:55 +053012348 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053012349 if (rssidx == 1 || rssidx == 2)
12350 {
12351 //get middle rate MCS index if rssi=1/2
12352 for (i=0; i <= 7; i++)
12353 {
12354 if (sinfo->signal <= rssiMcsTbl[mode][i])
12355 {
12356 temp = i+1;
12357 break;
12358 }
12359 }
12360 }
c_hpothu79aab322014-07-14 21:11:01 +053012361
12362 for (i = 0; i < MCSLeng; i++)
12363 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012364 for (j = 0; j < temp; j++)
12365 {
12366 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
12367 {
12368 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
12369 break;
12370 }
12371 }
12372 if ((j < temp) && (currentRate > maxRate))
12373 {
12374 maxRate = currentRate;
12375 maxSpeedMCS = 1;
12376 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
12377 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012378 }
12379 }
12380 }
12381
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012382 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
12383 {
12384 maxRate = myRate;
12385 maxSpeedMCS = 1;
12386 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12387 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012388 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053012389 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070012390 {
12391 maxRate = myRate;
12392 if (rate_flags & eHAL_TX_RATE_LEGACY)
12393 {
12394 maxSpeedMCS = 0;
12395 }
12396 else
12397 {
12398 maxSpeedMCS = 1;
12399 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12400 }
12401 }
12402
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012403 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070012404 {
12405 sinfo->txrate.legacy = maxRate;
12406#ifdef LINKSPEED_DEBUG_ENABLED
12407 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
12408#endif //LINKSPEED_DEBUG_ENABLED
12409 }
12410 else
12411 {
12412 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070012413#ifdef WLAN_FEATURE_11AC
12414 sinfo->txrate.nss = 1;
12415 if (rate_flags & eHAL_TX_RATE_VHT80)
12416 {
12417 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012418 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070012419 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012420 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070012421 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012422 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12423 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12424 }
12425 else if (rate_flags & eHAL_TX_RATE_VHT20)
12426 {
12427 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12428 }
12429#endif /* WLAN_FEATURE_11AC */
12430 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
12431 {
12432 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12433 if (rate_flags & eHAL_TX_RATE_HT40)
12434 {
12435 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12436 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012437 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012438 if (rate_flags & eHAL_TX_RATE_SGI)
12439 {
12440 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12441 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012442
Jeff Johnson295189b2012-06-20 16:38:30 -070012443#ifdef LINKSPEED_DEBUG_ENABLED
12444 pr_info("Reporting MCS rate %d flags %x\n",
12445 sinfo->txrate.mcs,
12446 sinfo->txrate.flags );
12447#endif //LINKSPEED_DEBUG_ENABLED
12448 }
12449 }
12450 else
12451 {
12452 // report current rate instead of max rate
12453
12454 if (rate_flags & eHAL_TX_RATE_LEGACY)
12455 {
12456 //provide to the UI in units of 100kbps
12457 sinfo->txrate.legacy = myRate;
12458#ifdef LINKSPEED_DEBUG_ENABLED
12459 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
12460#endif //LINKSPEED_DEBUG_ENABLED
12461 }
12462 else
12463 {
12464 //must be MCS
12465 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070012466#ifdef WLAN_FEATURE_11AC
12467 sinfo->txrate.nss = 1;
12468 if (rate_flags & eHAL_TX_RATE_VHT80)
12469 {
12470 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12471 }
12472 else
12473#endif /* WLAN_FEATURE_11AC */
12474 {
12475 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12476 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012477 if (rate_flags & eHAL_TX_RATE_SGI)
12478 {
12479 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12480 }
12481 if (rate_flags & eHAL_TX_RATE_HT40)
12482 {
12483 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12484 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012485#ifdef WLAN_FEATURE_11AC
12486 else if (rate_flags & eHAL_TX_RATE_VHT80)
12487 {
12488 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
12489 }
12490#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070012491#ifdef LINKSPEED_DEBUG_ENABLED
12492 pr_info("Reporting actual MCS rate %d flags %x\n",
12493 sinfo->txrate.mcs,
12494 sinfo->txrate.flags );
12495#endif //LINKSPEED_DEBUG_ENABLED
12496 }
12497 }
12498 sinfo->filled |= STATION_INFO_TX_BITRATE;
12499
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012500 sinfo->tx_packets =
12501 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
12502 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
12503 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
12504 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
12505
12506 sinfo->tx_retries =
12507 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
12508 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
12509 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
12510 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
12511
12512 sinfo->tx_failed =
12513 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
12514 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
12515 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
12516 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
12517
12518 sinfo->filled |=
12519 STATION_INFO_TX_PACKETS |
12520 STATION_INFO_TX_RETRIES |
12521 STATION_INFO_TX_FAILED;
12522
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012523 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12524 TRACE_CODE_HDD_CFG80211_GET_STA,
12525 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012526 EXIT();
12527 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012528}
12529
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012530static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
12531 u8* mac, struct station_info *sinfo)
12532{
12533 int ret;
12534
12535 vos_ssr_protect(__func__);
12536 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
12537 vos_ssr_unprotect(__func__);
12538
12539 return ret;
12540}
12541
12542static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070012543 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070012544{
12545 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012546 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012547 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012548 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012549
Jeff Johnsone7245742012-09-05 17:12:55 -070012550 ENTER();
12551
Jeff Johnson295189b2012-06-20 16:38:30 -070012552 if (NULL == pAdapter)
12553 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012554 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012555 return -ENODEV;
12556 }
12557
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012558 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12559 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
12560 pAdapter->sessionId, timeout));
12561
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012562 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012563 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012564
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012565 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012566 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12568 "%s: HDD context is not valid", __func__);
12569 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012570 }
12571
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012572 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
12573 (TRUE == pHddCtx->hdd_wlan_suspended) &&
12574 (pHddCtx->cfg_ini->fhostArpOffload) &&
12575 (eConnectionState_Associated ==
12576 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12577 {
Amar Singhald53568e2013-09-26 11:03:45 -070012578
12579 hddLog(VOS_TRACE_LEVEL_INFO,
12580 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053012581 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012582 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12583 {
12584 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012585 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012586 __func__, vos_status);
12587 }
12588 }
12589
Jeff Johnson295189b2012-06-20 16:38:30 -070012590 /**The get power cmd from the supplicant gets updated by the nl only
12591 *on successful execution of the function call
12592 *we are oppositely mapped w.r.t mode in the driver
12593 **/
12594 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
12595
Jeff Johnsone7245742012-09-05 17:12:55 -070012596 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012597 if (VOS_STATUS_E_FAILURE == vos_status)
12598 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12600 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012601 return -EINVAL;
12602 }
12603 return 0;
12604}
12605
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012606static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
12607 struct net_device *dev, bool mode, int timeout)
12608{
12609 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012610
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012611 vos_ssr_protect(__func__);
12612 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
12613 vos_ssr_unprotect(__func__);
12614
12615 return ret;
12616}
Jeff Johnson295189b2012-06-20 16:38:30 -070012617#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12618static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
12619 struct net_device *netdev,
12620 u8 key_index)
12621{
Jeff Johnsone7245742012-09-05 17:12:55 -070012622 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012623 return 0;
12624}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012625#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070012626
12627#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
12628static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12629 struct net_device *dev,
12630 struct ieee80211_txq_params *params)
12631{
Jeff Johnsone7245742012-09-05 17:12:55 -070012632 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012633 return 0;
12634}
12635#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12636static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12637 struct ieee80211_txq_params *params)
12638{
Jeff Johnsone7245742012-09-05 17:12:55 -070012639 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012640 return 0;
12641}
12642#endif //LINUX_VERSION_CODE
12643
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012644#ifdef CFG80211_DEL_STA_V2
12645static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
12646 struct net_device *dev,
12647 struct station_del_parameters *param)
12648#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012649static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012650 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012651#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012652{
12653 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012654 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012655 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012656 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012657 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -070012658
Jeff Johnsone7245742012-09-05 17:12:55 -070012659 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012660
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012661 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070012662 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012663 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012664 return -EINVAL;
12665 }
12666
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012667 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12668 TRACE_CODE_HDD_CFG80211_DEL_STA,
12669 pAdapter->sessionId, pAdapter->device_mode));
12670
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012671 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12672 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012673
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012674 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012675 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12677 "%s: HDD context is not valid", __func__);
12678 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012679 }
12680
Jeff Johnson295189b2012-06-20 16:38:30 -070012681 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012682 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012683 )
12684 {
12685 if( NULL == mac )
12686 {
12687 v_U16_t i;
12688 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
12689 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012690 if ((pAdapter->aStaInfo[i].isUsed) &&
12691 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070012692 {
12693 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
12694 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012695 "%s: Delete STA with MAC::"
12696 MAC_ADDRESS_STR,
12697 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012698 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
12699 if (VOS_IS_STATUS_SUCCESS(vos_status))
12700 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012701 }
12702 }
12703 }
12704 else
12705 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012706
12707 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
12708 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12709 {
12710 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012711 "%s: Skip this DEL STA as this is not used::"
12712 MAC_ADDRESS_STR,
12713 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012714 return -ENOENT;
12715 }
12716
12717 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
12718 {
12719 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012720 "%s: Skip this DEL STA as deauth is in progress::"
12721 MAC_ADDRESS_STR,
12722 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012723 return -ENOENT;
12724 }
12725
12726 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
12727
Jeff Johnson295189b2012-06-20 16:38:30 -070012728 hddLog(VOS_TRACE_LEVEL_INFO,
12729 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080012730 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012731 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080012732 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012733
12734 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
12735 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12736 {
12737 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
12738 hddLog(VOS_TRACE_LEVEL_INFO,
12739 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080012740 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012741 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080012742 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012743 return -ENOENT;
12744 }
12745
Jeff Johnson295189b2012-06-20 16:38:30 -070012746 }
12747 }
12748
12749 EXIT();
12750
12751 return 0;
12752}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012753
12754#ifdef CFG80211_DEL_STA_V2
12755static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
12756 struct net_device *dev,
12757 struct station_del_parameters *param)
12758#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012759static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
12760 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012761#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012762{
12763 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012764
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012765 vos_ssr_protect(__func__);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012766#ifdef CFG80211_DEL_STA_V2
12767 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, param);
12768#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012769 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, mac);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053012770#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012771 vos_ssr_unprotect(__func__);
12772
12773 return ret;
12774}
12775
12776static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012777 struct net_device *dev, u8 *mac, struct station_parameters *params)
12778{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012779 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012780 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012781#ifdef FEATURE_WLAN_TDLS
12782 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012783 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012784
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012785 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12786 TRACE_CODE_HDD_CFG80211_ADD_STA,
12787 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012788 mask = params->sta_flags_mask;
12789
12790 set = params->sta_flags_set;
12791
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012792#ifdef WLAN_FEATURE_TDLS_DEBUG
12793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12794 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
12795 __func__, mask, set, MAC_ADDR_ARRAY(mac));
12796#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012797
12798 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12799 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012800 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012801 }
12802 }
12803#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012804 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012805}
12806
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012807static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
12808 struct net_device *dev, u8 *mac, struct station_parameters *params)
12809{
12810 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012811
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012812 vos_ssr_protect(__func__);
12813 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
12814 vos_ssr_unprotect(__func__);
12815
12816 return ret;
12817}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012818#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070012819
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012820static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070012821 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012822{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012823 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12824 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012825 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012826 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012827 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012828 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070012829
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012830 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012831 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012832 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012833 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012834 return -EINVAL;
12835 }
12836
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012837 if (!pmksa) {
12838 hddLog(LOGE, FL("pmksa is NULL"));
12839 return -EINVAL;
12840 }
12841
12842 if (!pmksa->bssid || !pmksa->pmkid) {
12843 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
12844 pmksa->bssid, pmksa->pmkid);
12845 return -EINVAL;
12846 }
12847
12848 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
12849 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
12850
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012851 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12852 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012853
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012854 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012855 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12857 "%s: HDD context is not valid", __func__);
12858 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012859 }
12860
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012861 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012862 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
12863
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012864 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
12865 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012866
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012867 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012868 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012869 &pmk_id, 1, FALSE);
12870
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012871 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12872 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
12873 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012874
12875 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012876}
12877
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012878static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
12879 struct cfg80211_pmksa *pmksa)
12880{
12881 int ret;
12882
12883 vos_ssr_protect(__func__);
12884 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
12885 vos_ssr_unprotect(__func__);
12886
12887 return ret;
12888}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012889
Wilson Yang6507c4e2013-10-01 20:11:19 -070012890
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012891static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070012892 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012893{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012894 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12895 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012896 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080012897 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012898
Wilson Yang6507c4e2013-10-01 20:11:19 -070012899 /* Validate pAdapter */
12900 if (NULL == pAdapter)
12901 {
12902 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
12903 return -EINVAL;
12904 }
12905
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012906 if (!pmksa) {
12907 hddLog(LOGE, FL("pmksa is NULL"));
12908 return -EINVAL;
12909 }
12910
12911 if (!pmksa->bssid) {
12912 hddLog(LOGE, FL("pmksa->bssid is NULL"));
12913 return -EINVAL;
12914 }
12915
Kiet Lam98c46a12014-10-31 15:34:57 -070012916 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
12917 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
12918
Wilson Yang6507c4e2013-10-01 20:11:19 -070012919 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12920 status = wlan_hdd_validate_context(pHddCtx);
12921
12922 if (0 != status)
12923 {
12924 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12925 "%s: HDD context is not valid", __func__);
12926 return status;
12927 }
12928
12929 /*Retrieve halHandle*/
12930 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
12931
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012932 /* Delete the PMKID CSR cache */
12933 if (eHAL_STATUS_SUCCESS !=
12934 sme_RoamDelPMKIDfromCache(halHandle,
12935 pAdapter->sessionId, pmksa->bssid, FALSE)) {
12936 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
12937 MAC_ADDR_ARRAY(pmksa->bssid));
12938 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012939 }
12940
Wilson Yangef657d32014-01-15 19:19:23 -080012941 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012942}
12943
Wilson Yang6507c4e2013-10-01 20:11:19 -070012944
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012945static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
12946 struct cfg80211_pmksa *pmksa)
12947{
12948 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012949
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012950 vos_ssr_protect(__func__);
12951 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
12952 vos_ssr_unprotect(__func__);
12953
12954 return ret;
12955
12956}
12957
12958static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012959{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012960 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12961 tHalHandle halHandle;
12962 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080012963 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012964
12965 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
12966
12967 /* Validate pAdapter */
12968 if (NULL == pAdapter)
12969 {
12970 hddLog(VOS_TRACE_LEVEL_ERROR,
12971 "%s: Invalid Adapter" ,__func__);
12972 return -EINVAL;
12973 }
12974
12975 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12976 status = wlan_hdd_validate_context(pHddCtx);
12977
12978 if (0 != status)
12979 {
12980 hddLog(VOS_TRACE_LEVEL_ERROR,
12981 "%s: HDD context is not valid", __func__);
12982 return status;
12983 }
12984
12985 /*Retrieve halHandle*/
12986 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
12987
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053012988 /* Flush the PMKID cache in CSR */
12989 if (eHAL_STATUS_SUCCESS !=
12990 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
12991 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
12992 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012993 }
12994
Wilson Yangef657d32014-01-15 19:19:23 -080012995 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012996}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012997
12998static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
12999{
13000 int ret;
13001
13002 vos_ssr_protect(__func__);
13003 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
13004 vos_ssr_unprotect(__func__);
13005
13006 return ret;
13007}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013008#endif
13009
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013010#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013011static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13012 struct net_device *dev,
13013 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013014{
13015 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13016 hdd_station_ctx_t *pHddStaCtx;
13017
13018 if (NULL == pAdapter)
13019 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013020 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013021 return -ENODEV;
13022 }
13023
13024 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13025
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013026 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13027 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
13028 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013029 // Added for debug on reception of Re-assoc Req.
13030 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
13031 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013032 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013033 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080013034 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013035 }
13036
13037#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080013038 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013039 ftie->ie_len);
13040#endif
13041
13042 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013043 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13044 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013045 ftie->ie_len);
13046 return 0;
13047}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013048
13049static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13050 struct net_device *dev,
13051 struct cfg80211_update_ft_ies_params *ftie)
13052{
13053 int ret;
13054
13055 vos_ssr_protect(__func__);
13056 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
13057 vos_ssr_unprotect(__func__);
13058
13059 return ret;
13060}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013061#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013062
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013063#ifdef FEATURE_WLAN_SCAN_PNO
13064
13065void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
13066 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
13067{
13068 int ret;
13069 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
13070 hdd_context_t *pHddCtx;
13071
Nirav Shah80830bf2013-12-31 16:35:12 +053013072 ENTER();
13073
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013074 if (NULL == pAdapter)
13075 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013076 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013077 "%s: HDD adapter is Null", __func__);
13078 return ;
13079 }
13080
13081 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13082 if (NULL == pHddCtx)
13083 {
13084 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13085 "%s: HDD context is Null!!!", __func__);
13086 return ;
13087 }
13088
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013089 spin_lock(&pHddCtx->schedScan_lock);
13090 if (TRUE == pHddCtx->isWiphySuspended)
13091 {
13092 pHddCtx->isSchedScanUpdatePending = TRUE;
13093 spin_unlock(&pHddCtx->schedScan_lock);
13094 hddLog(VOS_TRACE_LEVEL_INFO,
13095 "%s: Update cfg80211 scan database after it resume", __func__);
13096 return ;
13097 }
13098 spin_unlock(&pHddCtx->schedScan_lock);
13099
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013100 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
13101
13102 if (0 > ret)
13103 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
13104
13105 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013106 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13107 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013108}
13109
13110/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013111 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013112 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013113 */
13114static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
13115{
13116 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13117 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013118 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013119 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13120 int status = 0;
13121 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13122
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013123 /* The current firmware design does not allow PNO during any
13124 * active sessions. Hence, determine the active sessions
13125 * and return a failure.
13126 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013127 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
13128 {
13129 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013130 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013131
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013132 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
13133 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
13134 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
13135 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
13136 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
13137 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013138 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013139 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013140 }
13141 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13142 pAdapterNode = pNext;
13143 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013144 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013145}
13146
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013147void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
13148{
13149 hdd_adapter_t *pAdapter = callbackContext;
13150 hdd_context_t *pHddCtx;
13151
13152 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
13153 {
13154 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13155 FL("Invalid adapter or adapter has invalid magic"));
13156 return;
13157 }
13158
13159 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13160 if (0 != wlan_hdd_validate_context(pHddCtx))
13161 {
13162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13163 FL("HDD context is not valid"));
13164 return;
13165 }
13166
c_hpothub53c45d2014-08-18 16:53:14 +053013167 if (VOS_STATUS_SUCCESS != status)
13168 {
13169 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013170 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053013171 pHddCtx->isPnoEnable = FALSE;
13172 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013173
13174 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
13175 complete(&pAdapter->pno_comp_var);
13176}
13177
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013178/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013179 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
13180 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013181 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013182static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013183 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13184{
13185 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13186 tpSirPNOScanReq pPnoRequest = NULL;
13187 hdd_context_t *pHddCtx;
13188 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013189 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053013190 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
13191 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013192 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13193 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013194 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013195
13196 if (NULL == pAdapter)
13197 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013199 "%s: HDD adapter is Null", __func__);
13200 return -ENODEV;
13201 }
13202
13203 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013204 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013205
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013206 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013207 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13209 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013210 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013211 }
13212
13213 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13214 if (NULL == hHal)
13215 {
13216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13217 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013218 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013219 }
Sushant Kaushik2fe89932014-09-03 10:58:09 +053013220 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013221 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053013222 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013223 {
13224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13225 "%s: aborting the existing scan is unsuccessfull", __func__);
13226 return -EBUSY;
13227 }
13228
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013229 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013230 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013232 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013233 return -EBUSY;
13234 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013235
c_hpothu37f21312014-04-09 21:49:54 +053013236 if (TRUE == pHddCtx->isPnoEnable)
13237 {
13238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13239 FL("already PNO is enabled"));
13240 return -EBUSY;
13241 }
c_hpothu225aa7c2014-10-22 17:45:13 +053013242
13243 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
13244 {
13245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13246 "%s: abort ROC failed ", __func__);
13247 return -EBUSY;
13248 }
13249
c_hpothu37f21312014-04-09 21:49:54 +053013250 pHddCtx->isPnoEnable = TRUE;
13251
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013252 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13253 if (NULL == pPnoRequest)
13254 {
13255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13256 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053013257 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013258 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013259 }
13260
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053013261 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013262 pPnoRequest->enable = 1; /*Enable PNO */
13263 pPnoRequest->ucNetworksCount = request->n_match_sets;
13264
13265 if (( !pPnoRequest->ucNetworksCount ) ||
13266 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
13267 {
13268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013269 "%s: Network input is not correct %d Max Network supported is %d",
13270 __func__, pPnoRequest->ucNetworksCount,
13271 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013272 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013273 goto error;
13274 }
13275
13276 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
13277 {
13278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013279 "%s: Incorrect number of channels %d",
13280 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013281 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013282 goto error;
13283 }
13284
13285 /* Framework provides one set of channels(all)
13286 * common for all saved profile */
13287 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13288 channels_allowed, &num_channels_allowed))
13289 {
13290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13291 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013292 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013293 goto error;
13294 }
13295 /* Checking each channel against allowed channel list */
13296 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053013297 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013298 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013299 char chList [(request->n_channels*5)+1];
13300 int len;
13301 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013302 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013303 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013304 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013305 if (request->channels[i]->hw_value == channels_allowed[indx])
13306 {
13307 valid_ch[num_ch++] = request->channels[i]->hw_value;
13308 len += snprintf(chList+len, 5, "%d ",
13309 request->channels[i]->hw_value);
13310 break ;
13311 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013312 }
13313 }
Nirav Shah80830bf2013-12-31 16:35:12 +053013314 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
13315 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013316
13317 /* Filling per profile params */
13318 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
13319 {
13320 pPnoRequest->aNetworks[i].ssId.length =
13321 request->match_sets[i].ssid.ssid_len;
13322
13323 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
13324 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
13325 {
13326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013327 "%s: SSID Len %d is not correct for network %d",
13328 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013329 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013330 goto error;
13331 }
13332
13333 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
13334 request->match_sets[i].ssid.ssid,
13335 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013336 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13337 "%s: SSID of network %d is %s ", __func__,
13338 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013339 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
13340 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
13341 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
13342
13343 /*Copying list of valid channel into request */
13344 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
13345 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
13346
13347 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
13348 }
13349
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013350 for (i = 0; i < request->n_ssids; i++)
13351 {
13352 j = 0;
13353 while (j < pPnoRequest->ucNetworksCount)
13354 {
13355 if ((pPnoRequest->aNetworks[j].ssId.length ==
13356 request->ssids[i].ssid_len) &&
13357 (0 == memcmp(pPnoRequest->aNetworks[j].ssId.ssId,
13358 request->ssids[i].ssid,
13359 pPnoRequest->aNetworks[j].ssId.length)))
13360 {
13361 pPnoRequest->aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
13362 break;
13363 }
13364 j++;
13365 }
13366 }
13367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13368 "Number of hidden networks being Configured = %d",
13369 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080013371 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013372 if ((0 < request->ie_len) && (NULL != request->ie))
13373 {
13374 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
13375 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
13376 pPnoRequest->us24GProbeTemplateLen);
13377
13378 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
13379 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
13380 pPnoRequest->us5GProbeTemplateLen);
13381 }
13382
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053013383 /* Driver gets only one time interval which is hardcoded in
13384 * supplicant for 10000ms. Taking power consumption into account 6 timers
13385 * will be used, Timervalue is increased exponentially i.e 10,20,40,
13386 * 80,160,320 secs. And number of scan cycle for each timer
13387 * is configurable through INI param gPNOScanTimerRepeatValue.
13388 * If it is set to 0 only one timer will be used and PNO scan cycle
13389 * will be repeated after each interval specified by supplicant
13390 * till PNO is disabled.
13391 */
13392 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
13393 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
13394 else
13395 pPnoRequest->scanTimers.ucScanTimersCount =
13396 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
13397
13398 tempInterval = (request->interval)/1000;
13399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13400 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
13401 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
13402 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
13403 {
13404 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
13405 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
13406 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
13407 tempInterval *= 2;
13408 }
13409 //Repeat last timer until pno disabled.
13410 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
13411
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053013412 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013413
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013414 INIT_COMPLETION(pAdapter->pno_comp_var);
13415 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
13416 pPnoRequest->callbackContext = pAdapter;
13417 pAdapter->pno_req_status = 0;
13418
Nirav Shah80830bf2013-12-31 16:35:12 +053013419 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13420 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
13421 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
13422 pPnoRequest->scanTimers.ucScanTimersCount);
13423
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013424 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
13425 pPnoRequest, pAdapter->sessionId,
13426 hdd_cfg80211_sched_scan_done_callback, pAdapter);
13427 if (eHAL_STATUS_SUCCESS != status)
13428 {
13429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013430 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013431 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013432 goto error;
13433 }
13434
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013435 ret = wait_for_completion_timeout(
13436 &pAdapter->pno_comp_var,
13437 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
13438 if (0 >= ret)
13439 {
13440 // Did not receive the response for PNO enable in time.
13441 // Assuming the PNO enable was success.
13442 // Returning error from here, because we timeout, results
13443 // in side effect of Wifi (Wifi Setting) not to work.
13444 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13445 FL("Timed out waiting for PNO to be Enabled"));
13446 ret = 0;
13447 goto error;
13448 }
13449
c_hpothu3c986b22014-07-09 14:45:09 +053013450 vos_mem_free(pPnoRequest);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013451 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053013452 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013453
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013454error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013455 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13456 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013457 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053013458 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013459 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013460}
13461
13462/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013463 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
13464 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013465 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013466static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
13467 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13468{
13469 int ret;
13470
13471 vos_ssr_protect(__func__);
13472 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
13473 vos_ssr_unprotect(__func__);
13474
13475 return ret;
13476}
13477
13478/*
13479 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
13480 * Function to disable PNO
13481 */
13482static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013483 struct net_device *dev)
13484{
13485 eHalStatus status = eHAL_STATUS_FAILURE;
13486 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13487 hdd_context_t *pHddCtx;
13488 tHalHandle hHal;
13489 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013490 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013491
13492 ENTER();
13493
13494 if (NULL == pAdapter)
13495 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013497 "%s: HDD adapter is Null", __func__);
13498 return -ENODEV;
13499 }
13500
13501 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013502
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013503 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013504 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013505 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013506 "%s: HDD context is Null", __func__);
13507 return -ENODEV;
13508 }
13509
13510 /* The return 0 is intentional when isLogpInProgress and
13511 * isLoadUnloadInProgress. We did observe a crash due to a return of
13512 * failure in sched_scan_stop , especially for a case where the unload
13513 * of the happens at the same time. The function __cfg80211_stop_sched_scan
13514 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
13515 * success. If it returns a failure , then its next invocation due to the
13516 * clean up of the second interface will have the dev pointer corresponding
13517 * to the first one leading to a crash.
13518 */
13519 if (pHddCtx->isLogpInProgress)
13520 {
13521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13522 "%s: LOGP in Progress. Ignore!!!", __func__);
13523 return ret;
13524 }
13525
Mihir Shete18156292014-03-11 15:38:30 +053013526 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013527 {
13528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13529 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13530 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013531 }
13532
13533 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13534 if (NULL == hHal)
13535 {
13536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13537 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013538 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013539 }
13540
13541 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13542 if (NULL == pPnoRequest)
13543 {
13544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13545 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013546 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013547 }
13548
13549 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
13550 pPnoRequest->enable = 0; /* Disable PNO */
13551 pPnoRequest->ucNetworksCount = 0;
13552
13553 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
13554 pAdapter->sessionId,
13555 NULL, pAdapter);
13556 if (eHAL_STATUS_SUCCESS != status)
13557 {
13558 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13559 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013560 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013561 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013562 }
c_hpothu37f21312014-04-09 21:49:54 +053013563 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013564
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013565error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013567 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013568 vos_mem_free(pPnoRequest);
13569
13570 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013571 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013572}
13573
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013574/*
13575 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
13576 * NL interface to disable PNO
13577 */
13578static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
13579 struct net_device *dev)
13580{
13581 int ret;
13582
13583 vos_ssr_protect(__func__);
13584 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
13585 vos_ssr_unprotect(__func__);
13586
13587 return ret;
13588}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013589#endif /*FEATURE_WLAN_SCAN_PNO*/
13590
13591
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013592#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013593#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013594static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
13595 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013596 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
13597#else
13598static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
13599 u8 *peer, u8 action_code, u8 dialog_token,
13600 u16 status_code, const u8 *buf, size_t len)
13601#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013602{
13603
13604 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13605 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013606 u8 peerMac[6];
13607 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070013608 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080013609 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070013610 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013611#if !(TDLS_MGMT_VERSION2)
13612 u32 peer_capability = 0;
13613#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013614 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013615
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013616 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13617 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
13618 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013619 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013620 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013622 "Invalid arguments");
13623 return -EINVAL;
13624 }
13625
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013626 if (pHddCtx->isLogpInProgress)
13627 {
13628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13629 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053013630 wlan_hdd_tdls_set_link_status(pAdapter,
13631 peer,
13632 eTDLS_LINK_IDLE,
13633 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013634 return -EBUSY;
13635 }
13636
Hoonki Lee27511902013-03-14 18:19:06 -070013637 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013638 {
Hoonki Lee27511902013-03-14 18:19:06 -070013639 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13640 "%s: TDLS mode is disabled OR not enabled in FW."
13641 MAC_ADDRESS_STR " action %d declined.",
13642 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013643 return -ENOTSUPP;
13644 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013645
Hoonki Lee27511902013-03-14 18:19:06 -070013646 /* other than teardown frame, other mgmt frames are not sent if disabled */
13647 if (SIR_MAC_TDLS_TEARDOWN != action_code)
13648 {
13649 /* if tdls_mode is disabled to respond to peer's request */
13650 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
13651 {
13652 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13653 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013654 " TDLS mode is disabled. action %d declined.",
13655 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070013656
13657 return -ENOTSUPP;
13658 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053013659
13660 if (vos_max_concurrent_connections_reached())
13661 {
13662 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13663 return -EINVAL;
13664 }
Hoonki Lee27511902013-03-14 18:19:06 -070013665 }
13666
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013667 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
13668 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013669 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013670 {
13671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013672 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013673 " TDLS setup is ongoing. action %d declined.",
13674 __func__, MAC_ADDR_ARRAY(peer), action_code);
13675 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013676 }
13677 }
13678
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013679 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
13680 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080013681 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013682 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
13683 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080013684 {
13685 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
13686 we return error code at 'add_station()'. Hence we have this
13687 check again in addtion to add_station().
13688 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013689 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080013690 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013691 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13692 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013693 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
13694 __func__, MAC_ADDR_ARRAY(peer), action_code,
13695 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013696 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080013697 }
13698 else
13699 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013700 /* maximum reached. tweak to send error code to peer and return
13701 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080013702 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13704 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013705 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
13706 __func__, MAC_ADDR_ARRAY(peer), status_code,
13707 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013708 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013709 /* fall through to send setup resp with failure status
13710 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080013711 }
13712 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013713 else
13714 {
13715 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013716 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013717 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013718 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013719 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013720 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
13721 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013722 return -EPERM;
13723 }
13724 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013725 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013726 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013727
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013728#ifdef WLAN_FEATURE_TDLS_DEBUG
13729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053013730 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013731 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
13732 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013733#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013734
Hoonki Leea34dd892013-02-05 22:56:02 -080013735 /*Except teardown responder will not be used so just make 0*/
13736 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013737 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080013738 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013739
13740 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013741 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013742
13743 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
13744 responder = pTdlsPeer->is_responder;
13745 else
Hoonki Leea34dd892013-02-05 22:56:02 -080013746 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013747 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053013748 "%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 -070013749 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
13750 dialog_token, status_code, len);
13751 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080013752 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013753 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013754
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013755 /* For explicit trigger of DIS_REQ come out of BMPS for
13756 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070013757 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013758 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
13759 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070013760 {
13761 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
13762 {
13763 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013764 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070013765 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
13766 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013767 if (SIR_MAC_TDLS_DIS_REQ != action_code)
13768 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070013769 }
13770
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013771 /* make sure doesn't call send_mgmt() while it is pending */
13772 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
13773 {
13774 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013775 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013776 __func__, MAC_ADDR_ARRAY(peer), action_code);
13777 return -EBUSY;
13778 }
13779
13780 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013781 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
13782
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013783 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053013784 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013785
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013786 if (VOS_STATUS_SUCCESS != status)
13787 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13789 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013790 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -070013791 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013792 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013793 }
13794
Hoonki Leed37cbb32013-04-20 00:31:14 -070013795 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
13796 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
13797
13798 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013799 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070013800 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013801 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070013802 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013803 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080013804
13805 if (pHddCtx->isLogpInProgress)
13806 {
13807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13808 "%s: LOGP in Progress. Ignore!!!", __func__);
13809 return -EAGAIN;
13810 }
13811
Hoonki Leed37cbb32013-04-20 00:31:14 -070013812 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013813 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013814 }
13815
Gopichand Nakkala05922802013-03-14 12:23:19 -070013816 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070013817 {
13818 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013819 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070013820 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013821
Hoonki Leea34dd892013-02-05 22:56:02 -080013822 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
13823 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013824 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080013825 }
13826 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
13827 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013828 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080013829 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013830
13831 return 0;
13832}
13833
Atul Mittal115287b2014-07-08 13:26:33 +053013834
13835int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
13836 u8 *peer,
13837 cfg80211_exttdls_callback callback)
13838{
13839
13840 hddTdlsPeer_t *pTdlsPeer;
13841 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13843 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
13844 __func__, MAC_ADDR_ARRAY(peer));
13845
13846 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13847 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13848
13849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13850 " %s TDLS External control and Implicit Trigger not enabled ",
13851 __func__);
13852 return -ENOTSUPP;
13853 }
13854
13855 /* To cater the requirement of establishing the TDLS link
13856 * irrespective of the data traffic , get an entry of TDLS peer.
13857 */
13858 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
13859 if (pTdlsPeer == NULL) {
13860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13861 "%s: peer " MAC_ADDRESS_STR " not existing",
13862 __func__, MAC_ADDR_ARRAY(peer));
13863 return -EINVAL;
13864 }
13865
13866 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
13867
13868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13869 " %s TDLS Add Force Peer Failed",
13870 __func__);
13871 return -EINVAL;
13872 }
13873 /*EXT TDLS*/
13874
13875 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
13876 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13877 " %s TDLS set callback Failed",
13878 __func__);
13879 return -EINVAL;
13880 }
13881
13882 return(0);
13883
13884}
13885
13886int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
13887{
13888
13889 hddTdlsPeer_t *pTdlsPeer;
13890 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13891 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13892 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
13893 __func__, MAC_ADDR_ARRAY(peer));
13894
13895 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13896 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13897
13898 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13899 " %s TDLS External control and Implicit Trigger not enabled ",
13900 __func__);
13901 return -ENOTSUPP;
13902 }
13903
13904
13905 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13906
13907 if ( NULL == pTdlsPeer ) {
13908 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
13909 " peer not exsting",
13910 __func__, MAC_ADDR_ARRAY(peer));
13911 return -EINVAL;
13912 }
13913 else {
13914 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
13915 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
13916 }
13917
13918 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
13919 return -EINVAL;
13920
13921 /*EXT TDLS*/
13922
13923 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
13924
13925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13926 " %s TDLS set callback Failed",
13927 __func__);
13928 return -EINVAL;
13929 }
13930 return(0);
13931
13932}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013933static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013934 u8 *peer, enum nl80211_tdls_operation oper)
13935{
13936 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13937 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013938 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013939 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013940
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013941 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13942 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
13943 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013944 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013945 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013946 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070013947 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013948 return -EINVAL;
13949 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013950
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013951 status = wlan_hdd_validate_context(pHddCtx);
13952
13953 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013954 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13956 "%s: HDD context is not valid", __func__);
13957 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013958 }
13959
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013960
13961 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013962 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013963 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070013965 "TDLS Disabled in INI OR not enabled in FW. "
13966 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013967 return -ENOTSUPP;
13968 }
13969
13970 switch (oper) {
13971 case NL80211_TDLS_ENABLE_LINK:
13972 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013973 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013974 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013975 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013976
Sunil Dutt41de4e22013-11-14 18:09:02 +053013977 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13978
13979 if ( NULL == pTdlsPeer ) {
13980 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13981 " (oper %d) not exsting. ignored",
13982 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13983 return -EINVAL;
13984 }
13985
13986 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13987 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13988 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13989 "NL80211_TDLS_ENABLE_LINK");
13990
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070013991 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
13992 {
13993 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
13994 MAC_ADDRESS_STR " failed",
13995 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
13996 return -EINVAL;
13997 }
13998
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013999 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014000 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014001 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053014002
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014003 if (0 != wlan_hdd_tdls_get_link_establish_params(
14004 pAdapter, peer,&tdlsLinkEstablishParams)) {
14005 return -EINVAL;
14006 }
14007 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014008
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014009 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
14010 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
14011 /* Send TDLS peer UAPSD capabilities to the firmware and
14012 * register with the TL on after the response for this operation
14013 * is received .
14014 */
14015 ret = wait_for_completion_interruptible_timeout(
14016 &pAdapter->tdls_link_establish_req_comp,
14017 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
14018 if (ret <= 0)
14019 {
14020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14021 "%s: Link Establish Request Faled Status %ld",
14022 __func__, ret);
14023 return -EINVAL;
14024 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014025 }
Atul Mittal115287b2014-07-08 13:26:33 +053014026 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
14027 eTDLS_LINK_CONNECTED,
14028 eTDLS_LINK_SUCCESS);
Gopichand Nakkala471708b2013-06-04 20:03:01 +053014029 /* Mark TDLS client Authenticated .*/
14030 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
14031 pTdlsPeer->staId,
14032 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014033 if (VOS_STATUS_SUCCESS == status)
14034 {
Hoonki Lee14621352013-04-16 17:51:19 -070014035 if (pTdlsPeer->is_responder == 0)
14036 {
14037 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
14038
14039 wlan_hdd_tdls_timer_restart(pAdapter,
14040 &pTdlsPeer->initiatorWaitTimeoutTimer,
14041 WAIT_TIME_TDLS_INITIATOR);
14042 /* suspend initiator TX until it receives direct packet from the
14043 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
14044 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
14045 &staId, NULL);
14046 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014047 wlan_hdd_tdls_increment_peer_count(pAdapter);
14048 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014049 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014050
14051 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053014052 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
14053 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014054 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053014055 int ac;
14056 uint8 ucAc[4] = { WLANTL_AC_VO,
14057 WLANTL_AC_VI,
14058 WLANTL_AC_BK,
14059 WLANTL_AC_BE };
14060 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
14061 for(ac=0; ac < 4; ac++)
14062 {
14063 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
14064 pTdlsPeer->staId, ucAc[ac],
14065 tlTid[ac], tlTid[ac], 0, 0,
14066 WLANTL_BI_DIR );
14067 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014068 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014069 }
14070
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014071 }
14072 break;
14073 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080014074 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053014075 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
14076
14077 if ( NULL == pTdlsPeer ) {
14078 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
14079 " (oper %d) not exsting. ignored",
14080 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
14081 return -EINVAL;
14082 }
14083
14084 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14085 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
14086 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
14087 "NL80211_TDLS_DISABLE_LINK");
14088
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014089 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080014090 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014091 long status;
14092
Atul Mittal271a7652014-09-12 13:18:22 +053014093
14094 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
14095 eTDLS_LINK_TEARING,
14096 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
14097 eTDLS_LINK_UNSPECIFIED:
14098 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014099 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
14100
Lee Hoonkic1262f22013-01-24 21:59:00 -080014101 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
14102 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014103
14104 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
14105 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053014106 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053014107 eTDLS_LINK_IDLE,
14108 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014109 if (status <= 0)
14110 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014111 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14112 "%s: Del station failed status %ld",
14113 __func__, status);
14114 return -EPERM;
14115 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014116 }
14117 else
14118 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014119 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14120 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080014121 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014122 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014123 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014124 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053014125 {
Atul Mittal115287b2014-07-08 13:26:33 +053014126 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053014127
Atul Mittal115287b2014-07-08 13:26:33 +053014128 if (0 != status)
14129 {
14130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14131 "%s: Error in TDLS Teardown", __func__);
14132 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053014133 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053014134 break;
14135 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014136 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053014137 {
Atul Mittal115287b2014-07-08 13:26:33 +053014138 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
14139 peer,
14140 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053014141
Atul Mittal115287b2014-07-08 13:26:33 +053014142 if (0 != status)
14143 {
14144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14145 "%s: Error in TDLS Setup", __func__);
14146 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053014147 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053014148 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053014149 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014150 case NL80211_TDLS_DISCOVERY_REQ:
14151 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14153 "%s: We don't support in-driver setup/teardown/discovery "
14154 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014155 return -ENOTSUPP;
14156 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014157 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14158 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014159 return -ENOTSUPP;
14160 }
14161 return 0;
14162}
Chilam NG571c65a2013-01-19 12:27:36 +053014163
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014164static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
14165 u8 *peer, enum nl80211_tdls_operation oper)
14166{
14167 int ret;
14168
14169 vos_ssr_protect(__func__);
14170 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
14171 vos_ssr_unprotect(__func__);
14172
14173 return ret;
14174}
14175
Chilam NG571c65a2013-01-19 12:27:36 +053014176int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
14177 struct net_device *dev, u8 *peer)
14178{
Arif Hussaina7c8e412013-11-20 11:06:42 -080014179 hddLog(VOS_TRACE_LEVEL_INFO,
14180 "tdls send discover req: "MAC_ADDRESS_STR,
14181 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053014182
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014183#if TDLS_MGMT_VERSION2
14184 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14185 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
14186#else
Chilam NG571c65a2013-01-19 12:27:36 +053014187 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14188 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014189#endif
Chilam NG571c65a2013-01-19 12:27:36 +053014190}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014191#endif
14192
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014193#ifdef WLAN_FEATURE_GTK_OFFLOAD
14194/*
14195 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
14196 * Callback rountine called upon receiving response for
14197 * get offload info
14198 */
14199void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
14200 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
14201{
14202
14203 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014204 tANI_U8 tempReplayCounter[8];
14205 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014206
14207 ENTER();
14208
14209 if (NULL == pAdapter)
14210 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014211 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014212 "%s: HDD adapter is Null", __func__);
14213 return ;
14214 }
14215
14216 if (NULL == pGtkOffloadGetInfoRsp)
14217 {
14218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14219 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
14220 return ;
14221 }
14222
14223 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
14224 {
14225 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14226 "%s: wlan Failed to get replay counter value",
14227 __func__);
14228 return ;
14229 }
14230
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014231 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14232 /* Update replay counter */
14233 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
14234 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14235
14236 {
14237 /* changing from little to big endian since supplicant
14238 * works on big endian format
14239 */
14240 int i;
14241 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14242
14243 for (i = 0; i < 8; i++)
14244 {
14245 tempReplayCounter[7-i] = (tANI_U8)p[i];
14246 }
14247 }
14248
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014249 /* Update replay counter to NL */
14250 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014251 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014252}
14253
14254/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014255 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014256 * This function is used to offload GTK rekeying job to the firmware.
14257 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014258int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014259 struct cfg80211_gtk_rekey_data *data)
14260{
14261 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14262 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14263 hdd_station_ctx_t *pHddStaCtx;
14264 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014265 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014266 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014267 eHalStatus status = eHAL_STATUS_FAILURE;
14268
14269 ENTER();
14270
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014271
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014272 if (NULL == pAdapter)
14273 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014275 "%s: HDD adapter is Null", __func__);
14276 return -ENODEV;
14277 }
14278
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014279 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14280 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
14281 pAdapter->sessionId, pAdapter->device_mode));
14282
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014283 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014284
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014285 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014286 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14288 "%s: HDD context is not valid", __func__);
14289 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014290 }
14291
14292 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14293 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14294 if (NULL == hHal)
14295 {
14296 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14297 "%s: HAL context is Null!!!", __func__);
14298 return -EAGAIN;
14299 }
14300
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014301 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
14302 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
14303 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
14304 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014305 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014306 {
14307 /* changing from big to little endian since driver
14308 * works on little endian format
14309 */
14310 tANI_U8 *p =
14311 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
14312 int i;
14313
14314 for (i = 0; i < 8; i++)
14315 {
14316 p[7-i] = data->replay_ctr[i];
14317 }
14318 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014319
14320 if (TRUE == pHddCtx->hdd_wlan_suspended)
14321 {
14322 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014323 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
14324 sizeof (tSirGtkOffloadParams));
14325 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014326 pAdapter->sessionId);
14327
14328 if (eHAL_STATUS_SUCCESS != status)
14329 {
14330 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14331 "%s: sme_SetGTKOffload failed, returned %d",
14332 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053014333
14334 /* Need to clear any trace of key value in the memory.
14335 * Thus zero out the memory even though it is local
14336 * variable.
14337 */
14338 vos_mem_zero(&hddGtkOffloadReqParams,
14339 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014340 return status;
14341 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14343 "%s: sme_SetGTKOffload successfull", __func__);
14344 }
14345 else
14346 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14348 "%s: wlan not suspended GTKOffload request is stored",
14349 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014350 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014351
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053014352 /* Need to clear any trace of key value in the memory.
14353 * Thus zero out the memory even though it is local
14354 * variable.
14355 */
14356 vos_mem_zero(&hddGtkOffloadReqParams,
14357 sizeof(hddGtkOffloadReqParams));
14358
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014359 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014360}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014361
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014362int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
14363 struct cfg80211_gtk_rekey_data *data)
14364{
14365 int ret;
14366
14367 vos_ssr_protect(__func__);
14368 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
14369 vos_ssr_unprotect(__func__);
14370
14371 return ret;
14372}
14373#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014374/*
14375 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
14376 * This function is used to set access control policy
14377 */
14378static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
14379 struct net_device *dev, const struct cfg80211_acl_data *params)
14380{
14381 int i;
14382 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14383 hdd_hostapd_state_t *pHostapdState;
14384 tsap_Config_t *pConfig;
14385 v_CONTEXT_t pVosContext = NULL;
14386 hdd_context_t *pHddCtx;
14387 int status;
14388
14389 ENTER();
14390
14391 if (NULL == pAdapter)
14392 {
14393 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14394 "%s: HDD adapter is Null", __func__);
14395 return -ENODEV;
14396 }
14397
14398 if (NULL == params)
14399 {
14400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14401 "%s: params is Null", __func__);
14402 return -EINVAL;
14403 }
14404
14405 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14406 status = wlan_hdd_validate_context(pHddCtx);
14407
14408 if (0 != status)
14409 {
14410 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14411 "%s: HDD context is not valid", __func__);
14412 return status;
14413 }
14414
14415 pVosContext = pHddCtx->pvosContext;
14416 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
14417
14418 if (NULL == pHostapdState)
14419 {
14420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14421 "%s: pHostapdState is Null", __func__);
14422 return -EINVAL;
14423 }
14424
14425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
14426 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
14427
14428 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
14429 {
14430 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
14431
14432 /* default value */
14433 pConfig->num_accept_mac = 0;
14434 pConfig->num_deny_mac = 0;
14435
14436 /**
14437 * access control policy
14438 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
14439 * listed in hostapd.deny file.
14440 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
14441 * listed in hostapd.accept file.
14442 */
14443 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
14444 {
14445 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
14446 }
14447 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
14448 {
14449 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
14450 }
14451 else
14452 {
14453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14454 "%s:Acl Policy : %d is not supported",
14455 __func__, params->acl_policy);
14456 return -ENOTSUPP;
14457 }
14458
14459 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
14460 {
14461 pConfig->num_accept_mac = params->n_acl_entries;
14462 for (i = 0; i < params->n_acl_entries; i++)
14463 {
14464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14465 "** Add ACL MAC entry %i in WhiletList :"
14466 MAC_ADDRESS_STR, i,
14467 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14468
14469 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
14470 sizeof(qcmacaddr));
14471 }
14472 }
14473 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
14474 {
14475 pConfig->num_deny_mac = params->n_acl_entries;
14476 for (i = 0; i < params->n_acl_entries; i++)
14477 {
14478 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14479 "** Add ACL MAC entry %i in BlackList :"
14480 MAC_ADDRESS_STR, i,
14481 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14482
14483 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
14484 sizeof(qcmacaddr));
14485 }
14486 }
14487
14488 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
14489 {
14490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14491 "%s: SAP Set Mac Acl fail", __func__);
14492 return -EINVAL;
14493 }
14494 }
14495 else
14496 {
14497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014498 "%s: Invalid device_mode = %s (%d)",
14499 __func__, hdd_device_modetoString(pAdapter->device_mode),
14500 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014501 return -EINVAL;
14502 }
14503
14504 return 0;
14505}
14506
Leo Chang9056f462013-08-01 19:21:11 -070014507#ifdef WLAN_NL80211_TESTMODE
14508#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070014509void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070014510(
14511 void *pAdapter,
14512 void *indCont
14513)
14514{
Leo Changd9df8aa2013-09-26 13:32:26 -070014515 tSirLPHBInd *lphbInd;
14516 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053014517 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070014518
14519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014520 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070014521
c_hpothu73f35e62014-04-18 13:40:08 +053014522 if (pAdapter == NULL)
14523 {
14524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14525 "%s: pAdapter is NULL\n",__func__);
14526 return;
14527 }
14528
Leo Chang9056f462013-08-01 19:21:11 -070014529 if (NULL == indCont)
14530 {
14531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014532 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070014533 return;
14534 }
14535
c_hpothu73f35e62014-04-18 13:40:08 +053014536 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070014537 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070014538 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053014539 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070014540 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070014541 GFP_ATOMIC);
14542 if (!skb)
14543 {
14544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14545 "LPHB timeout, NL buffer alloc fail");
14546 return;
14547 }
14548
Leo Changac3ba772013-10-07 09:47:04 -070014549 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070014550 {
14551 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14552 "WLAN_HDD_TM_ATTR_CMD put fail");
14553 goto nla_put_failure;
14554 }
Leo Changac3ba772013-10-07 09:47:04 -070014555 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070014556 {
14557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14558 "WLAN_HDD_TM_ATTR_TYPE put fail");
14559 goto nla_put_failure;
14560 }
Leo Changac3ba772013-10-07 09:47:04 -070014561 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070014562 sizeof(tSirLPHBInd), lphbInd))
14563 {
14564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14565 "WLAN_HDD_TM_ATTR_DATA put fail");
14566 goto nla_put_failure;
14567 }
Leo Chang9056f462013-08-01 19:21:11 -070014568 cfg80211_testmode_event(skb, GFP_ATOMIC);
14569 return;
14570
14571nla_put_failure:
14572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14573 "NLA Put fail");
14574 kfree_skb(skb);
14575
14576 return;
14577}
14578#endif /* FEATURE_WLAN_LPHB */
14579
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014580static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070014581{
14582 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
14583 int err = 0;
14584#ifdef FEATURE_WLAN_LPHB
14585 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070014586 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -070014587#endif /* FEATURE_WLAN_LPHB */
14588
14589 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
14590 if (err)
14591 {
14592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14593 "%s Testmode INV ATTR", __func__);
14594 return err;
14595 }
14596
14597 if (!tb[WLAN_HDD_TM_ATTR_CMD])
14598 {
14599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14600 "%s Testmode INV CMD", __func__);
14601 return -EINVAL;
14602 }
14603
14604 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
14605 {
14606#ifdef FEATURE_WLAN_LPHB
14607 /* Low Power Heartbeat configuration request */
14608 case WLAN_HDD_TM_CMD_WLAN_HB:
14609 {
14610 int buf_len;
14611 void *buf;
14612 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080014613 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070014614
14615 if (!tb[WLAN_HDD_TM_ATTR_DATA])
14616 {
14617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14618 "%s Testmode INV DATA", __func__);
14619 return -EINVAL;
14620 }
14621
14622 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
14623 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080014624
14625 hb_params_temp =(tSirLPHBReq *)buf;
14626 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
14627 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
14628 return -EINVAL;
14629
Leo Chang9056f462013-08-01 19:21:11 -070014630 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
14631 if (NULL == hb_params)
14632 {
14633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14634 "%s Request Buffer Alloc Fail", __func__);
14635 return -EINVAL;
14636 }
14637
14638 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070014639 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
14640 hb_params,
14641 wlan_hdd_cfg80211_lphb_ind_handler);
14642 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070014643 {
Leo Changd9df8aa2013-09-26 13:32:26 -070014644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14645 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070014646 vos_mem_free(hb_params);
14647 }
Leo Chang9056f462013-08-01 19:21:11 -070014648 return 0;
14649 }
14650#endif /* FEATURE_WLAN_LPHB */
14651 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14653 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070014654 return -EOPNOTSUPP;
14655 }
14656
14657 return err;
14658}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014659
14660static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
14661{
14662 int ret;
14663
14664 vos_ssr_protect(__func__);
14665 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
14666 vos_ssr_unprotect(__func__);
14667
14668 return ret;
14669}
Leo Chang9056f462013-08-01 19:21:11 -070014670#endif /* CONFIG_NL80211_TESTMODE */
14671
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014672static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014673 struct net_device *dev,
14674 int idx, struct survey_info *survey)
14675{
14676 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14677 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053014678 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014679 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053014680 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014681 v_S7_t snr,rssi;
14682 int status, i, j, filled = 0;
14683
14684 ENTER();
14685
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014686 if (NULL == pAdapter)
14687 {
14688 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14689 "%s: HDD adapter is Null", __func__);
14690 return -ENODEV;
14691 }
14692
14693 if (NULL == wiphy)
14694 {
14695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14696 "%s: wiphy is Null", __func__);
14697 return -ENODEV;
14698 }
14699
14700 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14701 status = wlan_hdd_validate_context(pHddCtx);
14702
14703 if (0 != status)
14704 {
14705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14706 "%s: HDD context is not valid", __func__);
14707 return status;
14708 }
14709
Mihir Sheted9072e02013-08-21 17:02:29 +053014710 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14711
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014712 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053014713 0 != pAdapter->survey_idx ||
14714 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014715 {
14716 /* The survey dump ops when implemented completely is expected to
14717 * return a survey of all channels and the ops is called by the
14718 * kernel with incremental values of the argument 'idx' till it
14719 * returns -ENONET. But we can only support the survey for the
14720 * operating channel for now. survey_idx is used to track
14721 * that the ops is called only once and then return -ENONET for
14722 * the next iteration
14723 */
14724 pAdapter->survey_idx = 0;
14725 return -ENONET;
14726 }
14727
14728 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14729
14730 wlan_hdd_get_snr(pAdapter, &snr);
14731 wlan_hdd_get_rssi(pAdapter, &rssi);
14732
14733 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
14734 hdd_wlan_get_freq(channel, &freq);
14735
14736
14737 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
14738 {
14739 if (NULL == wiphy->bands[i])
14740 {
14741 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
14742 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
14743 continue;
14744 }
14745
14746 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
14747 {
14748 struct ieee80211_supported_band *band = wiphy->bands[i];
14749
14750 if (band->channels[j].center_freq == (v_U16_t)freq)
14751 {
14752 survey->channel = &band->channels[j];
14753 /* The Rx BDs contain SNR values in dB for the received frames
14754 * while the supplicant expects noise. So we calculate and
14755 * return the value of noise (dBm)
14756 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
14757 */
14758 survey->noise = rssi - snr;
14759 survey->filled = SURVEY_INFO_NOISE_DBM;
14760 filled = 1;
14761 }
14762 }
14763 }
14764
14765 if (filled)
14766 pAdapter->survey_idx = 1;
14767 else
14768 {
14769 pAdapter->survey_idx = 0;
14770 return -ENONET;
14771 }
14772
14773 return 0;
14774}
14775
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014776static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
14777 struct net_device *dev,
14778 int idx, struct survey_info *survey)
14779{
14780 int ret;
14781
14782 vos_ssr_protect(__func__);
14783 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
14784 vos_ssr_unprotect(__func__);
14785
14786 return ret;
14787}
14788
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014789/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014790 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014791 * this is called when cfg80211 driver resume
14792 * driver updates latest sched_scan scan result(if any) to cfg80211 database
14793 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014794int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014795{
14796 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14797 hdd_adapter_t *pAdapter;
14798 hdd_adapter_list_node_t *pAdapterNode, *pNext;
14799 VOS_STATUS status = VOS_STATUS_SUCCESS;
14800
14801 ENTER();
14802
14803 if ( NULL == pHddCtx )
14804 {
14805 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14806 "%s: HddCtx validation failed", __func__);
14807 return 0;
14808 }
14809
14810 if (pHddCtx->isLogpInProgress)
14811 {
14812 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14813 "%s: LOGP in Progress. Ignore!!!", __func__);
14814 return 0;
14815 }
14816
Mihir Shete18156292014-03-11 15:38:30 +053014817 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014818 {
14819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14820 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14821 return 0;
14822 }
14823
14824 spin_lock(&pHddCtx->schedScan_lock);
14825 pHddCtx->isWiphySuspended = FALSE;
14826 if (TRUE != pHddCtx->isSchedScanUpdatePending)
14827 {
14828 spin_unlock(&pHddCtx->schedScan_lock);
14829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14830 "%s: Return resume is not due to PNO indication", __func__);
14831 return 0;
14832 }
14833 // Reset flag to avoid updatating cfg80211 data old results again
14834 pHddCtx->isSchedScanUpdatePending = FALSE;
14835 spin_unlock(&pHddCtx->schedScan_lock);
14836
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014837
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014838 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14839
14840 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14841 {
14842 pAdapter = pAdapterNode->pAdapter;
14843 if ( (NULL != pAdapter) &&
14844 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
14845 {
14846 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014847 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14849 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014850 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014851 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014852 {
14853 /* Acquire wakelock to handle the case where APP's tries to
14854 * suspend immediately after updating the scan results. Whis
14855 * results in app's is in suspended state and not able to
14856 * process the connect request to AP
14857 */
14858 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014859 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053014860 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014861
14862 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14863 "%s : cfg80211 scan result database updated", __func__);
14864
14865 return 0;
14866
14867 }
14868 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14869 pAdapterNode = pNext;
14870 }
14871
14872 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14873 "%s: Failed to find Adapter", __func__);
14874 return 0;
14875}
14876
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014877int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
14878{
14879 int ret;
14880
14881 vos_ssr_protect(__func__);
14882 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
14883 vos_ssr_unprotect(__func__);
14884
14885 return ret;
14886}
14887
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014888/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014889 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014890 * this is called when cfg80211 driver suspends
14891 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014892int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014893 struct cfg80211_wowlan *wow)
14894{
14895 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14896
14897 ENTER();
14898 if (NULL == pHddCtx)
14899 {
14900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14901 "%s: HddCtx validation failed", __func__);
14902 return 0;
14903 }
14904
14905 pHddCtx->isWiphySuspended = TRUE;
14906
14907 EXIT();
14908
14909 return 0;
14910}
14911
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053014912int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
14913 struct cfg80211_wowlan *wow)
14914{
14915 int ret;
14916
14917 vos_ssr_protect(__func__);
14918 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
14919 vos_ssr_unprotect(__func__);
14920
14921 return ret;
14922}
Jeff Johnson295189b2012-06-20 16:38:30 -070014923/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014924static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070014925{
14926 .add_virtual_intf = wlan_hdd_add_virtual_intf,
14927 .del_virtual_intf = wlan_hdd_del_virtual_intf,
14928 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
14929 .change_station = wlan_hdd_change_station,
14930#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
14931 .add_beacon = wlan_hdd_cfg80211_add_beacon,
14932 .del_beacon = wlan_hdd_cfg80211_del_beacon,
14933 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014934#else
14935 .start_ap = wlan_hdd_cfg80211_start_ap,
14936 .change_beacon = wlan_hdd_cfg80211_change_beacon,
14937 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070014938#endif
14939 .change_bss = wlan_hdd_cfg80211_change_bss,
14940 .add_key = wlan_hdd_cfg80211_add_key,
14941 .get_key = wlan_hdd_cfg80211_get_key,
14942 .del_key = wlan_hdd_cfg80211_del_key,
14943 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014944#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070014945 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014946#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014947 .scan = wlan_hdd_cfg80211_scan,
14948 .connect = wlan_hdd_cfg80211_connect,
14949 .disconnect = wlan_hdd_cfg80211_disconnect,
14950 .join_ibss = wlan_hdd_cfg80211_join_ibss,
14951 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
14952 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
14953 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
14954 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070014955 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
14956 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053014957 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070014958#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14959 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
14960 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
14961 .set_txq_params = wlan_hdd_set_txq_params,
14962#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014963 .get_station = wlan_hdd_cfg80211_get_station,
14964 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
14965 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014966 .add_station = wlan_hdd_cfg80211_add_station,
14967#ifdef FEATURE_WLAN_LFR
14968 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
14969 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
14970 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
14971#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014972#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
14973 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
14974#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014975#ifdef FEATURE_WLAN_TDLS
14976 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
14977 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
14978#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014979#ifdef WLAN_FEATURE_GTK_OFFLOAD
14980 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
14981#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014982#ifdef FEATURE_WLAN_SCAN_PNO
14983 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
14984 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
14985#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014986 .resume = wlan_hdd_cfg80211_resume_wlan,
14987 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014988 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070014989#ifdef WLAN_NL80211_TESTMODE
14990 .testmode_cmd = wlan_hdd_cfg80211_testmode,
14991#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014992 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070014993};
14994