blob: b0723e33263ce164949d68031139328541ef01c0 [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
146
Sunil Duttc69bccb2014-05-26 21:30:20 +0530147#ifdef WLAN_FEATURE_LINK_LAYER_STATS
148/*
149 * Used to allocate the size of 4096 for the link layer stats.
150 * The size of 4096 is considered assuming that all data per
151 * respective event fit with in the limit.Please take a call
152 * on the limit based on the data requirements on link layer
153 * statistics.
154 */
155#define LL_STATS_EVENT_BUF_SIZE 4096
156#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530157#ifdef WLAN_FEATURE_EXTSCAN
158/*
159 * Used to allocate the size of 4096 for the EXTScan NL data.
160 * The size of 4096 is considered assuming that all data per
161 * respective event fit with in the limit.Please take a call
162 * on the limit based on the data requirements.
163 */
164
165#define EXTSCAN_EVENT_BUF_SIZE 4096
166#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
167#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530168
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530169static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700170{
171 WLAN_CIPHER_SUITE_WEP40,
172 WLAN_CIPHER_SUITE_WEP104,
173 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800174#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700175#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
176 WLAN_CIPHER_SUITE_KRK,
177 WLAN_CIPHER_SUITE_CCMP,
178#else
179 WLAN_CIPHER_SUITE_CCMP,
180#endif
181#ifdef FEATURE_WLAN_WAPI
182 WLAN_CIPHER_SUITE_SMS4,
183#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700184#ifdef WLAN_FEATURE_11W
185 WLAN_CIPHER_SUITE_AES_CMAC,
186#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700187};
188
189static inline int is_broadcast_ether_addr(const u8 *addr)
190{
191 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
192 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
193}
194
195static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530196{
Jeff Johnson295189b2012-06-20 16:38:30 -0700197 HDD2GHZCHAN(2412, 1, 0) ,
198 HDD2GHZCHAN(2417, 2, 0) ,
199 HDD2GHZCHAN(2422, 3, 0) ,
200 HDD2GHZCHAN(2427, 4, 0) ,
201 HDD2GHZCHAN(2432, 5, 0) ,
202 HDD2GHZCHAN(2437, 6, 0) ,
203 HDD2GHZCHAN(2442, 7, 0) ,
204 HDD2GHZCHAN(2447, 8, 0) ,
205 HDD2GHZCHAN(2452, 9, 0) ,
206 HDD2GHZCHAN(2457, 10, 0) ,
207 HDD2GHZCHAN(2462, 11, 0) ,
208 HDD2GHZCHAN(2467, 12, 0) ,
209 HDD2GHZCHAN(2472, 13, 0) ,
210 HDD2GHZCHAN(2484, 14, 0) ,
211};
212
Jeff Johnson295189b2012-06-20 16:38:30 -0700213static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
214{
215 HDD2GHZCHAN(2412, 1, 0) ,
216 HDD2GHZCHAN(2437, 6, 0) ,
217 HDD2GHZCHAN(2462, 11, 0) ,
218};
Jeff Johnson295189b2012-06-20 16:38:30 -0700219
220static struct ieee80211_channel hdd_channels_5_GHZ[] =
221{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700222 HDD5GHZCHAN(4920, 240, 0) ,
223 HDD5GHZCHAN(4940, 244, 0) ,
224 HDD5GHZCHAN(4960, 248, 0) ,
225 HDD5GHZCHAN(4980, 252, 0) ,
226 HDD5GHZCHAN(5040, 208, 0) ,
227 HDD5GHZCHAN(5060, 212, 0) ,
228 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700229 HDD5GHZCHAN(5180, 36, 0) ,
230 HDD5GHZCHAN(5200, 40, 0) ,
231 HDD5GHZCHAN(5220, 44, 0) ,
232 HDD5GHZCHAN(5240, 48, 0) ,
233 HDD5GHZCHAN(5260, 52, 0) ,
234 HDD5GHZCHAN(5280, 56, 0) ,
235 HDD5GHZCHAN(5300, 60, 0) ,
236 HDD5GHZCHAN(5320, 64, 0) ,
237 HDD5GHZCHAN(5500,100, 0) ,
238 HDD5GHZCHAN(5520,104, 0) ,
239 HDD5GHZCHAN(5540,108, 0) ,
240 HDD5GHZCHAN(5560,112, 0) ,
241 HDD5GHZCHAN(5580,116, 0) ,
242 HDD5GHZCHAN(5600,120, 0) ,
243 HDD5GHZCHAN(5620,124, 0) ,
244 HDD5GHZCHAN(5640,128, 0) ,
245 HDD5GHZCHAN(5660,132, 0) ,
246 HDD5GHZCHAN(5680,136, 0) ,
247 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800248#ifdef FEATURE_WLAN_CH144
249 HDD5GHZCHAN(5720,144, 0) ,
250#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700251 HDD5GHZCHAN(5745,149, 0) ,
252 HDD5GHZCHAN(5765,153, 0) ,
253 HDD5GHZCHAN(5785,157, 0) ,
254 HDD5GHZCHAN(5805,161, 0) ,
255 HDD5GHZCHAN(5825,165, 0) ,
256};
257
258static struct ieee80211_rate g_mode_rates[] =
259{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530260 HDD_G_MODE_RATETAB(10, 0x1, 0),
261 HDD_G_MODE_RATETAB(20, 0x2, 0),
262 HDD_G_MODE_RATETAB(55, 0x4, 0),
263 HDD_G_MODE_RATETAB(110, 0x8, 0),
264 HDD_G_MODE_RATETAB(60, 0x10, 0),
265 HDD_G_MODE_RATETAB(90, 0x20, 0),
266 HDD_G_MODE_RATETAB(120, 0x40, 0),
267 HDD_G_MODE_RATETAB(180, 0x80, 0),
268 HDD_G_MODE_RATETAB(240, 0x100, 0),
269 HDD_G_MODE_RATETAB(360, 0x200, 0),
270 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700271 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530272};
Jeff Johnson295189b2012-06-20 16:38:30 -0700273
274static struct ieee80211_rate a_mode_rates[] =
275{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530276 HDD_G_MODE_RATETAB(60, 0x10, 0),
277 HDD_G_MODE_RATETAB(90, 0x20, 0),
278 HDD_G_MODE_RATETAB(120, 0x40, 0),
279 HDD_G_MODE_RATETAB(180, 0x80, 0),
280 HDD_G_MODE_RATETAB(240, 0x100, 0),
281 HDD_G_MODE_RATETAB(360, 0x200, 0),
282 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700283 HDD_G_MODE_RATETAB(540, 0x800, 0),
284};
285
286static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
287{
288 .channels = hdd_channels_2_4_GHZ,
289 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
290 .band = IEEE80211_BAND_2GHZ,
291 .bitrates = g_mode_rates,
292 .n_bitrates = g_mode_rates_size,
293 .ht_cap.ht_supported = 1,
294 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
295 | IEEE80211_HT_CAP_GRN_FLD
296 | IEEE80211_HT_CAP_DSSSCCK40
297 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
298 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
299 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
300 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
301 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
302 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
303};
304
Jeff Johnson295189b2012-06-20 16:38:30 -0700305static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
306{
307 .channels = hdd_social_channels_2_4_GHZ,
308 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
309 .band = IEEE80211_BAND_2GHZ,
310 .bitrates = g_mode_rates,
311 .n_bitrates = g_mode_rates_size,
312 .ht_cap.ht_supported = 1,
313 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
314 | IEEE80211_HT_CAP_GRN_FLD
315 | IEEE80211_HT_CAP_DSSSCCK40
316 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
317 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
318 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
319 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
320 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
321 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
322};
Jeff Johnson295189b2012-06-20 16:38:30 -0700323
324static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
325{
326 .channels = hdd_channels_5_GHZ,
327 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
328 .band = IEEE80211_BAND_5GHZ,
329 .bitrates = a_mode_rates,
330 .n_bitrates = a_mode_rates_size,
331 .ht_cap.ht_supported = 1,
332 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
333 | IEEE80211_HT_CAP_GRN_FLD
334 | IEEE80211_HT_CAP_DSSSCCK40
335 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
336 | IEEE80211_HT_CAP_SGI_40
337 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
338 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
339 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
340 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
341 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
342 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
343};
344
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530345/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700346 TX/RX direction for each kind of interface */
347static const struct ieee80211_txrx_stypes
348wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
349 [NL80211_IFTYPE_STATION] = {
350 .tx = 0xffff,
351 .rx = BIT(SIR_MAC_MGMT_ACTION) |
352 BIT(SIR_MAC_MGMT_PROBE_REQ),
353 },
354 [NL80211_IFTYPE_AP] = {
355 .tx = 0xffff,
356 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
357 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
358 BIT(SIR_MAC_MGMT_PROBE_REQ) |
359 BIT(SIR_MAC_MGMT_DISASSOC) |
360 BIT(SIR_MAC_MGMT_AUTH) |
361 BIT(SIR_MAC_MGMT_DEAUTH) |
362 BIT(SIR_MAC_MGMT_ACTION),
363 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700364 [NL80211_IFTYPE_ADHOC] = {
365 .tx = 0xffff,
366 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
367 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
368 BIT(SIR_MAC_MGMT_PROBE_REQ) |
369 BIT(SIR_MAC_MGMT_DISASSOC) |
370 BIT(SIR_MAC_MGMT_AUTH) |
371 BIT(SIR_MAC_MGMT_DEAUTH) |
372 BIT(SIR_MAC_MGMT_ACTION),
373 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700374 [NL80211_IFTYPE_P2P_CLIENT] = {
375 .tx = 0xffff,
376 .rx = BIT(SIR_MAC_MGMT_ACTION) |
377 BIT(SIR_MAC_MGMT_PROBE_REQ),
378 },
379 [NL80211_IFTYPE_P2P_GO] = {
380 /* This is also same as for SoftAP */
381 .tx = 0xffff,
382 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
383 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
384 BIT(SIR_MAC_MGMT_PROBE_REQ) |
385 BIT(SIR_MAC_MGMT_DISASSOC) |
386 BIT(SIR_MAC_MGMT_AUTH) |
387 BIT(SIR_MAC_MGMT_DEAUTH) |
388 BIT(SIR_MAC_MGMT_ACTION),
389 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700390};
391
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800392#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800393static const struct ieee80211_iface_limit
394wlan_hdd_iface_limit[] = {
395 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800396 /* max = 3 ; Our driver create two interfaces during driver init
397 * wlan0 and p2p0 interfaces. p2p0 is considered as station
398 * interface until a group is formed. In JB architecture, once the
399 * group is formed, interface type of p2p0 is changed to P2P GO or
400 * Client.
401 * When supplicant remove the group, it first issue a set interface
402 * cmd to change the mode back to Station. In JB this works fine as
403 * we advertize two station type interface during driver init.
404 * Some vendors create separate interface for P2P GO/Client,
405 * after group formation(Third one). But while group remove
406 * supplicant first tries to change the mode(3rd interface) to STATION
407 * But as we advertized only two sta type interfaces nl80211 was
408 * returning error for the third one which was leading to failure in
409 * delete interface. Ideally while removing the group, supplicant
410 * should not try to change the 3rd interface mode to Station type.
411 * Till we get a fix in wpa_supplicant, we advertize max STA
412 * interface type to 3
413 */
414 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800415 .types = BIT(NL80211_IFTYPE_STATION),
416 },
417 {
418 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700419 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800420 },
421 {
422 .max = 1,
423 .types = BIT(NL80211_IFTYPE_P2P_GO) |
424 BIT(NL80211_IFTYPE_P2P_CLIENT),
425 },
426};
427
428/* By default, only single channel concurrency is allowed */
429static struct ieee80211_iface_combination
430wlan_hdd_iface_combination = {
431 .limits = wlan_hdd_iface_limit,
432 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800433 /*
434 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
435 * and p2p0 interfaces during driver init
436 * Some vendors create separate interface for P2P operations.
437 * wlan0: STA interface
438 * p2p0: P2P Device interface, action frames goes
439 * through this interface.
440 * p2p-xx: P2P interface, After GO negotiation this interface is
441 * created for p2p operations(GO/CLIENT interface).
442 */
443 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800444 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
445 .beacon_int_infra_match = false,
446};
447#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800448
Jeff Johnson295189b2012-06-20 16:38:30 -0700449static struct cfg80211_ops wlan_hdd_cfg80211_ops;
450
451/* Data rate 100KBPS based on IE Index */
452struct index_data_rate_type
453{
454 v_U8_t beacon_rate_index;
455 v_U16_t supported_rate[4];
456};
457
458/* 11B, 11G Rate table include Basic rate and Extended rate
459 The IDX field is the rate index
460 The HI field is the rate when RSSI is strong or being ignored
461 (in this case we report actual rate)
462 The MID field is the rate when RSSI is moderate
463 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
464 The LO field is the rate when RSSI is low
465 (in this case we don't report rates, actual current rate used)
466 */
467static const struct
468{
469 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700470 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700471} supported_data_rate[] =
472{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700473/* IDX HI HM LM LO (RSSI-based index */
474 {2, { 10, 10, 10, 0}},
475 {4, { 20, 20, 10, 0}},
476 {11, { 55, 20, 10, 0}},
477 {12, { 60, 55, 20, 0}},
478 {18, { 90, 55, 20, 0}},
479 {22, {110, 55, 20, 0}},
480 {24, {120, 90, 60, 0}},
481 {36, {180, 120, 60, 0}},
482 {44, {220, 180, 60, 0}},
483 {48, {240, 180, 90, 0}},
484 {66, {330, 180, 90, 0}},
485 {72, {360, 240, 90, 0}},
486 {96, {480, 240, 120, 0}},
487 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700488};
489
490/* MCS Based rate table */
491static struct index_data_rate_type supported_mcs_rate[] =
492{
493/* MCS L20 L40 S20 S40 */
494 {0, {65, 135, 72, 150}},
495 {1, {130, 270, 144, 300}},
496 {2, {195, 405, 217, 450}},
497 {3, {260, 540, 289, 600}},
498 {4, {390, 810, 433, 900}},
499 {5, {520, 1080, 578, 1200}},
500 {6, {585, 1215, 650, 1350}},
501 {7, {650, 1350, 722, 1500}}
502};
503
Leo Chang6f8870f2013-03-26 18:11:36 -0700504#ifdef WLAN_FEATURE_11AC
505
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530506#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700507
508struct index_vht_data_rate_type
509{
510 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530511 v_U16_t supported_VHT80_rate[2];
512 v_U16_t supported_VHT40_rate[2];
513 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700514};
515
516typedef enum
517{
518 DATA_RATE_11AC_MAX_MCS_7,
519 DATA_RATE_11AC_MAX_MCS_8,
520 DATA_RATE_11AC_MAX_MCS_9,
521 DATA_RATE_11AC_MAX_MCS_NA
522} eDataRate11ACMaxMcs;
523
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530524/* SSID broadcast type */
525typedef enum eSSIDBcastType
526{
527 eBCAST_UNKNOWN = 0,
528 eBCAST_NORMAL = 1,
529 eBCAST_HIDDEN = 2,
530} tSSIDBcastType;
531
Leo Chang6f8870f2013-03-26 18:11:36 -0700532/* MCS Based VHT rate table */
533static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
534{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530535/* MCS L80 S80 L40 S40 L20 S40*/
536 {0, {293, 325}, {135, 150}, {65, 72}},
537 {1, {585, 650}, {270, 300}, {130, 144}},
538 {2, {878, 975}, {405, 450}, {195, 217}},
539 {3, {1170, 1300}, {540, 600}, {260, 289}},
540 {4, {1755, 1950}, {810, 900}, {390, 433}},
541 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
542 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
543 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
544 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
545 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700546};
547#endif /* WLAN_FEATURE_11AC */
548
c_hpothu79aab322014-07-14 21:11:01 +0530549/*array index points to MCS and array value points respective rssi*/
550static int rssiMcsTbl[][10] =
551{
552/*MCS 0 1 2 3 4 5 6 7 8 9*/
553 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
554 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
555 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
556};
557
Jeff Johnson295189b2012-06-20 16:38:30 -0700558extern struct net_device_ops net_ops_struct;
559
Leo Chang9056f462013-08-01 19:21:11 -0700560#ifdef WLAN_NL80211_TESTMODE
561enum wlan_hdd_tm_attr
562{
563 WLAN_HDD_TM_ATTR_INVALID = 0,
564 WLAN_HDD_TM_ATTR_CMD = 1,
565 WLAN_HDD_TM_ATTR_DATA = 2,
566 WLAN_HDD_TM_ATTR_TYPE = 3,
567 /* keep last */
568 WLAN_HDD_TM_ATTR_AFTER_LAST,
569 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
570};
571
572enum wlan_hdd_tm_cmd
573{
574 WLAN_HDD_TM_CMD_WLAN_HB = 1,
575};
576
577#define WLAN_HDD_TM_DATA_MAX_LEN 5000
578
579static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
580{
581 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
582 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
583 .len = WLAN_HDD_TM_DATA_MAX_LEN },
584};
585#endif /* WLAN_NL80211_TESTMODE */
586
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800587#ifdef FEATURE_WLAN_CH_AVOID
588/*
589 * FUNCTION: wlan_hdd_send_avoid_freq_event
590 * This is called when wlan driver needs to send vendor specific
591 * avoid frequency range event to userspace
592 */
593int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
594 tHddAvoidFreqList *pAvoidFreqList)
595{
596 struct sk_buff *vendor_event;
597
598 ENTER();
599
600 if (!pHddCtx)
601 {
602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
603 "%s: HDD context is null", __func__);
604 return -1;
605 }
606
607 if (!pAvoidFreqList)
608 {
609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
610 "%s: pAvoidFreqList is null", __func__);
611 return -1;
612 }
613
614 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
615 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530616 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800617 GFP_KERNEL);
618 if (!vendor_event)
619 {
620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
621 "%s: cfg80211_vendor_event_alloc failed", __func__);
622 return -1;
623 }
624
625 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
626 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
627
628 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
629
630 EXIT();
631 return 0;
632}
633#endif /* FEATURE_WLAN_CH_AVOID */
634
Sunil Duttc69bccb2014-05-26 21:30:20 +0530635#ifdef WLAN_FEATURE_LINK_LAYER_STATS
636
637static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
638 struct sk_buff *vendor_event)
639{
640 if (nla_put_u8(vendor_event,
641 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
642 stats->rate.preamble) ||
643 nla_put_u8(vendor_event,
644 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
645 stats->rate.nss) ||
646 nla_put_u8(vendor_event,
647 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
648 stats->rate.bw) ||
649 nla_put_u8(vendor_event,
650 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
651 stats->rate.rateMcsIdx) ||
652 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
653 stats->rate.bitrate ) ||
654 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
655 stats->txMpdu ) ||
656 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
657 stats->rxMpdu ) ||
658 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
659 stats->mpduLost ) ||
660 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
661 stats->retries) ||
662 nla_put_u32(vendor_event,
663 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
664 stats->retriesShort ) ||
665 nla_put_u32(vendor_event,
666 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
667 stats->retriesLong))
668 {
669 hddLog(VOS_TRACE_LEVEL_ERROR,
670 FL("QCA_WLAN_VENDOR_ATTR put fail"));
671 return FALSE;
672 }
673 return TRUE;
674}
675
676static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
677 struct sk_buff *vendor_event)
678{
679 u32 i = 0;
680 struct nlattr *rateInfo;
681 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
682 stats->type) ||
683 nla_put(vendor_event,
684 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
685 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
686 nla_put_u32(vendor_event,
687 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
688 stats->capabilities) ||
689 nla_put_u32(vendor_event,
690 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
691 stats->numRate))
692 {
693 hddLog(VOS_TRACE_LEVEL_ERROR,
694 FL("QCA_WLAN_VENDOR_ATTR put fail"));
695 goto error;
696 }
697
698 rateInfo = nla_nest_start(vendor_event,
699 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
700 for (i = 0; i < stats->numRate; i++)
701 {
702 struct nlattr *rates;
703 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
704 stats->rateStats +
705 (i * sizeof(tSirWifiRateStat)));
706 rates = nla_nest_start(vendor_event, i);
707
708 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
709 {
710 hddLog(VOS_TRACE_LEVEL_ERROR,
711 FL("QCA_WLAN_VENDOR_ATTR put fail"));
712 return FALSE;
713 }
714 nla_nest_end(vendor_event, rates);
715 }
716 nla_nest_end(vendor_event, rateInfo);
717
718 return TRUE;
719error:
720 return FALSE;
721}
722
723static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
724 struct sk_buff *vendor_event)
725{
726 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
727 stats->ac ) ||
728 nla_put_u32(vendor_event,
729 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
730 stats->txMpdu ) ||
731 nla_put_u32(vendor_event,
732 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
733 stats->rxMpdu ) ||
734 nla_put_u32(vendor_event,
735 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
736 stats->txMcast ) ||
737 nla_put_u32(vendor_event,
738 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
739 stats->rxMcast ) ||
740 nla_put_u32(vendor_event,
741 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
742 stats->rxAmpdu ) ||
743 nla_put_u32(vendor_event,
744 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
745 stats->txAmpdu ) ||
746 nla_put_u32(vendor_event,
747 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
748 stats->mpduLost )||
749 nla_put_u32(vendor_event,
750 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
751 stats->retries ) ||
752 nla_put_u32(vendor_event,
753 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
754 stats->retriesShort ) ||
755 nla_put_u32(vendor_event,
756 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
757 stats->retriesLong ) ||
758 nla_put_u32(vendor_event,
759 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
760 stats->contentionTimeMin ) ||
761 nla_put_u32(vendor_event,
762 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
763 stats->contentionTimeMax ) ||
764 nla_put_u32(vendor_event,
765 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
766 stats->contentionTimeAvg ) ||
767 nla_put_u32(vendor_event,
768 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
769 stats->contentionNumSamples ))
770 {
771 hddLog(VOS_TRACE_LEVEL_ERROR,
772 FL("QCA_WLAN_VENDOR_ATTR put fail") );
773 return FALSE;
774 }
775 return TRUE;
776}
777
778static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
779 struct sk_buff *vendor_event)
780{
781 if (nla_put_u32(vendor_event,
782 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
783 nla_put(vendor_event,
784 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
785 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
786 nla_put_u32(vendor_event,
787 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
788 stats->state ) ||
789 nla_put_u32(vendor_event,
790 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
791 stats->roaming ) ||
792 nla_put_u32(vendor_event,
793 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
794 stats->capabilities ) ||
795 nla_put(vendor_event,
796 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
797 strlen(stats->ssid), stats->ssid) ||
798 nla_put(vendor_event,
799 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
800 WNI_CFG_BSSID_LEN, stats->bssid) ||
801 nla_put(vendor_event,
802 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
803 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
804 nla_put(vendor_event,
805 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
806 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
807 )
808 {
809 hddLog(VOS_TRACE_LEVEL_ERROR,
810 FL("QCA_WLAN_VENDOR_ATTR put fail") );
811 return FALSE;
812 }
813 return TRUE;
814}
815
816static v_BOOL_t put_wifi_iface_stats(tpSirWifiIfaceStat pWifiIfaceStat,
817 struct sk_buff *vendor_event)
818{
819 int i = 0;
820 struct nlattr *wmmInfo;
821 if (FALSE == put_wifi_interface_info(
822 &pWifiIfaceStat->info,
823 vendor_event))
824 {
825 hddLog(VOS_TRACE_LEVEL_ERROR,
826 FL("QCA_WLAN_VENDOR_ATTR put fail") );
827 return FALSE;
828
829 }
830
831 if (nla_put_u32(vendor_event,
832 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
833 pWifiIfaceStat->beaconRx) ||
834 nla_put_u32(vendor_event,
835 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
836 pWifiIfaceStat->mgmtRx) ||
837 nla_put_u32(vendor_event,
838 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
839 pWifiIfaceStat->mgmtActionRx) ||
840 nla_put_u32(vendor_event,
841 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
842 pWifiIfaceStat->mgmtActionTx) ||
843 nla_put_u32(vendor_event,
844 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
845 pWifiIfaceStat->rssiMgmt) ||
846 nla_put_u32(vendor_event,
847 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
848 pWifiIfaceStat->rssiData) ||
849 nla_put_u32(vendor_event,
850 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
851 pWifiIfaceStat->rssiAck))
852 {
853 hddLog(VOS_TRACE_LEVEL_ERROR,
854 FL("QCA_WLAN_VENDOR_ATTR put fail"));
855 return FALSE;
856 }
857
858 wmmInfo = nla_nest_start(vendor_event,
859 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
860 for (i = 0; i < WIFI_AC_MAX; i++)
861 {
862 struct nlattr *wmmStats;
863 wmmStats = nla_nest_start(vendor_event, i);
864 if (FALSE == put_wifi_wmm_ac_stat(
865 &pWifiIfaceStat->AccessclassStats[i],
866 vendor_event))
867 {
868 hddLog(VOS_TRACE_LEVEL_ERROR,
869 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
870 return FALSE;
871 }
872
873 nla_nest_end(vendor_event, wmmStats);
874 }
875 nla_nest_end(vendor_event, wmmInfo);
876 return TRUE;
877}
878
879static tSirWifiInterfaceMode
880 hdd_map_device_to_ll_iface_mode ( int deviceMode )
881{
882 switch (deviceMode)
883 {
884 case WLAN_HDD_INFRA_STATION:
885 return WIFI_INTERFACE_STA;
886 case WLAN_HDD_SOFTAP:
887 return WIFI_INTERFACE_SOFTAP;
888 case WLAN_HDD_P2P_CLIENT:
889 return WIFI_INTERFACE_P2P_CLIENT;
890 case WLAN_HDD_P2P_GO:
891 return WIFI_INTERFACE_P2P_GO;
892 case WLAN_HDD_IBSS:
893 return WIFI_INTERFACE_IBSS;
894 default:
895 /* Return Interface Mode as STA for all the unsupported modes */
896 return WIFI_INTERFACE_STA;
897 }
898}
899
900static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
901 tpSirWifiInterfaceInfo pInfo)
902{
903 v_U8_t *staMac = NULL;
904 hdd_station_ctx_t *pHddStaCtx;
905 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
906 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
907
908 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
909
910 vos_mem_copy(pInfo->macAddr,
911 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
912
913 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
914 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
915 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
916 {
917 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
918 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
919 {
920 pInfo->state = WIFI_DISCONNECTED;
921 }
922 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
923 {
924 hddLog(VOS_TRACE_LEVEL_ERROR,
925 "%s: Session ID %d, Connection is in progress", __func__,
926 pAdapter->sessionId);
927 pInfo->state = WIFI_ASSOCIATING;
928 }
929 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
930 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
931 {
932 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
933 hddLog(VOS_TRACE_LEVEL_ERROR,
934 "%s: client " MAC_ADDRESS_STR
935 " is in the middle of WPS/EAPOL exchange.", __func__,
936 MAC_ADDR_ARRAY(staMac));
937 pInfo->state = WIFI_AUTHENTICATING;
938 }
939 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
940 {
941 pInfo->state = WIFI_ASSOCIATED;
942 vos_mem_copy(pInfo->bssid,
943 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
944 vos_mem_copy(pInfo->ssid,
945 pHddStaCtx->conn_info.SSID.SSID.ssId,
946 pHddStaCtx->conn_info.SSID.SSID.length);
947 //NULL Terminate the string.
948 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
949 }
950 }
951 vos_mem_copy(pInfo->countryStr,
952 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
953
954 vos_mem_copy(pInfo->apCountryStr,
955 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
956
957 return TRUE;
958}
959
960/*
961 * hdd_link_layer_process_peer_stats () - This function is called after
962 * receiving Link Layer Peer statistics from FW.This function converts
963 * the firmware data to the NL data and sends the same to the kernel/upper
964 * layers.
965 */
966static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
967 v_VOID_t *pData)
968{
969 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
970 tpSirWifiRateStat pWifiRateStat;
971 tpSirWifiPeerStat pWifiPeerStat;
972 tpSirWifiPeerInfo pWifiPeerInfo;
973 struct nlattr *peerInfo;
974 struct sk_buff *vendor_event;
975 int status, i;
976
977 status = wlan_hdd_validate_context(pHddCtx);
978 if (0 != status)
979 {
980 hddLog(VOS_TRACE_LEVEL_ERROR,
981 FL("HDD context is not valid") );
982 return;
983 }
984
985 pWifiPeerStat = (tpSirWifiPeerStat) pData;
986
987 hddLog(VOS_TRACE_LEVEL_INFO,
988 "LL_STATS_PEER_ALL : numPeers %u",
989 pWifiPeerStat->numPeers);
990 {
991 for (i = 0; i < pWifiPeerStat->numPeers; i++)
992 {
993 pWifiPeerInfo = (tpSirWifiPeerInfo)
994 ((uint8 *)pWifiPeerStat->peerInfo +
995 ( i * sizeof(tSirWifiPeerInfo)));
996
997 hddLog(VOS_TRACE_LEVEL_INFO,
998 " %d) LL_STATS Channel Stats "
999 " Peer Type %u "
1000 " peerMacAddress %pM "
1001 " capabilities 0x%x "
1002 " numRate %u ",
1003 i,
1004 pWifiPeerInfo->type,
1005 pWifiPeerInfo->peerMacAddress,
1006 pWifiPeerInfo->capabilities,
1007 pWifiPeerInfo->numRate);
1008 {
1009 int j;
1010 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1011 {
1012 pWifiRateStat = (tpSirWifiRateStat)
1013 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1014 ( j * sizeof(tSirWifiRateStat)));
1015
1016 hddLog(VOS_TRACE_LEVEL_INFO,
1017 " peer Rate Stats "
1018 " preamble %u "
1019 " nss %u "
1020 " bw %u "
1021 " rateMcsIdx %u "
1022 " reserved %u "
1023 " bitrate %u "
1024 " txMpdu %u "
1025 " rxMpdu %u "
1026 " mpduLost %u "
1027 " retries %u "
1028 " retriesShort %u "
1029 " retriesLong %u",
1030 pWifiRateStat->rate.preamble,
1031 pWifiRateStat->rate.nss,
1032 pWifiRateStat->rate.bw,
1033 pWifiRateStat->rate.rateMcsIdx,
1034 pWifiRateStat->rate.reserved,
1035 pWifiRateStat->rate.bitrate,
1036 pWifiRateStat->txMpdu,
1037 pWifiRateStat->rxMpdu,
1038 pWifiRateStat->mpduLost,
1039 pWifiRateStat->retries,
1040 pWifiRateStat->retriesShort,
1041 pWifiRateStat->retriesLong);
1042 }
1043 }
1044 }
1045 }
1046
1047 /*
1048 * Allocate a size of 4096 for the peer stats comprising
1049 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1050 * sizeof (tSirWifiRateStat).Each field is put with an
1051 * NL attribute.The size of 4096 is considered assuming
1052 * that number of rates shall not exceed beyond 50 with
1053 * the sizeof (tSirWifiRateStat) being 32.
1054 */
1055 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1056 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1057 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1058 GFP_KERNEL);
1059 if (!vendor_event)
1060 {
1061 hddLog(VOS_TRACE_LEVEL_ERROR,
1062 "%s: cfg80211_vendor_event_alloc failed",
1063 __func__);
1064 return;
1065 }
1066 if (nla_put_u32(vendor_event,
1067 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1068 pWifiPeerStat->numPeers))
1069 {
1070 hddLog(VOS_TRACE_LEVEL_ERROR,
1071 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1072 kfree_skb(vendor_event);
1073 return;
1074 }
1075
1076 peerInfo = nla_nest_start(vendor_event,
1077 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
1078
1079 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1080 pWifiPeerStat->peerInfo);
1081
1082 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1083 {
1084 struct nlattr *peers = nla_nest_start(vendor_event, i);
1085 int numRate = pWifiPeerInfo->numRate;
1086
1087 if (FALSE == put_wifi_peer_info(
1088 pWifiPeerInfo, vendor_event))
1089 {
1090 hddLog(VOS_TRACE_LEVEL_ERROR,
1091 "%s: put_wifi_peer_info put fail", __func__);
1092 kfree_skb(vendor_event);
1093 return;
1094 }
1095
1096 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1097 pWifiPeerStat->peerInfo +
1098 (i * sizeof(tSirWifiPeerInfo)) +
1099 (numRate * sizeof (tSirWifiRateStat)));
1100 nla_nest_end(vendor_event, peers);
1101 }
1102 nla_nest_end(vendor_event, peerInfo);
1103 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1104}
1105
1106/*
1107 * hdd_link_layer_process_iface_stats () - This function is called after
1108 * receiving Link Layer Interface statistics from FW.This function converts
1109 * the firmware data to the NL data and sends the same to the kernel/upper
1110 * layers.
1111 */
1112static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1113 v_VOID_t *pData)
1114{
1115 tpSirWifiIfaceStat pWifiIfaceStat;
1116 struct sk_buff *vendor_event;
1117 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1118 int status;
1119
1120 status = wlan_hdd_validate_context(pHddCtx);
1121 if (0 != status)
1122 {
1123 hddLog(VOS_TRACE_LEVEL_ERROR,
1124 FL("HDD context is not valid") );
1125 return;
1126 }
1127 /*
1128 * Allocate a size of 4096 for the interface stats comprising
1129 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1130 * assuming that all these fit with in the limit.Please take
1131 * a call on the limit based on the data requirements on
1132 * interface statistics.
1133 */
1134 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1135 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1136 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1137 GFP_KERNEL);
1138 if (!vendor_event)
1139 {
1140 hddLog(VOS_TRACE_LEVEL_ERROR,
1141 FL("cfg80211_vendor_event_alloc failed") );
1142 return;
1143 }
1144
1145 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1146
1147 hddLog(VOS_TRACE_LEVEL_INFO,
1148 "WMI_LINK_STATS_IFACE Data");
1149
1150 hddLog(VOS_TRACE_LEVEL_INFO,
1151 "LL_STATS_IFACE: "
1152 " Mode %u "
1153 " MAC %pM "
1154 " State %u "
1155 " Roaming %u "
1156 " capabilities 0x%x "
1157 " SSID %s "
1158 " BSSID %pM",
1159 pWifiIfaceStat->info.mode,
1160 pWifiIfaceStat->info.macAddr,
1161 pWifiIfaceStat->info.state,
1162 pWifiIfaceStat->info.roaming,
1163 pWifiIfaceStat->info.capabilities,
1164 pWifiIfaceStat->info.ssid,
1165 pWifiIfaceStat->info.bssid);
1166
1167 hddLog(VOS_TRACE_LEVEL_INFO,
1168 " AP country str: %c%c%c",
1169 pWifiIfaceStat->info.apCountryStr[0],
1170 pWifiIfaceStat->info.apCountryStr[1],
1171 pWifiIfaceStat->info.apCountryStr[2]);
1172
1173
1174 hddLog(VOS_TRACE_LEVEL_INFO,
1175 " Country Str Association: %c%c%c",
1176 pWifiIfaceStat->info.countryStr[0],
1177 pWifiIfaceStat->info.countryStr[1],
1178 pWifiIfaceStat->info.countryStr[2]);
1179
1180 hddLog(VOS_TRACE_LEVEL_INFO,
1181 " beaconRx %u "
1182 " mgmtRx %u "
1183 " mgmtActionRx %u "
1184 " mgmtActionTx %u "
1185 " rssiMgmt %u "
1186 " rssiData %u "
1187 " rssiAck %u",
1188 pWifiIfaceStat->beaconRx,
1189 pWifiIfaceStat->mgmtRx,
1190 pWifiIfaceStat->mgmtActionRx,
1191 pWifiIfaceStat->mgmtActionTx,
1192 pWifiIfaceStat->rssiMgmt,
1193 pWifiIfaceStat->rssiData,
1194 pWifiIfaceStat->rssiAck );
1195
1196
1197 {
1198 int i;
1199 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1200 {
1201 hddLog(VOS_TRACE_LEVEL_INFO,
1202
1203 " %d) LL_STATS IFACE: "
1204 " ac: %u txMpdu: %u "
1205 " rxMpdu: %u txMcast: %u "
1206 " rxMcast: %u rxAmpdu: %u "
1207 " txAmpdu: %u mpduLost: %u "
1208 " retries: %u retriesShort: %u "
1209 " retriesLong: %u contentionTimeMin: %u "
1210 " contentionTimeMax: %u contentionTimeAvg: %u "
1211 " contentionNumSamples: %u",
1212 i,
1213 pWifiIfaceStat->AccessclassStats[i].ac,
1214 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1215 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1216 pWifiIfaceStat->AccessclassStats[i].txMcast,
1217 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1218 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1219 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1220 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1221 pWifiIfaceStat->AccessclassStats[i].retries,
1222 pWifiIfaceStat->
1223 AccessclassStats[i].retriesShort,
1224 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1225 pWifiIfaceStat->
1226 AccessclassStats[i].contentionTimeMin,
1227 pWifiIfaceStat->
1228 AccessclassStats[i].contentionTimeMax,
1229 pWifiIfaceStat->
1230 AccessclassStats[i].contentionTimeAvg,
1231 pWifiIfaceStat->
1232 AccessclassStats[i].contentionNumSamples);
1233
1234 }
1235 }
1236
1237 if (FALSE == hdd_get_interface_info( pAdapter,
1238 &pWifiIfaceStat->info))
1239 {
1240 hddLog(VOS_TRACE_LEVEL_ERROR,
1241 FL("hdd_get_interface_info get fail") );
1242 kfree_skb(vendor_event);
1243 return;
1244 }
1245
1246 if (FALSE == put_wifi_iface_stats( pWifiIfaceStat,
1247 vendor_event))
1248 {
1249 hddLog(VOS_TRACE_LEVEL_ERROR,
1250 FL("put_wifi_iface_stats fail") );
1251 kfree_skb(vendor_event);
1252 return;
1253 }
1254 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1255}
1256
1257/*
1258 * hdd_link_layer_process_radio_stats () - This function is called after
1259 * receiving Link Layer Radio statistics from FW.This function converts
1260 * the firmware data to the NL data and sends the same to the kernel/upper
1261 * layers.
1262 */
1263static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1264 v_VOID_t *pData)
1265{
1266 int status, i;
1267 tpSirWifiRadioStat pWifiRadioStat;
1268 tpSirWifiChannelStats pWifiChannelStats;
1269 struct sk_buff *vendor_event;
1270 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1271 struct nlattr *chList;
1272
1273 status = wlan_hdd_validate_context(pHddCtx);
1274 if (0 != status)
1275 {
1276 hddLog(VOS_TRACE_LEVEL_ERROR,
1277 FL("HDD context is not valid") );
1278 return;
1279 }
1280 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1281
1282 hddLog(VOS_TRACE_LEVEL_INFO,
1283 "LL_STATS_RADIO"
1284 " radio is %d onTime is %u "
1285 " txTime is %u rxTime is %u "
1286 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301287 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301288 " onTimePnoScan is %u onTimeHs20 is %u "
1289 " numChannels is %u",
1290 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1291 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1292 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301293 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301294 pWifiRadioStat->onTimeRoamScan,
1295 pWifiRadioStat->onTimePnoScan,
1296 pWifiRadioStat->onTimeHs20,
1297 pWifiRadioStat->numChannels);
1298 /*
1299 * Allocate a size of 4096 for the Radio stats comprising
1300 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1301 * (tSirWifiChannelStats).Each channel data is put with an
1302 * NL attribute.The size of 4096 is considered assuming that
1303 * number of channels shall not exceed beyond 60 with the
1304 * sizeof (tSirWifiChannelStats) being 24 bytes.
1305 */
1306
1307 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1308 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1309 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1310 GFP_KERNEL);
1311
1312 if (!vendor_event)
1313 {
1314 hddLog(VOS_TRACE_LEVEL_ERROR,
1315 FL("cfg80211_vendor_event_alloc failed") );
1316 return;
1317 }
1318
1319 if (nla_put_u32(vendor_event,
1320 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1321 pWifiRadioStat->radio) ||
1322 nla_put_u32(vendor_event,
1323 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1324 pWifiRadioStat->onTime) ||
1325 nla_put_u32(vendor_event,
1326 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1327 pWifiRadioStat->txTime) ||
1328 nla_put_u32(vendor_event,
1329 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1330 pWifiRadioStat->rxTime) ||
1331 nla_put_u32(vendor_event,
1332 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1333 pWifiRadioStat->onTimeScan) ||
1334 nla_put_u32(vendor_event,
1335 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1336 pWifiRadioStat->onTimeNbd) ||
1337 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301338 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1339 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301340 nla_put_u32(vendor_event,
1341 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1342 pWifiRadioStat->onTimeRoamScan) ||
1343 nla_put_u32(vendor_event,
1344 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1345 pWifiRadioStat->onTimePnoScan) ||
1346 nla_put_u32(vendor_event,
1347 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1348 pWifiRadioStat->onTimeHs20) ||
1349 nla_put_u32(vendor_event,
1350 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1351 pWifiRadioStat->numChannels))
1352 {
1353 hddLog(VOS_TRACE_LEVEL_ERROR,
1354 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1355 kfree_skb(vendor_event);
1356 return ;
1357 }
1358
1359 chList = nla_nest_start(vendor_event,
1360 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
1361 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1362 {
1363 struct nlattr *chInfo;
1364
1365 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1366 pWifiRadioStat->channels +
1367 (i * sizeof(tSirWifiChannelStats)));
1368
1369 hddLog(VOS_TRACE_LEVEL_INFO,
1370 " %d) Channel Info"
1371 " width is %u "
1372 " CenterFreq %u "
1373 " CenterFreq0 %u "
1374 " CenterFreq1 %u "
1375 " onTime %u "
1376 " ccaBusyTime %u",
1377 i,
1378 pWifiChannelStats->channel.width,
1379 pWifiChannelStats->channel.centerFreq,
1380 pWifiChannelStats->channel.centerFreq0,
1381 pWifiChannelStats->channel.centerFreq1,
1382 pWifiChannelStats->onTime,
1383 pWifiChannelStats->ccaBusyTime);
1384
1385
1386 chInfo = nla_nest_start(vendor_event, i);
1387
1388 if (nla_put_u32(vendor_event,
1389 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1390 pWifiChannelStats->channel.width) ||
1391 nla_put_u32(vendor_event,
1392 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1393 pWifiChannelStats->channel.centerFreq) ||
1394 nla_put_u32(vendor_event,
1395 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1396 pWifiChannelStats->channel.centerFreq0) ||
1397 nla_put_u32(vendor_event,
1398 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1399 pWifiChannelStats->channel.centerFreq1) ||
1400 nla_put_u32(vendor_event,
1401 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1402 pWifiChannelStats->onTime) ||
1403 nla_put_u32(vendor_event,
1404 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1405 pWifiChannelStats->ccaBusyTime))
1406 {
1407 hddLog(VOS_TRACE_LEVEL_ERROR,
1408 FL("cfg80211_vendor_event_alloc failed") );
1409 kfree_skb(vendor_event);
1410 return ;
1411 }
1412 nla_nest_end(vendor_event, chInfo);
1413 }
1414 nla_nest_end(vendor_event, chList);
1415
1416 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1417 return;
1418}
1419
1420/*
1421 * hdd_link_layer_stats_ind_callback () - This function is called after
1422 * receiving Link Layer indications from FW.This callback converts the firmware
1423 * data to the NL data and send the same to the kernel/upper layers.
1424 */
1425static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1426 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301427 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301428{
Dino Mycled3d50022014-07-07 12:58:25 +05301429 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1430 hdd_adapter_t *pAdapter = NULL;
1431 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301432 int status;
1433
1434 status = wlan_hdd_validate_context(pHddCtx);
1435
1436 if (0 != status)
1437 {
1438 hddLog(VOS_TRACE_LEVEL_ERROR,
1439 FL("HDD context is not valid"));
1440 return;
1441 }
1442
Dino Mycled3d50022014-07-07 12:58:25 +05301443
1444
1445 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1446 if (NULL == pAdapter)
1447 {
1448 hddLog(VOS_TRACE_LEVEL_ERROR,
1449 FL(" MAC address %pM does not exist with host"),
1450 macAddr);
1451 return;
1452 }
1453
Sunil Duttc69bccb2014-05-26 21:30:20 +05301454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301455 "%s: Interface: %s LLStats indType: %d", __func__,
1456 pAdapter->dev->name, indType);
1457
Sunil Duttc69bccb2014-05-26 21:30:20 +05301458 switch (indType)
1459 {
1460 case SIR_HAL_LL_STATS_RESULTS_RSP:
1461 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301462 hddLog(VOS_TRACE_LEVEL_INFO,
1463 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1464 hddLog(VOS_TRACE_LEVEL_INFO,
1465 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1466 linkLayerStatsResults->paramId);
1467 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301468 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1469 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301470 hddLog(VOS_TRACE_LEVEL_INFO,
1471 "LL_STATS RESULTS RESPONSE respId = %u",
1472 linkLayerStatsResults->respId);
1473 hddLog(VOS_TRACE_LEVEL_INFO,
1474 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1475 linkLayerStatsResults->moreResultToFollow);
1476 hddLog(VOS_TRACE_LEVEL_INFO,
1477 "LL_STATS RESULTS RESPONSE result = %p",
1478 linkLayerStatsResults->result);
1479 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1480 {
1481 hdd_link_layer_process_radio_stats(pAdapter,
1482 (v_VOID_t *)linkLayerStatsResults->result);
1483 }
1484 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1485 {
1486 hdd_link_layer_process_iface_stats(pAdapter,
1487 (v_VOID_t *)linkLayerStatsResults->result);
1488 }
1489 else if ( linkLayerStatsResults->paramId &
1490 WMI_LINK_STATS_ALL_PEER )
1491 {
1492 hdd_link_layer_process_peer_stats(pAdapter,
1493 (v_VOID_t *)linkLayerStatsResults->result);
1494 } /* WMI_LINK_STATS_ALL_PEER */
1495 else
1496 {
1497 hddLog(VOS_TRACE_LEVEL_ERROR,
1498 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1499 }
1500
1501 break;
1502 }
1503 default:
1504 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1505 break;
1506 }
1507 return;
1508}
1509
1510const struct
1511nla_policy
1512qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1513{
1514 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1515 { .type = NLA_U32 },
1516 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1517 { .type = NLA_U32 },
1518};
1519
1520static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1521 struct wireless_dev *wdev,
1522 void *data,
1523 int data_len)
1524{
1525 int status;
1526 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301527 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301528 struct net_device *dev = wdev->netdev;
1529 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1530 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1531
1532 status = wlan_hdd_validate_context(pHddCtx);
1533 if (0 != status)
1534 {
1535 hddLog(VOS_TRACE_LEVEL_ERROR,
1536 FL("HDD context is not valid"));
1537 return -EINVAL;
1538 }
1539
1540 if (NULL == pAdapter)
1541 {
1542 hddLog(VOS_TRACE_LEVEL_ERROR,
1543 FL("HDD adapter is Null"));
1544 return -ENODEV;
1545 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301546 /* check the LLStats Capability */
1547 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1548 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1549 {
1550 hddLog(VOS_TRACE_LEVEL_ERROR,
1551 FL("Link Layer Statistics not supported by Firmware"));
1552 return -EINVAL;
1553 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301554
1555 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1556 (struct nlattr *)data,
1557 data_len, qca_wlan_vendor_ll_set_policy))
1558 {
1559 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1560 return -EINVAL;
1561 }
1562 if (!tb_vendor
1563 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1564 {
1565 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1566 return -EINVAL;
1567 }
1568 if (!tb_vendor[
1569 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1570 {
1571 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1572 return -EINVAL;
1573 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301574 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301575 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301576
Dino Mycledf0a5d92014-07-04 09:41:55 +05301577 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301578 nla_get_u32(
1579 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1580
Dino Mycledf0a5d92014-07-04 09:41:55 +05301581 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301582 nla_get_u32(
1583 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1584
Dino Mycled3d50022014-07-07 12:58:25 +05301585 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1586 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301587
1588
1589 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301590 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301591 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301592 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301593 hddLog(VOS_TRACE_LEVEL_INFO,
1594 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301595 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301596 hddLog(VOS_TRACE_LEVEL_INFO,
1597 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301598 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301599
1600 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1601 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301602 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301603 {
1604 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1605 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301606 return -EINVAL;
1607
1608 }
1609 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301610 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301611 {
1612 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1613 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301614 return -EINVAL;
1615 }
1616
1617 pAdapter->isLinkLayerStatsSet = 1;
1618
1619 return 0;
1620}
1621
1622const struct
1623nla_policy
1624qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1625{
1626 /* Unsigned 32bit value provided by the caller issuing the GET stats
1627 * command. When reporting
1628 * the stats results, the driver uses the same value to indicate
1629 * which GET request the results
1630 * correspond to.
1631 */
1632 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1633
1634 /* Unsigned 32bit value . bit mask to identify what statistics are
1635 requested for retrieval */
1636 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1637};
1638
1639static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1640 struct wireless_dev *wdev,
1641 void *data,
1642 int data_len)
1643{
1644 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1645 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301646 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301647 struct net_device *dev = wdev->netdev;
1648 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1649 int status;
1650
1651 status = wlan_hdd_validate_context(pHddCtx);
1652 if (0 != status)
1653 {
1654 hddLog(VOS_TRACE_LEVEL_ERROR,
1655 FL("HDD context is not valid"));
1656 return -EINVAL ;
1657 }
1658
1659 if (NULL == pAdapter)
1660 {
1661 hddLog(VOS_TRACE_LEVEL_FATAL,
1662 "%s: HDD adapter is Null", __func__);
1663 return -ENODEV;
1664 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301665 /* check the LLStats Capability */
1666 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1667 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1668 {
1669 hddLog(VOS_TRACE_LEVEL_ERROR,
1670 FL("Link Layer Statistics not supported by Firmware"));
1671 return -EINVAL;
1672 }
1673
Sunil Duttc69bccb2014-05-26 21:30:20 +05301674
1675 if (!pAdapter->isLinkLayerStatsSet)
1676 {
1677 hddLog(VOS_TRACE_LEVEL_FATAL,
1678 "%s: isLinkLayerStatsSet : %d",
1679 __func__, pAdapter->isLinkLayerStatsSet);
1680 return -EINVAL;
1681 }
1682
1683 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1684 (struct nlattr *)data,
1685 data_len, qca_wlan_vendor_ll_get_policy))
1686 {
1687 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1688 return -EINVAL;
1689 }
1690
1691 if (!tb_vendor
1692 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1693 {
1694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1695 return -EINVAL;
1696 }
1697
1698 if (!tb_vendor
1699 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1700 {
1701 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1702 return -EINVAL;
1703 }
1704
Sunil Duttc69bccb2014-05-26 21:30:20 +05301705
Dino Mycledf0a5d92014-07-04 09:41:55 +05301706 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301707 nla_get_u32( tb_vendor[
1708 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301709 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301710 nla_get_u32( tb_vendor[
1711 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1712
Dino Mycled3d50022014-07-07 12:58:25 +05301713 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1714 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301715
1716 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301717 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301718 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301719 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301720 hddLog(VOS_TRACE_LEVEL_INFO,
1721 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301722 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301723
1724 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301725 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301726 {
1727 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1728 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301729 return -EINVAL;
1730 }
1731 return 0;
1732}
1733
1734const struct
1735nla_policy
1736qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1737{
1738 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1739 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1740 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1741 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1742};
1743
1744static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1745 struct wireless_dev *wdev,
1746 void *data,
1747 int data_len)
1748{
1749 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1750 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301751 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301752 struct net_device *dev = wdev->netdev;
1753 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1754 u32 statsClearReqMask;
1755 u8 stopReq;
1756 int status;
1757
1758 status = wlan_hdd_validate_context(pHddCtx);
1759 if (0 != status)
1760 {
1761 hddLog(VOS_TRACE_LEVEL_ERROR,
1762 FL("HDD context is not valid"));
1763 return -EINVAL;
1764 }
1765
1766 if (NULL == pAdapter)
1767 {
1768 hddLog(VOS_TRACE_LEVEL_FATAL,
1769 "%s: HDD adapter is Null", __func__);
1770 return -ENODEV;
1771 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301772 /* check the LLStats Capability */
1773 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1774 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1775 {
1776 hddLog(VOS_TRACE_LEVEL_ERROR,
1777 FL("Enable LLStats Capability"));
1778 return -EINVAL;
1779 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301780
1781 if (!pAdapter->isLinkLayerStatsSet)
1782 {
1783 hddLog(VOS_TRACE_LEVEL_FATAL,
1784 "%s: isLinkLayerStatsSet : %d",
1785 __func__, pAdapter->isLinkLayerStatsSet);
1786 return -EINVAL;
1787 }
1788
1789 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1790 (struct nlattr *)data,
1791 data_len, qca_wlan_vendor_ll_clr_policy))
1792 {
1793 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1794 return -EINVAL;
1795 }
1796
1797 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
1798
1799 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
1800 {
1801 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
1802 return -EINVAL;
1803
1804 }
1805
Sunil Duttc69bccb2014-05-26 21:30:20 +05301806
Dino Mycledf0a5d92014-07-04 09:41:55 +05301807 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301808 nla_get_u32(
1809 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
1810
Dino Mycledf0a5d92014-07-04 09:41:55 +05301811 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301812 nla_get_u8(
1813 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
1814
1815 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301816 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301817
Dino Mycled3d50022014-07-07 12:58:25 +05301818 vos_mem_copy(linkLayerStatsClearReq.macAddr,
1819 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301820
1821 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301822 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301823 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301824 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301825 hddLog(VOS_TRACE_LEVEL_INFO,
1826 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301827 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301828 hddLog(VOS_TRACE_LEVEL_INFO,
1829 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301830 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301831
1832 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301833 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301834 {
1835 struct sk_buff *temp_skbuff;
1836 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
1837 2 * sizeof(u32) +
1838 NLMSG_HDRLEN);
1839
1840 if (temp_skbuff != NULL)
1841 {
1842
1843 if (nla_put_u32(temp_skbuff,
1844 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
1845 statsClearReqMask) ||
1846 nla_put_u32(temp_skbuff,
1847 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
1848 stopReq))
1849 {
1850 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
1851 kfree_skb(temp_skbuff);
1852 return -EINVAL;
1853 }
1854 /* If the ask is to stop the stats collection as part of clear
1855 * (stopReq = 1) , ensure that no further requests of get
1856 * go to the firmware by having isLinkLayerStatsSet set to 0.
1857 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301858 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05301859 * case the firmware is just asked to clear the statistics.
1860 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05301861 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301862 pAdapter->isLinkLayerStatsSet = 0;
1863 return cfg80211_vendor_cmd_reply(temp_skbuff);
1864 }
1865 return -ENOMEM;
1866 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301867 return -EINVAL;
1868}
1869#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
1870
Dino Mycle6fb96c12014-06-10 11:52:40 +05301871#ifdef WLAN_FEATURE_EXTSCAN
1872static const struct nla_policy
1873wlan_hdd_extscan_config_policy
1874 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
1875{
1876 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
1877 { .type = NLA_U32 },
1878 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
1879 { .type = NLA_U32 },
1880 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
1881 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
1882 { .type = NLA_U32 },
1883 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
1884 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
1885
1886 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
1887 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
1888 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
1889 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
1890 { .type = NLA_U8 },
1891 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
1892 { .type = NLA_U32 },
1893 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
1894 { .type = NLA_U32 },
1895 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
1896 { .type = NLA_U32 },
1897 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
1898 { .type = NLA_U8 },
1899 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
1900 { .type = NLA_U8 },
1901 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
1902 { .type = NLA_U8 },
1903
1904 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
1905 { .type = NLA_U32 },
1906 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
1907 { .type = NLA_UNSPEC },
1908 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
1909 { .type = NLA_S32 },
1910 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
1911 { .type = NLA_S32 },
1912 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
1913 { .type = NLA_U32 },
1914 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
1915 { .type = NLA_U32 },
1916 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
1917 { .type = NLA_U32 },
1918 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
1919 = { .type = NLA_U32 },
1920 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
1921 { .type = NLA_U32 },
1922 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
1923 NLA_U32 },
1924};
1925
1926static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
1927{
1928 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
1929 struct sk_buff *skb = NULL;
1930 tpSirEXTScanCapabilitiesEvent pData =
1931 (tpSirEXTScanCapabilitiesEvent) pMsg;
1932
1933 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
1934 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
1935 "or pData(%p) is null"), pData);
1936 return;
1937 }
1938
1939 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1940 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1941 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
1942 GFP_KERNEL);
1943
1944 if (!skb) {
1945 hddLog(VOS_TRACE_LEVEL_ERROR,
1946 FL("cfg80211_vendor_event_alloc failed"));
1947 return;
1948 }
1949
1950 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
1951 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
1952 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
1953 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
1954 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
1955 pData->maxRssiSampleSize);
1956 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
1957 pData->maxScanReportingThreshold);
1958 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
1959 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
1960 pData->maxSignificantWifiChangeAPs);
1961 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
1962 pData->maxBsidHistoryEntries);
1963
1964 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
1965 pData->requestId) ||
1966 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
1967 nla_put_u32(skb,
1968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
1969 pData->scanCacheSize) ||
1970 nla_put_u32(skb,
1971 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
1972 pData->scanBuckets) ||
1973 nla_put_u32(skb,
1974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
1975 pData->maxApPerScan) ||
1976 nla_put_u32(skb,
1977 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
1978 pData->maxRssiSampleSize) ||
1979 nla_put_u32(skb,
1980 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
1981 pData->maxScanReportingThreshold) ||
1982 nla_put_u32(skb,
1983 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
1984 pData->maxHotlistAPs) ||
1985 nla_put_u32(skb,
1986 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
1987 pData->maxSignificantWifiChangeAPs) ||
1988 nla_put_u32(skb,
1989 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
1990 pData->maxBsidHistoryEntries)) {
1991 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
1992 goto nla_put_failure;
1993 }
1994
1995 cfg80211_vendor_event(skb, GFP_KERNEL);
1996 return;
1997
1998nla_put_failure:
1999 kfree_skb(skb);
2000 return;
2001}
2002
2003
2004static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2005{
2006 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2007 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2008 struct sk_buff *skb = NULL;
2009 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2010
2011
2012 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2013 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2014 "or pData(%p) is null"), pData);
2015 return;
2016 }
2017
2018 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2019 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2020 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2021 GFP_KERNEL);
2022
2023 if (!skb) {
2024 hddLog(VOS_TRACE_LEVEL_ERROR,
2025 FL("cfg80211_vendor_event_alloc failed"));
2026 return;
2027 }
2028 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2029 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2030 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2031
2032 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2033 pData->requestId) ||
2034 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2035 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2036 goto nla_put_failure;
2037 }
2038
2039 /*
2040 * Store the Request ID for comparing with the requestID obtained
2041 * in other requests.HDD shall return a failure is the extscan_stop
2042 * request is issued with a different requestId as that of the
2043 * extscan_start request. Also, This requestId shall be used while
2044 * indicating the full scan results to the upper layers.
2045 * The requestId is stored with the assumption that the firmware
2046 * shall return the ext scan start request's requestId in ext scan
2047 * start response.
2048 */
2049 if (pData->status == 0)
2050 pMac->sme.extScanStartReqId = pData->requestId;
2051
2052
2053 cfg80211_vendor_event(skb, GFP_KERNEL);
2054 return;
2055
2056nla_put_failure:
2057 kfree_skb(skb);
2058 return;
2059}
2060
2061
2062static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2063{
2064 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2065 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2066 struct sk_buff *skb = NULL;
2067
2068 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2069 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2070 "or pData(%p) is null"), pData);
2071 return;
2072 }
2073
2074 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2075 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2076 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2077 GFP_KERNEL);
2078
2079 if (!skb) {
2080 hddLog(VOS_TRACE_LEVEL_ERROR,
2081 FL("cfg80211_vendor_event_alloc failed"));
2082 return;
2083 }
2084 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2085 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2086
2087 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2088 pData->requestId) ||
2089 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2090 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2091 goto nla_put_failure;
2092 }
2093
2094 cfg80211_vendor_event(skb, GFP_KERNEL);
2095 return;
2096
2097nla_put_failure:
2098 kfree_skb(skb);
2099 return;
2100}
2101
2102
2103static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2104 void *pMsg)
2105{
2106 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2107 struct sk_buff *skb = NULL;
2108 tpSirEXTScanSetBssidHotListRspParams pData =
2109 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2110
2111 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2112 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2113 "or pData(%p) is null"), pData);
2114 return;
2115 }
2116 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2117 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2118 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2119 GFP_KERNEL);
2120
2121 if (!skb) {
2122 hddLog(VOS_TRACE_LEVEL_ERROR,
2123 FL("cfg80211_vendor_event_alloc failed"));
2124 return;
2125 }
2126 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2127 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2128 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2129
2130 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2131 pData->requestId) ||
2132 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2133 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2134 goto nla_put_failure;
2135 }
2136
2137 cfg80211_vendor_event(skb, GFP_KERNEL);
2138 return;
2139
2140nla_put_failure:
2141 kfree_skb(skb);
2142 return;
2143}
2144
2145static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2146 void *pMsg)
2147{
2148 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2149 struct sk_buff *skb = NULL;
2150 tpSirEXTScanResetBssidHotlistRspParams pData =
2151 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2152
2153 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2154 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2155 "or pData(%p) is null"), pData);
2156 return;
2157 }
2158
2159 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2160 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2161 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2162 GFP_KERNEL);
2163
2164 if (!skb) {
2165 hddLog(VOS_TRACE_LEVEL_ERROR,
2166 FL("cfg80211_vendor_event_alloc failed"));
2167 return;
2168 }
2169 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2170 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2171
2172 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2173 pData->requestId) ||
2174 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2175 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2176 goto nla_put_failure;
2177 }
2178
2179 cfg80211_vendor_event(skb, GFP_KERNEL);
2180 return;
2181
2182nla_put_failure:
2183 kfree_skb(skb);
2184 return;
2185}
2186
2187
2188static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2189 void *pMsg)
2190{
2191 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2192 struct sk_buff *skb = NULL;
2193 tpSirEXTScanSetSignificantChangeRspParams pData =
2194 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2195
2196 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2197 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2198 "or pData(%p) is null"), pData);
2199 return;
2200 }
2201
2202 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2203 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2204 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2205 GFP_KERNEL);
2206
2207 if (!skb) {
2208 hddLog(VOS_TRACE_LEVEL_ERROR,
2209 FL("cfg80211_vendor_event_alloc failed"));
2210 return;
2211 }
2212 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2213 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2214 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2215
2216 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2217 pData->requestId) ||
2218 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2219 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2220 goto nla_put_failure;
2221 }
2222
2223 cfg80211_vendor_event(skb, GFP_KERNEL);
2224 return;
2225
2226nla_put_failure:
2227 kfree_skb(skb);
2228 return;
2229}
2230
2231
2232static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2233 void *pMsg)
2234{
2235 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2236 struct sk_buff *skb = NULL;
2237 tpSirEXTScanResetSignificantChangeRspParams pData =
2238 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2239
2240 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2241 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2242 "or pData(%p) is null"), pData);
2243 return;
2244 }
2245
2246 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2247 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2248 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2249 GFP_KERNEL);
2250
2251 if (!skb) {
2252 hddLog(VOS_TRACE_LEVEL_ERROR,
2253 FL("cfg80211_vendor_event_alloc failed"));
2254 return;
2255 }
2256 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2257 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2258 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2259
2260 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2261 pData->requestId) ||
2262 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2263 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2264 goto nla_put_failure;
2265 }
2266
2267 cfg80211_vendor_event(skb, GFP_KERNEL);
2268 return;
2269
2270nla_put_failure:
2271 kfree_skb(skb);
2272 return;
2273}
2274
2275static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2276 void *pMsg)
2277{
2278 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2279 struct sk_buff *skb = NULL;
2280 tANI_U32 i = 0, j, resultsPerEvent;
2281 tANI_S32 totalResults;
2282 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2283 tpSirWifiScanResult pSirWifiScanResult;
2284
2285 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2286 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2287 "or pData(%p) is null"), pData);
2288 return;
2289 }
2290 totalResults = pData->numOfAps;
2291 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2292 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2293 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2294
2295 do{
2296 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2297 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2298 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2299
2300 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2301 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2302 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2303 GFP_KERNEL);
2304
2305 if (!skb) {
2306 hddLog(VOS_TRACE_LEVEL_ERROR,
2307 FL("cfg80211_vendor_event_alloc failed"));
2308 return;
2309 }
2310
2311 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2312
2313 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2314 pData->requestId) ||
2315 nla_put_u32(skb,
2316 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2317 resultsPerEvent)) {
2318 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2319 goto fail;
2320 }
2321 if (nla_put_u8(skb,
2322 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2323 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2324 {
2325 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2326 goto fail;
2327 }
2328
2329 if (resultsPerEvent) {
2330 struct nlattr *aps;
2331
2332 aps = nla_nest_start(skb,
2333 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2334 if (!aps)
2335 {
2336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2337 goto fail;
2338 }
2339
2340 for (j = 0; j < resultsPerEvent; j++, i++) {
2341 struct nlattr *ap;
2342 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2343 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2344
2345 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2346 "Ssid (%s)"
2347 "Bssid: %pM "
2348 "Channel (%u)"
2349 "Rssi (%d)"
2350 "RTT (%u)"
2351 "RTT_SD (%u)",
2352 i,
2353 pSirWifiScanResult->ts,
2354 pSirWifiScanResult->ssid,
2355 pSirWifiScanResult->bssid,
2356 pSirWifiScanResult->channel,
2357 pSirWifiScanResult->rssi,
2358 pSirWifiScanResult->rtt,
2359 pSirWifiScanResult->rtt_sd);
2360
2361 ap = nla_nest_start(skb, j + 1);
2362 if (!ap)
2363 {
2364 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2365 goto fail;
2366 }
2367
2368 if (nla_put_u64(skb,
2369 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2370 pSirWifiScanResult->ts) )
2371 {
2372 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2373 goto fail;
2374 }
2375 if (nla_put(skb,
2376 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2377 sizeof(pSirWifiScanResult->ssid),
2378 pSirWifiScanResult->ssid) )
2379 {
2380 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2381 goto fail;
2382 }
2383 if (nla_put(skb,
2384 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2385 sizeof(pSirWifiScanResult->bssid),
2386 pSirWifiScanResult->bssid) )
2387 {
2388 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2389 goto fail;
2390 }
2391 if (nla_put_u32(skb,
2392 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2393 pSirWifiScanResult->channel) )
2394 {
2395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2396 goto fail;
2397 }
2398 if (nla_put_u32(skb,
2399 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2400 pSirWifiScanResult->rssi) )
2401 {
2402 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2403 goto fail;
2404 }
2405 if (nla_put_u32(skb,
2406 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2407 pSirWifiScanResult->rtt) )
2408 {
2409 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2410 goto fail;
2411 }
2412 if (nla_put_u32(skb,
2413 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2414 pSirWifiScanResult->rtt_sd))
2415 {
2416 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2417 goto fail;
2418 }
2419
2420 nla_nest_end(skb, ap);
2421 }
2422 nla_nest_end(skb, aps);
2423
2424 }
2425 cfg80211_vendor_event(skb, GFP_KERNEL);
2426 } while (totalResults > 0);
2427
2428 return;
2429fail:
2430 kfree_skb(skb);
2431 return;
2432}
2433
2434static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2435 void *pMsg)
2436{
2437 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2438 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2439 struct sk_buff *skb = NULL;
2440 tANI_U32 i;
2441
2442 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2443 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2444 "or pData(%p) is null"), pData);
2445 return;
2446 }
2447
2448 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2449 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2450 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2451 GFP_KERNEL);
2452
2453 if (!skb) {
2454 hddLog(VOS_TRACE_LEVEL_ERROR,
2455 FL("cfg80211_vendor_event_alloc failed"));
2456 return;
2457 }
2458 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2459 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2460 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2461 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2462
2463 for (i = 0; i < pData->numOfAps; i++) {
2464 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2465 "Ssid (%s) "
2466 "Bssid (" MAC_ADDRESS_STR ") "
2467 "Channel (%u) "
2468 "Rssi (%d) "
2469 "RTT (%u) "
2470 "RTT_SD (%u) ",
2471 i,
2472 pData->ap[i].ts,
2473 pData->ap[i].ssid,
2474 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2475 pData->ap[i].channel,
2476 pData->ap[i].rssi,
2477 pData->ap[i].rtt,
2478 pData->ap[i].rtt_sd);
2479 }
2480
2481 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2482 pData->requestId) ||
2483 nla_put_u32(skb,
2484 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2485 pData->numOfAps)) {
2486 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2487 goto fail;
2488 }
2489 if (pData->numOfAps) {
2490 struct nlattr *aps;
2491
2492 aps = nla_nest_start(skb,
2493 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2494 if (!aps)
2495 goto fail;
2496
2497 for (i = 0; i < pData->numOfAps; i++) {
2498 struct nlattr *ap;
2499
2500 ap = nla_nest_start(skb, i + 1);
2501 if (!ap)
2502 goto fail;
2503
2504 if (nla_put_u64(skb,
2505 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2506 pData->ap[i].ts) ||
2507 nla_put(skb,
2508 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2509 sizeof(pData->ap[i].ssid),
2510 pData->ap[i].ssid) ||
2511 nla_put(skb,
2512 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2513 sizeof(pData->ap[i].bssid),
2514 pData->ap[i].bssid) ||
2515 nla_put_u32(skb,
2516 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2517 pData->ap[i].channel) ||
2518 nla_put_s32(skb,
2519 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2520 pData->ap[i].rssi) ||
2521 nla_put_u32(skb,
2522 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2523 pData->ap[i].rtt) ||
2524 nla_put_u32(skb,
2525 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2526 pData->ap[i].rtt_sd))
2527 goto fail;
2528
2529 nla_nest_end(skb, ap);
2530 }
2531 nla_nest_end(skb, aps);
2532
2533 if (nla_put_u8(skb,
2534 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2535 pData->moreData))
2536 goto fail;
2537 }
2538
2539 cfg80211_vendor_event(skb, GFP_KERNEL);
2540 return;
2541
2542fail:
2543 kfree_skb(skb);
2544 return;
2545
2546}
2547static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2548 void *pMsg)
2549{
2550 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2551 struct sk_buff *skb = NULL;
2552 tANI_U32 i, j;
2553 tpSirWifiSignificantChangeEvent pData =
2554 (tpSirWifiSignificantChangeEvent) pMsg;
2555
2556 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2557 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2558 "or pData(%p) is null"), pData);
2559 return;
2560 }
2561 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2562 EXTSCAN_EVENT_BUF_SIZE,
2563 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2564 GFP_KERNEL);
2565
2566 if (!skb) {
2567 hddLog(VOS_TRACE_LEVEL_ERROR,
2568 FL("cfg80211_vendor_event_alloc failed"));
2569 return;
2570 }
2571 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2572 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2573 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2574 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2575 pData->numSigRssiBss);
2576 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2577
2578 for (i = 0; i < pData->numSigRssiBss; i++) {
2579 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2580 " num RSSI %u ",
2581 i, pData->sigRssiResult[i].bssid,
2582 pData->sigRssiResult[i].channel,
2583 pData->sigRssiResult[i].numRssi);
2584
2585 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2586
2587 hddLog(VOS_TRACE_LEVEL_INFO,
2588 " [%d]",
2589 pData->sigRssiResult[i].rssi[0]);
2590
2591 }
2592 }
2593
2594
2595 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2596 pData->requestId) ||
2597 nla_put_u32(skb,
2598 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2599 pData->numSigRssiBss)) {
2600 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2601 goto fail;
2602 }
2603
2604 if (pData->numSigRssiBss) {
2605 struct nlattr *aps;
2606 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2607 if (!aps)
2608 goto fail;
2609 for (i = 0; i < pData->numSigRssiBss; i++) {
2610 struct nlattr *ap;
2611
2612 ap = nla_nest_start(skb, i);
2613 if (!ap)
2614 goto fail;
2615 if (nla_put(skb,
2616 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2617 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2618 nla_put_u32(skb,
2619 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2620 pData->sigRssiResult[i].channel) ||
2621 nla_put_u32(skb,
2622 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2623 pData->sigRssiResult[i].numRssi) ||
2624 nla_put(skb,
2625 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2626 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2627 pData->sigRssiResult[i].rssi))
2628 goto fail;
2629 nla_nest_end(skb, ap);
2630 }
2631 nla_nest_end(skb, aps);
2632 if (nla_put_u8(skb,
2633 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2634 pData->moreData))
2635 goto fail;
2636 }
2637 cfg80211_vendor_event(skb, GFP_KERNEL);
2638 return;
2639fail:
2640 kfree_skb(skb);
2641 return;
2642}
2643
2644static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2645 void *pMsg)
2646{
2647 struct sk_buff *skb;
2648 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2649 tpSirWifiFullScanResultEvent pData =
2650 (tpSirWifiFullScanResultEvent) (pMsg);
2651
2652 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2654 "or pData(%p) is null"), pData);
2655 return;
2656 }
2657
2658 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2659 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2660 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2661 GFP_KERNEL);
2662
2663 if (!skb) {
2664 hddLog(VOS_TRACE_LEVEL_ERROR,
2665 FL("cfg80211_vendor_event_alloc failed"));
2666 return;
2667 }
2668
2669 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2670 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2671 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2672 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2673 "Ssid (%s)"
2674 "Bssid (" MAC_ADDRESS_STR ")"
2675 "Channel (%u)"
2676 "Rssi (%d)"
2677 "RTT (%u)"
2678 "RTT_SD (%u)"),
2679 pData->ap.ts,
2680 pData->ap.ssid,
2681 MAC_ADDR_ARRAY(pData->ap.bssid),
2682 pData->ap.channel,
2683 pData->ap.rssi,
2684 pData->ap.rtt,
2685 pData->ap.rtt_sd);
2686 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2687 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2688 pData->requestId) ||
2689 nla_put_u64(skb,
2690 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2691 pData->ap.ts) ||
2692 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2693 sizeof(pData->ap.ssid),
2694 pData->ap.ssid) ||
2695 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2696 WNI_CFG_BSSID_LEN,
2697 pData->ap.bssid) ||
2698 nla_put_u32(skb,
2699 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2700 pData->ap.channel) ||
2701 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2702 pData->ap.rssi) ||
2703 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2704 pData->ap.rtt) ||
2705 nla_put_u32(skb,
2706 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2707 pData->ap.rtt_sd) ||
2708 nla_put_u16(skb,
2709 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2710 pData->ap.beaconPeriod) ||
2711 nla_put_u16(skb,
2712 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2713 pData->ap.capability) ||
2714 nla_put_u32(skb,
2715 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2716 pData->ieLength))
2717 {
2718 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2719 goto nla_put_failure;
2720 }
2721 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2722 pData->ieLength,
2723 pData->ie))
2724 {
2725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2726 goto nla_put_failure;
2727 }
2728
2729 cfg80211_vendor_event(skb, GFP_KERNEL);
2730 return;
2731
2732nla_put_failure:
2733 kfree_skb(skb);
2734 return;
2735}
2736
2737static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
2738 void *pMsg)
2739{
2740 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2741 struct sk_buff *skb = NULL;
2742 tpSirEXTScanResultsAvailableIndParams pData =
2743 (tpSirEXTScanResultsAvailableIndParams) pMsg;
2744
2745 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2747 "or pData(%p) is null"), pData);
2748 return;
2749 }
2750
2751 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2752 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2753 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
2754 GFP_KERNEL);
2755
2756 if (!skb) {
2757 hddLog(VOS_TRACE_LEVEL_ERROR,
2758 FL("cfg80211_vendor_event_alloc failed"));
2759 return;
2760 }
2761
2762 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2763 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2764 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
2765 pData->numResultsAvailable);
2766 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2767 pData->requestId) ||
2768 nla_put_u32(skb,
2769 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2770 pData->numResultsAvailable)) {
2771 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2772 goto nla_put_failure;
2773 }
2774
2775 cfg80211_vendor_event(skb, GFP_KERNEL);
2776 return;
2777
2778nla_put_failure:
2779 kfree_skb(skb);
2780 return;
2781}
2782
2783static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
2784{
2785 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2786 struct sk_buff *skb = NULL;
2787 tpSirEXTScanProgressIndParams pData =
2788 (tpSirEXTScanProgressIndParams) pMsg;
2789
2790 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2791 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2792 "or pData(%p) is null"), pData);
2793 return;
2794 }
2795
2796 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2797 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2798 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
2799 GFP_KERNEL);
2800
2801 if (!skb) {
2802 hddLog(VOS_TRACE_LEVEL_ERROR,
2803 FL("cfg80211_vendor_event_alloc failed"));
2804 return;
2805 }
2806 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2807 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
2808 pData->extScanEventType);
2809 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
2810 pData->status);
2811
2812 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
2813 pData->extScanEventType) ||
2814 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05302815 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2816 pData->requestId) ||
2817 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302818 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
2819 pData->status)) {
2820 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2821 goto nla_put_failure;
2822 }
2823
2824 cfg80211_vendor_event(skb, GFP_KERNEL);
2825 return;
2826
2827nla_put_failure:
2828 kfree_skb(skb);
2829 return;
2830}
2831
2832void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
2833 void *pMsg)
2834{
2835 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2836
2837 if (wlan_hdd_validate_context(pHddCtx)) {
2838 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
2839 return;
2840 }
2841
2842 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
2843
2844
2845 switch(evType) {
2846 case SIR_HAL_EXTSCAN_START_RSP:
2847 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
2848 break;
2849
2850 case SIR_HAL_EXTSCAN_STOP_RSP:
2851 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
2852 break;
2853 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
2854 /* There is no need to send this response to upper layer
2855 Just log the message */
2856 hddLog(VOS_TRACE_LEVEL_INFO,
2857 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
2858 break;
2859 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
2860 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
2861 break;
2862
2863 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
2864 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
2865 break;
2866
2867 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
2868 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
2869 break;
2870
2871 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
2872 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
2873 break;
2874 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
2875 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
2876 break;
2877 case SIR_HAL_EXTSCAN_PROGRESS_IND:
2878 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
2879 break;
2880 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
2881 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
2882 break;
2883 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
2884 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
2885 break;
2886 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
2887 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
2888 break;
2889 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
2890 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
2891 break;
2892 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
2893 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
2894 break;
2895 default:
2896 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
2897 break;
2898 }
2899}
2900
2901static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
2902 struct wireless_dev *wdev,
2903 void *data, int dataLen)
2904{
Dino Myclee8843b32014-07-04 14:21:45 +05302905 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302906 struct net_device *dev = wdev->netdev;
2907 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2908 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2909 struct nlattr
2910 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
2911 eHalStatus status;
2912
2913 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
2914 status = wlan_hdd_validate_context(pHddCtx);
2915 if (0 != status)
2916 {
2917 hddLog(VOS_TRACE_LEVEL_ERROR,
2918 FL("HDD context is not valid"));
2919 return -EINVAL;
2920 }
Dino Myclee8843b32014-07-04 14:21:45 +05302921 /* check the EXTScan Capability */
2922 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
2923 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
2924 {
2925 hddLog(VOS_TRACE_LEVEL_ERROR,
2926 FL("EXTScan not enabled/supported by Firmware"));
2927 return -EINVAL;
2928 }
2929
Dino Mycle6fb96c12014-06-10 11:52:40 +05302930 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
2931 data, dataLen,
2932 wlan_hdd_extscan_config_policy)) {
2933 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
2934 return -EINVAL;
2935 }
2936
2937 /* Parse and fetch request Id */
2938 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
2939 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
2940 return -EINVAL;
2941 }
2942
Dino Mycle6fb96c12014-06-10 11:52:40 +05302943
Dino Myclee8843b32014-07-04 14:21:45 +05302944 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05302945 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05302946 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302947
Dino Myclee8843b32014-07-04 14:21:45 +05302948 reqMsg.sessionId = pAdapter->sessionId;
2949 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302950
Dino Myclee8843b32014-07-04 14:21:45 +05302951 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302952 if (!HAL_STATUS_SUCCESS(status)) {
2953 hddLog(VOS_TRACE_LEVEL_ERROR,
2954 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302955 return -EINVAL;
2956 }
2957
2958 return 0;
2959}
2960
2961
2962static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
2963 struct wireless_dev *wdev,
2964 void *data, int dataLen)
2965{
Dino Myclee8843b32014-07-04 14:21:45 +05302966 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302967 struct net_device *dev = wdev->netdev;
2968 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2969 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2970 struct nlattr
2971 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
2972 eHalStatus status;
2973
2974 status = wlan_hdd_validate_context(pHddCtx);
2975 if (0 != status)
2976 {
2977 hddLog(VOS_TRACE_LEVEL_ERROR,
2978 FL("HDD context is not valid"));
2979 return -EINVAL;
2980 }
Dino Myclee8843b32014-07-04 14:21:45 +05302981 /* check the EXTScan Capability */
2982 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
2983 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
2984 {
2985 hddLog(VOS_TRACE_LEVEL_ERROR,
2986 FL("EXTScan not enabled/supported by Firmware"));
2987 return -EINVAL;
2988 }
2989
Dino Mycle6fb96c12014-06-10 11:52:40 +05302990 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
2991 data, dataLen,
2992 wlan_hdd_extscan_config_policy)) {
2993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
2994 return -EINVAL;
2995 }
2996 /* Parse and fetch request Id */
2997 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
2998 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
2999 return -EINVAL;
3000 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303001
Dino Myclee8843b32014-07-04 14:21:45 +05303002 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303003 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3004
Dino Myclee8843b32014-07-04 14:21:45 +05303005 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303006
Dino Myclee8843b32014-07-04 14:21:45 +05303007 reqMsg.sessionId = pAdapter->sessionId;
3008 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303009
3010 /* Parse and fetch flush parameter */
3011 if (!tb
3012 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3013 {
3014 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3015 goto failed;
3016 }
Dino Myclee8843b32014-07-04 14:21:45 +05303017 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303018 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3019
Dino Myclee8843b32014-07-04 14:21:45 +05303020 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303021
Dino Myclee8843b32014-07-04 14:21:45 +05303022 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303023 if (!HAL_STATUS_SUCCESS(status)) {
3024 hddLog(VOS_TRACE_LEVEL_ERROR,
3025 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303026 return -EINVAL;
3027 }
3028 return 0;
3029
3030failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303031 return -EINVAL;
3032}
3033
3034static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3035 struct wireless_dev *wdev,
3036 void *data, int dataLen)
3037{
3038 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3039 struct net_device *dev = wdev->netdev;
3040 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3041 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3042 struct nlattr
3043 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3044 struct nlattr
3045 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3046 struct nlattr *apTh;
3047 eHalStatus status;
3048 tANI_U8 i = 0;
3049 int rem;
3050
3051 status = wlan_hdd_validate_context(pHddCtx);
3052 if (0 != status)
3053 {
3054 hddLog(VOS_TRACE_LEVEL_ERROR,
3055 FL("HDD context is not valid"));
3056 return -EINVAL;
3057 }
Dino Myclee8843b32014-07-04 14:21:45 +05303058 /* check the EXTScan Capability */
3059 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3060 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3061 {
3062 hddLog(VOS_TRACE_LEVEL_ERROR,
3063 FL("EXTScan not enabled/supported by Firmware"));
3064 return -EINVAL;
3065 }
3066
Dino Mycle6fb96c12014-06-10 11:52:40 +05303067 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3068 data, dataLen,
3069 wlan_hdd_extscan_config_policy)) {
3070 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3071 return -EINVAL;
3072 }
3073
3074 /* Parse and fetch request Id */
3075 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3076 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3077 return -EINVAL;
3078 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303079 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3080 vos_mem_malloc(sizeof(*pReqMsg));
3081 if (!pReqMsg) {
3082 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3083 return -ENOMEM;
3084 }
3085
Dino Myclee8843b32014-07-04 14:21:45 +05303086
Dino Mycle6fb96c12014-06-10 11:52:40 +05303087 pReqMsg->requestId = nla_get_u32(
3088 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3089 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3090
3091 /* Parse and fetch number of APs */
3092 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3093 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3094 goto fail;
3095 }
3096
3097 pReqMsg->sessionId = pAdapter->sessionId;
3098 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3099
3100 pReqMsg->numAp = nla_get_u32(
3101 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3102 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3103
3104 nla_for_each_nested(apTh,
3105 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3106 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3107 nla_data(apTh), nla_len(apTh),
3108 NULL)) {
3109 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3110 goto fail;
3111 }
3112
3113 /* Parse and fetch MAC address */
3114 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3115 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3116 goto fail;
3117 }
3118 memcpy(pReqMsg->ap[i].bssid, nla_data(
3119 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3120 sizeof(tSirMacAddr));
3121 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3122
3123 /* Parse and fetch low RSSI */
3124 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3125 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3126 goto fail;
3127 }
3128 pReqMsg->ap[i].low = nla_get_s32(
3129 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3130 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3131
3132 /* Parse and fetch high RSSI */
3133 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3134 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3135 goto fail;
3136 }
3137 pReqMsg->ap[i].high = nla_get_s32(
3138 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3139 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3140 pReqMsg->ap[i].high);
3141
3142 /* Parse and fetch channel */
3143 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3144 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3145 goto fail;
3146 }
3147 pReqMsg->ap[i].channel = nla_get_u32(
3148 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3149 hddLog(VOS_TRACE_LEVEL_INFO,
3150 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3151 i++;
3152 }
3153 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3154 if (!HAL_STATUS_SUCCESS(status)) {
3155 hddLog(VOS_TRACE_LEVEL_ERROR,
3156 FL("sme_SetBssHotlist failed(err=%d)"), status);
3157 vos_mem_free(pReqMsg);
3158 return -EINVAL;
3159 }
3160
Dino Myclee8843b32014-07-04 14:21:45 +05303161 vos_mem_free(pReqMsg);
3162
Dino Mycle6fb96c12014-06-10 11:52:40 +05303163 return 0;
3164
3165fail:
3166 vos_mem_free(pReqMsg);
3167 return -EINVAL;
3168}
3169
3170static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3171 struct wireless_dev *wdev,
3172 void *data, int dataLen)
3173{
3174 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3175 struct net_device *dev = wdev->netdev;
3176 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3177 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3178 struct nlattr
3179 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3180 struct nlattr
3181 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3182 struct nlattr *apTh;
3183 eHalStatus status;
3184 int i = 0;
3185 int rem;
3186
3187 status = wlan_hdd_validate_context(pHddCtx);
3188 if (0 != status)
3189 {
3190 hddLog(VOS_TRACE_LEVEL_ERROR,
3191 FL("HDD context is not valid"));
3192 return -EINVAL;
3193 }
Dino Myclee8843b32014-07-04 14:21:45 +05303194 /* check the EXTScan Capability */
3195 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3196 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3197 {
3198 hddLog(VOS_TRACE_LEVEL_ERROR,
3199 FL("EXTScan not enabled/supported by Firmware"));
3200 return -EINVAL;
3201 }
3202
Dino Mycle6fb96c12014-06-10 11:52:40 +05303203 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3204 data, dataLen,
3205 wlan_hdd_extscan_config_policy)) {
3206 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3207 return -EINVAL;
3208 }
3209
3210 /* Parse and fetch request Id */
3211 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3212 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3213 return -EINVAL;
3214 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303215 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303216 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303217 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303218 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3219 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303220 }
3221
Dino Myclee8843b32014-07-04 14:21:45 +05303222
3223
Dino Mycle6fb96c12014-06-10 11:52:40 +05303224 pReqMsg->requestId = nla_get_u32(
3225 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3226 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3227
3228 /* Parse and fetch RSSI sample size */
3229 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3230 {
3231 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3232 goto fail;
3233 }
3234 pReqMsg->rssiSampleSize = nla_get_u32(
3235 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3236 hddLog(VOS_TRACE_LEVEL_INFO,
3237 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3238
3239 /* Parse and fetch lost AP sample size */
3240 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3241 {
3242 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3243 goto fail;
3244 }
3245 pReqMsg->lostApSampleSize = nla_get_u32(
3246 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3247 hddLog(VOS_TRACE_LEVEL_INFO,
3248 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3249 /* Parse and fetch minimum Breaching */
3250 if (!tb
3251 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3252 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3253 goto fail;
3254 }
3255 pReqMsg->minBreaching = nla_get_u32(
3256 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3257 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3258
3259 /* Parse and fetch number of APs */
3260 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3262 goto fail;
3263 }
3264 pReqMsg->numAp = nla_get_u32(
3265 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3266 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3267
3268 pReqMsg->sessionId = pAdapter->sessionId;
3269 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3270
3271 nla_for_each_nested(apTh,
3272 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3273 if(nla_parse(tb2,
3274 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3275 nla_data(apTh), nla_len(apTh),
3276 NULL)) {
3277 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3278 goto fail;
3279 }
3280
3281 /* Parse and fetch MAC address */
3282 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3283 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3284 goto fail;
3285 }
3286 memcpy(pReqMsg->ap[i].bssid, nla_data(
3287 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3288 sizeof(tSirMacAddr));
3289
3290 /* Parse and fetch low RSSI */
3291 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3292 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3293 goto fail;
3294 }
3295 pReqMsg->ap[i].low = nla_get_s32(
3296 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3297 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3298
3299 /* Parse and fetch high RSSI */
3300 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3301 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3302 goto fail;
3303 }
3304 pReqMsg->ap[i].high = nla_get_s32(
3305 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3306 hddLog(VOS_TRACE_LEVEL_INFO,
3307 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3308
3309 /* Parse and fetch channel */
3310 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3311 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3312 goto fail;
3313 }
3314 pReqMsg->ap[i].channel = nla_get_u32(
3315 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3316 hddLog(VOS_TRACE_LEVEL_INFO,
3317 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3318 i++;
3319 }
3320
3321 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3322 if (!HAL_STATUS_SUCCESS(status)) {
3323 hddLog(VOS_TRACE_LEVEL_ERROR,
3324 FL("sme_SetSignificantChange failed(err=%d)"), status);
3325 vos_mem_free(pReqMsg);
3326 return -EINVAL;
3327 }
Dino Myclee8843b32014-07-04 14:21:45 +05303328 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303329 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3330 return 0;
3331
3332fail:
3333 vos_mem_free(pReqMsg);
3334 return -EINVAL;
3335}
3336
3337static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3338 struct wireless_dev *wdev,
3339 void *data, int dataLen)
3340{
3341 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3342 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3343 tANI_U8 numChannels = 0;
3344 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3345 tANI_U32 requestId;
3346 tWifiBand wifiBand;
3347 eHalStatus status;
3348 struct sk_buff *replySkb;
3349 tANI_U8 i;
3350
3351 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3352 status = wlan_hdd_validate_context(pHddCtx);
3353 if (0 != status)
3354 {
3355 hddLog(VOS_TRACE_LEVEL_ERROR,
3356 FL("HDD context is not valid"));
3357 return -EINVAL;
3358 }
Dino Myclee8843b32014-07-04 14:21:45 +05303359 /* check the EXTScan Capability */
3360 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3361 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3362 {
3363 hddLog(VOS_TRACE_LEVEL_ERROR,
3364 FL("EXTScan not enabled/supported by Firmware"));
3365 return -EINVAL;
3366 }
3367
Dino Mycle6fb96c12014-06-10 11:52:40 +05303368 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3369 data, dataLen,
3370 wlan_hdd_extscan_config_policy)) {
3371 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3372 return -EINVAL;
3373 }
3374
3375 /* Parse and fetch request Id */
3376 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3377 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3378 return -EINVAL;
3379 }
3380 requestId = nla_get_u32(
3381 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3382 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3383
3384 /* Parse and fetch wifi band */
3385 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3386 {
3387 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3388 return -EINVAL;
3389 }
3390 wifiBand = nla_get_u32(
3391 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3392 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3393
3394 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3395 wifiBand, ChannelList,
3396 &numChannels);
3397 if (eHAL_STATUS_SUCCESS != status) {
3398 hddLog(VOS_TRACE_LEVEL_ERROR,
3399 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3400 return -EINVAL;
3401 }
3402 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3403 for (i = 0; i < numChannels; i++)
3404 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3405
3406 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3407 sizeof(u32) * numChannels +
3408 NLMSG_HDRLEN);
3409
3410 if (!replySkb) {
3411 hddLog(VOS_TRACE_LEVEL_ERROR,
3412 FL("valid channels: buffer alloc fail"));
3413 return -EINVAL;
3414 }
3415 if (nla_put_u32(replySkb,
3416 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3417 numChannels) ||
3418 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3419 sizeof(u32) * numChannels, ChannelList)) {
3420
3421 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3422 kfree_skb(replySkb);
3423 return -EINVAL;
3424 }
3425
3426 return cfg80211_vendor_cmd_reply(replySkb);
3427}
3428
3429static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3430 struct wireless_dev *wdev,
3431 void *data, int dataLen)
3432{
Dino Myclee8843b32014-07-04 14:21:45 +05303433 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303434 struct net_device *dev = wdev->netdev;
3435 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3436 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3437 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3438 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3439 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3440 struct nlattr *buckets;
3441 struct nlattr *channels;
3442 int rem1;
3443 int rem2;
3444 eHalStatus status;
3445 tANI_U8 bktIndex;
3446 tANI_U32 i = 0, j = 0;
3447
3448 status = wlan_hdd_validate_context(pHddCtx);
3449 if (0 != status)
3450 {
3451 hddLog(VOS_TRACE_LEVEL_ERROR,
3452 FL("HDD context is not valid"));
3453 return -EINVAL;
3454 }
Dino Myclee8843b32014-07-04 14:21:45 +05303455 /* check the EXTScan Capability */
3456 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3457 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3458 {
3459 hddLog(VOS_TRACE_LEVEL_ERROR,
3460 FL("EXTScan not enabled/supported by Firmware"));
3461 return -EINVAL;
3462 }
3463
Dino Mycle6fb96c12014-06-10 11:52:40 +05303464 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3465 data, dataLen,
3466 wlan_hdd_extscan_config_policy)) {
3467 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3468 return -EINVAL;
3469 }
3470
3471 /* Parse and fetch request Id */
3472 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3473 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3474 return -EINVAL;
3475 }
3476
Dino Myclee8843b32014-07-04 14:21:45 +05303477 pReqMsg = (tpSirEXTScanStartReqParams)
3478 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303479 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303480 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3481 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303482 }
3483
3484 pReqMsg->requestId = nla_get_u32(
3485 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3486 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3487
3488 pReqMsg->sessionId = pAdapter->sessionId;
3489 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3490
3491 /* Parse and fetch base period */
3492 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3493 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3494 goto fail;
3495 }
3496 pReqMsg->basePeriod = nla_get_u32(
3497 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3498 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3499 pReqMsg->basePeriod);
3500
3501 /* Parse and fetch max AP per scan */
3502 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3503 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3504 goto fail;
3505 }
3506 pReqMsg->maxAPperScan = nla_get_u32(
3507 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3508 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3509 pReqMsg->maxAPperScan);
3510
3511 /* Parse and fetch report threshold */
3512 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3513 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3514 goto fail;
3515 }
3516 pReqMsg->reportThreshold = nla_get_u8(
3517 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3518 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3519 pReqMsg->reportThreshold);
3520
3521 /* Parse and fetch number of buckets */
3522 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3523 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3524 goto fail;
3525 }
3526 pReqMsg->numBuckets = nla_get_u8(
3527 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3528 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3529 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3530 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3531 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3532 }
3533 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3534 pReqMsg->numBuckets);
3535 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3536 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3537 goto fail;
3538 }
3539
3540 nla_for_each_nested(buckets,
3541 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3542 if(nla_parse(bucket,
3543 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3544 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3545 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3546 goto fail;
3547 }
3548
3549 /* Parse and fetch bucket spec */
3550 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3551 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3552 goto fail;
3553 }
3554 bktIndex = nla_get_u8(
3555 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3556 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"), bktIndex);
3557 pReqMsg->buckets[bktIndex].bucket = bktIndex;
3558
3559 /* Parse and fetch wifi band */
3560 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3561 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3562 goto fail;
3563 }
3564 pReqMsg->buckets[bktIndex].band = nla_get_u8(
3565 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3566 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
3567 pReqMsg->buckets[bktIndex].band);
3568
3569 /* Parse and fetch period */
3570 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3571 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3572 goto fail;
3573 }
3574 pReqMsg->buckets[bktIndex].period = nla_get_u32(
3575 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3576 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
3577 pReqMsg->buckets[bktIndex].period);
3578
3579 /* Parse and fetch report events */
3580 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3582 goto fail;
3583 }
3584 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
3585 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3586 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
3587 pReqMsg->buckets[bktIndex].reportEvents);
3588
3589 /* Parse and fetch number of channels */
3590 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
3591 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3592 goto fail;
3593 }
3594 pReqMsg->buckets[bktIndex].numChannels = nla_get_u32(
3595 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3596 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
3597 pReqMsg->buckets[bktIndex].numChannels);
3598
3599 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3600 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3601 goto fail;
3602 }
3603
3604 j = 0;
3605 nla_for_each_nested(channels,
3606 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3607 if(nla_parse(channel,
3608 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3609 nla_data(channels), nla_len(channels),
3610 NULL)) { //wlan_hdd_extscan_config_policy here
3611 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3612 goto fail;
3613 }
3614
3615 /* Parse and fetch channel */
3616 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3618 goto fail;
3619 }
3620 pReqMsg->buckets[bktIndex].channels[j].channel = nla_get_u32(
3621 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3622 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
3623 pReqMsg->buckets[bktIndex].channels[j].channel);
3624
3625 /* Parse and fetch dwell time */
3626 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3627 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3628 goto fail;
3629 }
3630 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs = nla_get_u32(
3631 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3632 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
3633 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
3634
3635 /* Parse and fetch channel spec passive */
3636 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3637 hddLog(VOS_TRACE_LEVEL_ERROR,
3638 FL("attr channel spec passive failed"));
3639 goto fail;
3640 }
3641 pReqMsg->buckets[bktIndex].channels[j].passive = nla_get_u8(
3642 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3643 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
3644 pReqMsg->buckets[bktIndex].channels[j].passive);
3645 j++;
3646 }
3647 i++;
3648 }
3649 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3650 if (!HAL_STATUS_SUCCESS(status)) {
3651 hddLog(VOS_TRACE_LEVEL_ERROR,
3652 FL("sme_EXTScanStart failed(err=%d)"), status);
3653 vos_mem_free(pReqMsg);
3654 return -EINVAL;
3655 }
3656
Dino Myclee8843b32014-07-04 14:21:45 +05303657 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303658 return 0;
3659
3660fail:
3661 vos_mem_free(pReqMsg);
3662 return -EINVAL;
3663}
3664
3665static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
3666 struct wireless_dev *wdev,
3667 void *data, int dataLen)
3668{
Dino Myclee8843b32014-07-04 14:21:45 +05303669 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303670 struct net_device *dev = wdev->netdev;
3671 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3672 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3673 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3674 eHalStatus status;
3675
3676 status = wlan_hdd_validate_context(pHddCtx);
3677 if (0 != status)
3678 {
3679 hddLog(VOS_TRACE_LEVEL_ERROR,
3680 FL("HDD context is not valid"));
3681 return -EINVAL;
3682 }
Dino Myclee8843b32014-07-04 14:21:45 +05303683 /* check the EXTScan Capability */
3684 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3685 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3686 {
3687 hddLog(VOS_TRACE_LEVEL_ERROR,
3688 FL("EXTScan not enabled/supported by Firmware"));
3689 return -EINVAL;
3690 }
3691
Dino Mycle6fb96c12014-06-10 11:52:40 +05303692 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3693 data, dataLen,
3694 wlan_hdd_extscan_config_policy)) {
3695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3696 return -EINVAL;
3697 }
3698
3699 /* Parse and fetch request Id */
3700 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3701 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3702 return -EINVAL;
3703 }
3704
Dino Myclee8843b32014-07-04 14:21:45 +05303705 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303706 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303707 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303708
Dino Myclee8843b32014-07-04 14:21:45 +05303709 reqMsg.sessionId = pAdapter->sessionId;
3710 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303711
Dino Myclee8843b32014-07-04 14:21:45 +05303712 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303713 if (!HAL_STATUS_SUCCESS(status)) {
3714 hddLog(VOS_TRACE_LEVEL_ERROR,
3715 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303716 return -EINVAL;
3717 }
3718
3719 return 0;
3720}
3721
3722static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
3723 struct wireless_dev *wdev,
3724 void *data, int dataLen)
3725{
Dino Myclee8843b32014-07-04 14:21:45 +05303726 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303727 struct net_device *dev = wdev->netdev;
3728 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3729 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3730 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3731 eHalStatus status;
3732
3733 status = wlan_hdd_validate_context(pHddCtx);
3734 if (0 != status)
3735 {
3736 hddLog(VOS_TRACE_LEVEL_ERROR,
3737 FL("HDD context is not valid"));
3738 return -EINVAL;
3739 }
Dino Myclee8843b32014-07-04 14:21:45 +05303740 /* check the EXTScan Capability */
3741 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3742 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3743 {
3744 hddLog(VOS_TRACE_LEVEL_ERROR,
3745 FL("EXTScan not enabled/supported by Firmware"));
3746 return -EINVAL;
3747 }
3748
Dino Mycle6fb96c12014-06-10 11:52:40 +05303749 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3750 data, dataLen,
3751 wlan_hdd_extscan_config_policy)) {
3752 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3753 return -EINVAL;
3754 }
3755
3756 /* Parse and fetch request Id */
3757 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3758 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3759 return -EINVAL;
3760 }
3761
Dino Myclee8843b32014-07-04 14:21:45 +05303762 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303763 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303764 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303765
Dino Myclee8843b32014-07-04 14:21:45 +05303766 reqMsg.sessionId = pAdapter->sessionId;
3767 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303768
Dino Myclee8843b32014-07-04 14:21:45 +05303769 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303770 if (!HAL_STATUS_SUCCESS(status)) {
3771 hddLog(VOS_TRACE_LEVEL_ERROR,
3772 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303773 return -EINVAL;
3774 }
3775
3776 return 0;
3777}
3778
3779static int wlan_hdd_cfg80211_extscan_reset_significant_change(
3780 struct wiphy *wiphy,
3781 struct wireless_dev *wdev,
3782 void *data, int dataLen)
3783{
Dino Myclee8843b32014-07-04 14:21:45 +05303784 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303785 struct net_device *dev = wdev->netdev;
3786 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3787 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3788 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3789 eHalStatus status;
3790
3791 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
3792 status = wlan_hdd_validate_context(pHddCtx);
3793 if (0 != status)
3794 {
3795 hddLog(VOS_TRACE_LEVEL_ERROR,
3796 FL("HDD context is not valid"));
3797 return -EINVAL;
3798 }
Dino Myclee8843b32014-07-04 14:21:45 +05303799 /* check the EXTScan Capability */
3800 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3801 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3802 {
3803 hddLog(VOS_TRACE_LEVEL_ERROR,
3804 FL("EXTScan not enabled/supported by Firmware"));
3805 return -EINVAL;
3806 }
3807
Dino Mycle6fb96c12014-06-10 11:52:40 +05303808 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3809 data, dataLen,
3810 wlan_hdd_extscan_config_policy)) {
3811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3812 return -EINVAL;
3813 }
3814
3815 /* Parse and fetch request Id */
3816 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3818 return -EINVAL;
3819 }
3820
Dino Mycle6fb96c12014-06-10 11:52:40 +05303821
Dino Myclee8843b32014-07-04 14:21:45 +05303822 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303823 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303824 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303825
Dino Myclee8843b32014-07-04 14:21:45 +05303826 reqMsg.sessionId = pAdapter->sessionId;
3827 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303828
Dino Myclee8843b32014-07-04 14:21:45 +05303829 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303830 if (!HAL_STATUS_SUCCESS(status)) {
3831 hddLog(VOS_TRACE_LEVEL_ERROR,
3832 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303833 return -EINVAL;
3834 }
3835
3836 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3837 return 0;
3838}
3839
3840#endif /* WLAN_FEATURE_EXTSCAN */
3841
Sunil Duttc69bccb2014-05-26 21:30:20 +05303842const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
3843{
3844#ifdef WLAN_FEATURE_LINK_LAYER_STATS
3845 {
3846 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3847 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
3848 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3849 WIPHY_VENDOR_CMD_NEED_NETDEV |
3850 WIPHY_VENDOR_CMD_NEED_RUNNING,
3851 .doit = wlan_hdd_cfg80211_ll_stats_clear
3852 },
3853
3854 {
3855 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3856 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
3857 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3858 WIPHY_VENDOR_CMD_NEED_NETDEV |
3859 WIPHY_VENDOR_CMD_NEED_RUNNING,
3860 .doit = wlan_hdd_cfg80211_ll_stats_set
3861 },
3862
3863 {
3864 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3865 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
3866 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3867 WIPHY_VENDOR_CMD_NEED_NETDEV |
3868 WIPHY_VENDOR_CMD_NEED_RUNNING,
3869 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05303870 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05303871#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05303872#ifdef WLAN_FEATURE_EXTSCAN
3873 {
3874 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3875 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
3876 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3877 WIPHY_VENDOR_CMD_NEED_NETDEV |
3878 WIPHY_VENDOR_CMD_NEED_RUNNING,
3879 .doit = wlan_hdd_cfg80211_extscan_start
3880 },
3881 {
3882 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3883 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
3884 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3885 WIPHY_VENDOR_CMD_NEED_NETDEV |
3886 WIPHY_VENDOR_CMD_NEED_RUNNING,
3887 .doit = wlan_hdd_cfg80211_extscan_stop
3888 },
3889 {
3890 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3891 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
3892 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3893 WIPHY_VENDOR_CMD_NEED_NETDEV,
3894 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
3895 },
3896 {
3897 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3898 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
3899 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3900 WIPHY_VENDOR_CMD_NEED_NETDEV |
3901 WIPHY_VENDOR_CMD_NEED_RUNNING,
3902 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
3903 },
3904 {
3905 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3906 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
3907 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3908 WIPHY_VENDOR_CMD_NEED_NETDEV |
3909 WIPHY_VENDOR_CMD_NEED_RUNNING,
3910 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
3911 },
3912 {
3913 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3914 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
3915 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3916 WIPHY_VENDOR_CMD_NEED_NETDEV |
3917 WIPHY_VENDOR_CMD_NEED_RUNNING,
3918 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
3919 },
3920 {
3921 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3922 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
3923 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3924 WIPHY_VENDOR_CMD_NEED_NETDEV |
3925 WIPHY_VENDOR_CMD_NEED_RUNNING,
3926 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
3927 },
3928 {
3929 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3930 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
3931 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3932 WIPHY_VENDOR_CMD_NEED_NETDEV |
3933 WIPHY_VENDOR_CMD_NEED_RUNNING,
3934 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
3935 },
3936 {
3937 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3938 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
3939 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3940 WIPHY_VENDOR_CMD_NEED_NETDEV |
3941 WIPHY_VENDOR_CMD_NEED_RUNNING,
3942 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
3943 },
3944#endif /* WLAN_FEATURE_EXTSCAN */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303945};
3946
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003947/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303948static const
3949struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003950{
3951#ifdef FEATURE_WLAN_CH_AVOID
3952 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303953 .vendor_id = QCA_NL80211_VENDOR_ID,
3954 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003955 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05303956#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
3957#ifdef WLAN_FEATURE_LINK_LAYER_STATS
3958 {
3959 /* Index = 1*/
3960 .vendor_id = QCA_NL80211_VENDOR_ID,
3961 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
3962 },
3963 {
3964 /* Index = 2*/
3965 .vendor_id = QCA_NL80211_VENDOR_ID,
3966 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
3967 },
3968 {
3969 /* Index = 3*/
3970 .vendor_id = QCA_NL80211_VENDOR_ID,
3971 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
3972 },
3973 {
3974 /* Index = 4*/
3975 .vendor_id = QCA_NL80211_VENDOR_ID,
3976 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
3977 },
3978 {
3979 /* Index = 5*/
3980 .vendor_id = QCA_NL80211_VENDOR_ID,
3981 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
3982 },
3983 {
3984 /* Index = 6*/
3985 .vendor_id = QCA_NL80211_VENDOR_ID,
3986 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
3987 },
3988#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05303989#ifdef WLAN_FEATURE_EXTSCAN
3990 {
3991 .vendor_id = QCA_NL80211_VENDOR_ID,
3992 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
3993 },
3994 {
3995 .vendor_id = QCA_NL80211_VENDOR_ID,
3996 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
3997 },
3998 {
3999 .vendor_id = QCA_NL80211_VENDOR_ID,
4000 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
4001 },
4002 {
4003 .vendor_id = QCA_NL80211_VENDOR_ID,
4004 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
4005 },
4006 {
4007 .vendor_id = QCA_NL80211_VENDOR_ID,
4008 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
4009 },
4010 {
4011 .vendor_id = QCA_NL80211_VENDOR_ID,
4012 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
4013 },
4014 {
4015 .vendor_id = QCA_NL80211_VENDOR_ID,
4016 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
4017 },
4018 {
4019 .vendor_id = QCA_NL80211_VENDOR_ID,
4020 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
4021 },
4022 {
4023 .vendor_id = QCA_NL80211_VENDOR_ID,
4024 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
4025 },
4026 {
4027 .vendor_id = QCA_NL80211_VENDOR_ID,
4028 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
4029 },
4030 {
4031 .vendor_id = QCA_NL80211_VENDOR_ID,
4032 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
4033 },
4034 {
4035 .vendor_id = QCA_NL80211_VENDOR_ID,
4036 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
4037 },
4038 {
4039 .vendor_id = QCA_NL80211_VENDOR_ID,
4040 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
4041 },
4042#endif /* WLAN_FEATURE_EXTSCAN */
Sunil Duttc69bccb2014-05-26 21:30:20 +05304043
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004044};
4045
Jeff Johnson295189b2012-06-20 16:38:30 -07004046/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304047 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304048 * This function is called by hdd_wlan_startup()
4049 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304050 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07004051 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304052struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07004053{
4054 struct wiphy *wiphy;
4055 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304056 /*
4057 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07004058 */
4059 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
4060
4061 if (!wiphy)
4062 {
4063 /* Print error and jump into err label and free the memory */
4064 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
4065 return NULL;
4066 }
4067
Sunil Duttc69bccb2014-05-26 21:30:20 +05304068
Jeff Johnson295189b2012-06-20 16:38:30 -07004069 return wiphy;
4070}
4071
4072/*
4073 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304074 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07004075 * private ioctl to change the band value
4076 */
4077int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
4078{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304079 int i, j;
4080 eNVChannelEnabledType channelEnabledState;
4081
Jeff Johnsone7245742012-09-05 17:12:55 -07004082 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304083
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304084 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07004085 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304086
4087 if (NULL == wiphy->bands[i])
4088 {
4089 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4090 __func__, i);
4091 continue;
4092 }
4093
4094 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4095 {
4096 struct ieee80211_supported_band *band = wiphy->bands[i];
4097
4098 channelEnabledState = vos_nv_getChannelEnabledState(
4099 band->channels[j].hw_value);
4100
4101 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
4102 {
4103 // Enable Social channels for P2P
4104 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
4105 NV_CHANNEL_ENABLE == channelEnabledState)
4106 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4107 else
4108 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4109 continue;
4110 }
4111 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
4112 {
4113 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4114 continue;
4115 }
4116
4117 if (NV_CHANNEL_DISABLE == channelEnabledState ||
4118 NV_CHANNEL_INVALID == channelEnabledState)
4119 {
4120 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4121 }
4122 else if (NV_CHANNEL_DFS == channelEnabledState)
4123 {
4124 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4125 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
4126 }
4127 else
4128 {
4129 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4130 |IEEE80211_CHAN_RADAR);
4131 }
4132 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004133 }
4134 return 0;
4135}
4136/*
4137 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304138 * This function is called by hdd_wlan_startup()
4139 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07004140 * This function is used to initialize and register wiphy structure.
4141 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304142int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07004143 struct wiphy *wiphy,
4144 hdd_config_t *pCfg
4145 )
4146{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304147 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304148 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4149
Jeff Johnsone7245742012-09-05 17:12:55 -07004150 ENTER();
4151
Jeff Johnson295189b2012-06-20 16:38:30 -07004152 /* Now bind the underlying wlan device with wiphy */
4153 set_wiphy_dev(wiphy, dev);
4154
4155 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004156
Kiet Lam6c583332013-10-14 05:37:09 +05304157#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07004158 /* the flag for the other case would be initialzed in
4159 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07004160 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05304161#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004162
Amar Singhalfddc28c2013-09-05 13:03:40 -07004163 /* This will disable updating of NL channels from passive to
4164 * active if a beacon is received on passive channel. */
4165 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07004166
Amar Singhalfddc28c2013-09-05 13:03:40 -07004167
Amar Singhala49cbc52013-10-08 18:37:44 -07004168
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004169#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004170 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
4171 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
4172 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07004173 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05304174 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004175#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004176
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004177#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004178 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08004179#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004180 || pCfg->isFastRoamIniFeatureEnabled
4181#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004182#ifdef FEATURE_WLAN_ESE
4183 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004184#endif
4185 )
4186 {
4187 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4188 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08004189#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004190#ifdef FEATURE_WLAN_TDLS
4191 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
4192 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
4193#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304194#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05304195 if (pCfg->configPNOScanSupport)
4196 {
4197 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4198 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
4199 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
4200 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
4201 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304202#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004203
Amar Singhalfddc28c2013-09-05 13:03:40 -07004204#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004205 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
4206 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07004207 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004208 driver need to determine what to do with both
4209 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07004210
4211 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07004212#else
4213 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004214#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004215
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304216 wiphy->max_scan_ssids = MAX_SCAN_SSID;
4217
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05304218 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07004219
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05304220 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
4221
Jeff Johnson295189b2012-06-20 16:38:30 -07004222 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304223 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004224 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07004225 | BIT(NL80211_IFTYPE_P2P_CLIENT)
4226 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07004227 | BIT(NL80211_IFTYPE_AP);
4228
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304229 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004230 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304231#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
4232 if( pCfg->enableMCC )
4233 {
4234 /* Currently, supports up to two channels */
4235 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004236
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304237 if( !pCfg->allowMCCGODiffBI )
4238 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004239
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304240 }
4241 wiphy->iface_combinations = &wlan_hdd_iface_combination;
4242 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004243#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304244 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004245
Jeff Johnson295189b2012-06-20 16:38:30 -07004246 /* Before registering we need to update the ht capabilitied based
4247 * on ini values*/
4248 if( !pCfg->ShortGI20MhzEnable )
4249 {
4250 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4251 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4252 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4253 }
4254
4255 if( !pCfg->ShortGI40MhzEnable )
4256 {
4257 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
4258 }
4259
4260 if( !pCfg->nChannelBondingMode5GHz )
4261 {
4262 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4263 }
4264
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304265 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304266 if (true == hdd_is_5g_supported(pHddCtx))
4267 {
4268 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
4269 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304270
4271 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
4272 {
4273
4274 if (NULL == wiphy->bands[i])
4275 {
4276 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4277 __func__, i);
4278 continue;
4279 }
4280
4281 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4282 {
4283 struct ieee80211_supported_band *band = wiphy->bands[i];
4284
4285 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
4286 {
4287 // Enable social channels for P2P
4288 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
4289 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4290 else
4291 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4292 continue;
4293 }
4294 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
4295 {
4296 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4297 continue;
4298 }
4299 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004300 }
4301 /*Initialise the supported cipher suite details*/
4302 wiphy->cipher_suites = hdd_cipher_suites;
4303 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
4304
4305 /*signal strength in mBm (100*dBm) */
4306 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4307
4308#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05304309 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07004310#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004311
Sunil Duttc69bccb2014-05-26 21:30:20 +05304312 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
4313 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004314 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
4315 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
4316
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304317 EXIT();
4318 return 0;
4319}
4320
4321/* In this function we are registering wiphy. */
4322int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
4323{
4324 ENTER();
4325 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004326 if (0 > wiphy_register(wiphy))
4327 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304328 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07004329 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
4330 return -EIO;
4331 }
4332
4333 EXIT();
4334 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304335}
Jeff Johnson295189b2012-06-20 16:38:30 -07004336
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304337/* In this function we are updating channel list when,
4338 regulatory domain is FCC and country code is US.
4339 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
4340 As per FCC smart phone is not a indoor device.
4341 GO should not opeate on indoor channels */
4342void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
4343{
4344 int j;
4345 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4346 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
4347 //Default counrtycode from NV at the time of wiphy initialization.
4348 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
4349 &defaultCountryCode[0]))
4350 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07004351 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304352 }
4353 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
4354 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304355 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
4356 {
4357 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
4358 return;
4359 }
4360 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
4361 {
4362 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
4363 // Mark UNII -1 band channel as passive
4364 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
4365 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4366 }
4367 }
4368}
4369
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304370/* This function registers for all frame which supplicant is interested in */
4371void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004372{
Jeff Johnson295189b2012-06-20 16:38:30 -07004373 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4374 /* Register for all P2P action, public action etc frames */
4375 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4376
Jeff Johnsone7245742012-09-05 17:12:55 -07004377 ENTER();
4378
Jeff Johnson295189b2012-06-20 16:38:30 -07004379 /* Right now we are registering these frame when driver is getting
4380 initialized. Once we will move to 2.6.37 kernel, in which we have
4381 frame register ops, we will move this code as a part of that */
4382 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304383 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07004384 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4385
4386 /* GAS Initial Response */
4387 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4388 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304389
Jeff Johnson295189b2012-06-20 16:38:30 -07004390 /* GAS Comeback Request */
4391 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4392 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4393
4394 /* GAS Comeback Response */
4395 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4396 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4397
4398 /* P2P Public Action */
4399 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304400 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004401 P2P_PUBLIC_ACTION_FRAME_SIZE );
4402
4403 /* P2P Action */
4404 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4405 (v_U8_t*)P2P_ACTION_FRAME,
4406 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07004407
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05304408 /* WNM BSS Transition Request frame */
4409 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4410 (v_U8_t*)WNM_BSS_ACTION_FRAME,
4411 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004412
4413 /* WNM-Notification */
4414 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4415 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4416 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004417}
4418
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304419void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004420{
Jeff Johnson295189b2012-06-20 16:38:30 -07004421 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4422 /* Register for all P2P action, public action etc frames */
4423 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4424
Jeff Johnsone7245742012-09-05 17:12:55 -07004425 ENTER();
4426
Jeff Johnson295189b2012-06-20 16:38:30 -07004427 /* Right now we are registering these frame when driver is getting
4428 initialized. Once we will move to 2.6.37 kernel, in which we have
4429 frame register ops, we will move this code as a part of that */
4430 /* GAS Initial Request */
4431
4432 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4433 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4434
4435 /* GAS Initial Response */
4436 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4437 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304438
Jeff Johnson295189b2012-06-20 16:38:30 -07004439 /* GAS Comeback Request */
4440 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4441 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4442
4443 /* GAS Comeback Response */
4444 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4445 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4446
4447 /* P2P Public Action */
4448 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304449 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004450 P2P_PUBLIC_ACTION_FRAME_SIZE );
4451
4452 /* P2P Action */
4453 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4454 (v_U8_t*)P2P_ACTION_FRAME,
4455 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004456 /* WNM-Notification */
4457 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4458 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4459 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004460}
4461
4462#ifdef FEATURE_WLAN_WAPI
4463void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
4464 const u8 *mac_addr, u8 *key , int key_Len)
4465{
4466 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4467 tCsrRoamSetKey setKey;
4468 v_BOOL_t isConnected = TRUE;
4469 int status = 0;
4470 v_U32_t roamId= 0xFF;
4471 tANI_U8 *pKeyPtr = NULL;
4472 int n = 0;
4473
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05304474 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
4475 __func__, hdd_device_modetoString(pAdapter->device_mode),
4476 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07004477
Gopichand Nakkalae7480202013-02-11 15:24:22 +05304478 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07004479 setKey.keyId = key_index; // Store Key ID
4480 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
4481 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
4482 setKey.paeRole = 0 ; // the PAE role
4483 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
4484 {
4485 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
4486 }
4487 else
4488 {
4489 isConnected = hdd_connIsConnected(pHddStaCtx);
4490 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
4491 }
4492 setKey.keyLength = key_Len;
4493 pKeyPtr = setKey.Key;
4494 memcpy( pKeyPtr, key, key_Len);
4495
Arif Hussain6d2a3322013-11-17 19:50:10 -08004496 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07004497 __func__, key_Len);
4498 for (n = 0 ; n < key_Len; n++)
4499 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
4500 __func__,n,setKey.Key[n]);
4501
4502 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4503 if ( isConnected )
4504 {
4505 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
4506 pAdapter->sessionId, &setKey, &roamId );
4507 }
4508 if ( status != 0 )
4509 {
4510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4511 "[%4d] sme_RoamSetKey returned ERROR status= %d",
4512 __LINE__, status );
4513 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4514 }
4515}
4516#endif /* FEATURE_WLAN_WAPI*/
4517
4518#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304519int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004520 beacon_data_t **ppBeacon,
4521 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004522#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304523int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004524 beacon_data_t **ppBeacon,
4525 struct cfg80211_beacon_data *params,
4526 int dtim_period)
4527#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304528{
Jeff Johnson295189b2012-06-20 16:38:30 -07004529 int size;
4530 beacon_data_t *beacon = NULL;
4531 beacon_data_t *old = NULL;
4532 int head_len,tail_len;
4533
Jeff Johnsone7245742012-09-05 17:12:55 -07004534 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07004535 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304536 {
4537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4538 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004539 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304540 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004541
4542 old = pAdapter->sessionCtx.ap.beacon;
4543
4544 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304545 {
4546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4547 FL("session(%d) old and new heads points to NULL"),
4548 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07004549 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304550 }
4551
4552 if (params->tail && !params->tail_len)
4553 {
4554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4555 FL("tail_len is zero but tail is not NULL"));
4556 return -EINVAL;
4557 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004558
Jeff Johnson295189b2012-06-20 16:38:30 -07004559#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
4560 /* Kernel 3.0 is not updating dtim_period for set beacon */
4561 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304562 {
4563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4564 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004565 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304566 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004567#endif
4568
4569 if(params->head)
4570 head_len = params->head_len;
4571 else
4572 head_len = old->head_len;
4573
4574 if(params->tail || !old)
4575 tail_len = params->tail_len;
4576 else
4577 tail_len = old->tail_len;
4578
4579 size = sizeof(beacon_data_t) + head_len + tail_len;
4580
4581 beacon = kzalloc(size, GFP_KERNEL);
4582
4583 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304584 {
4585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4586 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004587 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304588 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004589
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004590#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07004591 if(params->dtim_period || !old )
4592 beacon->dtim_period = params->dtim_period;
4593 else
4594 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004595#else
4596 if(dtim_period || !old )
4597 beacon->dtim_period = dtim_period;
4598 else
4599 beacon->dtim_period = old->dtim_period;
4600#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304601
Jeff Johnson295189b2012-06-20 16:38:30 -07004602 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
4603 beacon->tail = beacon->head + head_len;
4604 beacon->head_len = head_len;
4605 beacon->tail_len = tail_len;
4606
4607 if(params->head) {
4608 memcpy (beacon->head,params->head,beacon->head_len);
4609 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304610 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07004611 if(old)
4612 memcpy (beacon->head,old->head,beacon->head_len);
4613 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304614
Jeff Johnson295189b2012-06-20 16:38:30 -07004615 if(params->tail) {
4616 memcpy (beacon->tail,params->tail,beacon->tail_len);
4617 }
4618 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304619 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07004620 memcpy (beacon->tail,old->tail,beacon->tail_len);
4621 }
4622
4623 *ppBeacon = beacon;
4624
4625 kfree(old);
4626
4627 return 0;
4628
4629}
Jeff Johnson295189b2012-06-20 16:38:30 -07004630
4631v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
4632{
4633 int left = length;
4634 v_U8_t *ptr = pIes;
4635 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304636
Jeff Johnson295189b2012-06-20 16:38:30 -07004637 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304638 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004639 elem_id = ptr[0];
4640 elem_len = ptr[1];
4641 left -= 2;
4642 if(elem_len > left)
4643 {
4644 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07004645 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07004646 eid,elem_len,left);
4647 return NULL;
4648 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304649 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07004650 {
4651 return ptr;
4652 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304653
Jeff Johnson295189b2012-06-20 16:38:30 -07004654 left -= elem_len;
4655 ptr += (elem_len + 2);
4656 }
4657 return NULL;
4658}
4659
Jeff Johnson295189b2012-06-20 16:38:30 -07004660/* Check if rate is 11g rate or not */
4661static int wlan_hdd_rate_is_11g(u8 rate)
4662{
Sanjay Devnani28322e22013-06-21 16:13:40 -07004663 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004664 u8 i;
4665 for (i = 0; i < 8; i++)
4666 {
4667 if(rate == gRateArray[i])
4668 return TRUE;
4669 }
4670 return FALSE;
4671}
4672
4673/* Check for 11g rate and set proper 11g only mode */
4674static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
4675 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
4676{
4677 u8 i, num_rates = pIe[0];
4678
4679 pIe += 1;
4680 for ( i = 0; i < num_rates; i++)
4681 {
4682 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
4683 {
4684 /* If rate set have 11g rate than change the mode to 11G */
4685 *pSapHw_mode = eSAP_DOT11_MODE_11g;
4686 if (pIe[i] & BASIC_RATE_MASK)
4687 {
4688 /* If we have 11g rate as basic rate, it means mode
4689 is 11g only mode.
4690 */
4691 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
4692 *pCheckRatesfor11g = FALSE;
4693 }
4694 }
4695 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
4696 {
4697 *require_ht = TRUE;
4698 }
4699 }
4700 return;
4701}
4702
4703static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
4704{
4705 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
4706 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4707 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
4708 u8 checkRatesfor11g = TRUE;
4709 u8 require_ht = FALSE;
4710 u8 *pIe=NULL;
4711
4712 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
4713
4714 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
4715 pBeacon->head_len, WLAN_EID_SUPP_RATES);
4716 if (pIe != NULL)
4717 {
4718 pIe += 1;
4719 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
4720 &pConfig->SapHw_mode);
4721 }
4722
4723 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
4724 WLAN_EID_EXT_SUPP_RATES);
4725 if (pIe != NULL)
4726 {
4727
4728 pIe += 1;
4729 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
4730 &pConfig->SapHw_mode);
4731 }
4732
4733 if( pConfig->channel > 14 )
4734 {
4735 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
4736 }
4737
4738 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
4739 WLAN_EID_HT_CAPABILITY);
4740
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304741 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07004742 {
4743 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
4744 if(require_ht)
4745 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
4746 }
4747}
4748
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304749static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
4750 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
4751{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004752 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304753 v_U8_t *pIe = NULL;
4754 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4755
4756 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
4757 pBeacon->tail, pBeacon->tail_len);
4758
4759 if (pIe)
4760 {
4761 ielen = pIe[1] + 2;
4762 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
4763 {
4764 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
4765 }
4766 else
4767 {
4768 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
4769 return -EINVAL;
4770 }
4771 *total_ielen += ielen;
4772 }
4773 return 0;
4774}
4775
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004776static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
4777 v_U8_t *genie, v_U8_t *total_ielen)
4778{
4779 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4780 int left = pBeacon->tail_len;
4781 v_U8_t *ptr = pBeacon->tail;
4782 v_U8_t elem_id, elem_len;
4783 v_U16_t ielen = 0;
4784
4785 if ( NULL == ptr || 0 == left )
4786 return;
4787
4788 while (left >= 2)
4789 {
4790 elem_id = ptr[0];
4791 elem_len = ptr[1];
4792 left -= 2;
4793 if (elem_len > left)
4794 {
4795 hddLog( VOS_TRACE_LEVEL_ERROR,
4796 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
4797 elem_id, elem_len, left);
4798 return;
4799 }
4800 if (IE_EID_VENDOR == elem_id)
4801 {
4802 /* skipping the VSIE's which we don't want to include or
4803 * it will be included by existing code
4804 */
4805 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
4806#ifdef WLAN_FEATURE_WFD
4807 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
4808#endif
4809 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4810 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4811 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
4812 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4813 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
4814 {
4815 ielen = ptr[1] + 2;
4816 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
4817 {
4818 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
4819 *total_ielen += ielen;
4820 }
4821 else
4822 {
4823 hddLog( VOS_TRACE_LEVEL_ERROR,
4824 "IE Length is too big "
4825 "IEs eid=%d elem_len=%d total_ie_lent=%d",
4826 elem_id, elem_len, *total_ielen);
4827 }
4828 }
4829 }
4830
4831 left -= elem_len;
4832 ptr += (elem_len + 2);
4833 }
4834 return;
4835}
4836
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004837#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07004838static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
4839 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004840#else
4841static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
4842 struct cfg80211_beacon_data *params)
4843#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004844{
4845 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304846 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004847 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07004848 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004849
4850 genie = vos_mem_malloc(MAX_GENIE_LEN);
4851
4852 if(genie == NULL) {
4853
4854 return -ENOMEM;
4855 }
4856
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304857 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4858 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07004859 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304860 hddLog(LOGE,
4861 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304862 ret = -EINVAL;
4863 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004864 }
4865
4866#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304867 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4868 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
4869 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304870 hddLog(LOGE,
4871 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304872 ret = -EINVAL;
4873 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004874 }
4875#endif
4876
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304877 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4878 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07004879 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304880 hddLog(LOGE,
4881 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304882 ret = -EINVAL;
4883 goto done;
4884 }
4885
4886 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
4887 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004888 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07004889 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004890
4891 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4892 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
4893 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
4894 {
4895 hddLog(LOGE,
4896 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004897 ret = -EINVAL;
4898 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004899 }
4900
4901 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4902 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
4903 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
4904 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
4905 ==eHAL_STATUS_FAILURE)
4906 {
4907 hddLog(LOGE,
4908 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004909 ret = -EINVAL;
4910 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004911 }
4912
4913 // Added for ProResp IE
4914 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
4915 {
4916 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
4917 u8 probe_rsp_ie_len[3] = {0};
4918 u8 counter = 0;
4919 /* Check Probe Resp Length if it is greater then 255 then Store
4920 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
4921 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
4922 Store More then 255 bytes into One Variable.
4923 */
4924 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
4925 {
4926 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
4927 {
4928 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
4929 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
4930 }
4931 else
4932 {
4933 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
4934 rem_probe_resp_ie_len = 0;
4935 }
4936 }
4937
4938 rem_probe_resp_ie_len = 0;
4939
4940 if (probe_rsp_ie_len[0] > 0)
4941 {
4942 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4943 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
4944 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4945 probe_rsp_ie_len[0], NULL,
4946 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4947 {
4948 hddLog(LOGE,
4949 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004950 ret = -EINVAL;
4951 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004952 }
4953 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
4954 }
4955
4956 if (probe_rsp_ie_len[1] > 0)
4957 {
4958 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4959 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
4960 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4961 probe_rsp_ie_len[1], NULL,
4962 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4963 {
4964 hddLog(LOGE,
4965 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004966 ret = -EINVAL;
4967 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004968 }
4969 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
4970 }
4971
4972 if (probe_rsp_ie_len[2] > 0)
4973 {
4974 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4975 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
4976 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4977 probe_rsp_ie_len[2], NULL,
4978 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4979 {
4980 hddLog(LOGE,
4981 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004982 ret = -EINVAL;
4983 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004984 }
4985 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
4986 }
4987
4988 if (probe_rsp_ie_len[1] == 0 )
4989 {
4990 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4991 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
4992 eANI_BOOLEAN_FALSE) )
4993 {
4994 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004995 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07004996 }
4997 }
4998
4999 if (probe_rsp_ie_len[2] == 0 )
5000 {
5001 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5002 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
5003 eANI_BOOLEAN_FALSE) )
5004 {
5005 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005006 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005007 }
5008 }
5009
5010 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5011 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5012 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5013 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5014 == eHAL_STATUS_FAILURE)
5015 {
5016 hddLog(LOGE,
5017 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005018 ret = -EINVAL;
5019 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005020 }
5021 }
5022 else
5023 {
5024 // Reset WNI_CFG_PROBE_RSP Flags
5025 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
5026
5027 hddLog(VOS_TRACE_LEVEL_INFO,
5028 "%s: No Probe Response IE received in set beacon",
5029 __func__);
5030 }
5031
5032 // Added for AssocResp IE
5033 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
5034 {
5035 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5036 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
5037 params->assocresp_ies_len, NULL,
5038 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5039 {
5040 hddLog(LOGE,
5041 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005042 ret = -EINVAL;
5043 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005044 }
5045
5046 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5047 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
5048 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5049 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5050 == eHAL_STATUS_FAILURE)
5051 {
5052 hddLog(LOGE,
5053 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005054 ret = -EINVAL;
5055 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005056 }
5057 }
5058 else
5059 {
5060 hddLog(VOS_TRACE_LEVEL_INFO,
5061 "%s: No Assoc Response IE received in set beacon",
5062 __func__);
5063
5064 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5065 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5066 eANI_BOOLEAN_FALSE) )
5067 {
5068 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005069 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005070 }
5071 }
5072
Jeff Johnsone7245742012-09-05 17:12:55 -07005073done:
Jeff Johnson295189b2012-06-20 16:38:30 -07005074 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305075 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005076}
Jeff Johnson295189b2012-06-20 16:38:30 -07005077
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305078/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005079 * FUNCTION: wlan_hdd_validate_operation_channel
5080 * called by wlan_hdd_cfg80211_start_bss() and
5081 * wlan_hdd_cfg80211_set_channel()
5082 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305083 * channel list.
5084 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005085VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005086{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305087
Jeff Johnson295189b2012-06-20 16:38:30 -07005088 v_U32_t num_ch = 0;
5089 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5090 u32 indx = 0;
5091 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305092 v_U8_t fValidChannel = FALSE, count = 0;
5093 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305094
Jeff Johnson295189b2012-06-20 16:38:30 -07005095 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5096
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305097 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005098 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305099 /* Validate the channel */
5100 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005101 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305102 if ( channel == rfChannels[count].channelNum )
5103 {
5104 fValidChannel = TRUE;
5105 break;
5106 }
5107 }
5108 if (fValidChannel != TRUE)
5109 {
5110 hddLog(VOS_TRACE_LEVEL_ERROR,
5111 "%s: Invalid Channel [%d]", __func__, channel);
5112 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005113 }
5114 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305115 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005116 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305117 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5118 valid_ch, &num_ch))
5119 {
5120 hddLog(VOS_TRACE_LEVEL_ERROR,
5121 "%s: failed to get valid channel list", __func__);
5122 return VOS_STATUS_E_FAILURE;
5123 }
5124 for (indx = 0; indx < num_ch; indx++)
5125 {
5126 if (channel == valid_ch[indx])
5127 {
5128 break;
5129 }
5130 }
5131
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305132 if (indx >= num_ch)
5133 {
5134 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5135 {
5136 eCsrBand band;
5137 unsigned int freq;
5138
5139 sme_GetFreqBand(hHal, &band);
5140
5141 if (eCSR_BAND_5G == band)
5142 {
5143#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
5144 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
5145 {
5146 freq = ieee80211_channel_to_frequency(channel,
5147 IEEE80211_BAND_2GHZ);
5148 }
5149 else
5150 {
5151 freq = ieee80211_channel_to_frequency(channel,
5152 IEEE80211_BAND_5GHZ);
5153 }
5154#else
5155 freq = ieee80211_channel_to_frequency(channel);
5156#endif
5157 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
5158 return VOS_STATUS_SUCCESS;
5159 }
5160 }
5161
5162 hddLog(VOS_TRACE_LEVEL_ERROR,
5163 "%s: Invalid Channel [%d]", __func__, channel);
5164 return VOS_STATUS_E_FAILURE;
5165 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005166 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305167
Jeff Johnson295189b2012-06-20 16:38:30 -07005168 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305169
Jeff Johnson295189b2012-06-20 16:38:30 -07005170}
5171
Viral Modi3a32cc52013-02-08 11:14:52 -08005172/**
5173 * FUNCTION: wlan_hdd_cfg80211_set_channel
5174 * This function is used to set the channel number
5175 */
5176static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
5177 struct ieee80211_channel *chan,
5178 enum nl80211_channel_type channel_type
5179 )
5180{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305181 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08005182 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07005183 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08005184 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305185 hdd_context_t *pHddCtx;
5186 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005187
5188 ENTER();
5189
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305190
Viral Modi3a32cc52013-02-08 11:14:52 -08005191 if( NULL == dev )
5192 {
5193 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005194 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005195 return -ENODEV;
5196 }
5197 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305198
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305199 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5200 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
5201 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08005202 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305203 "%s: device_mode = %s (%d) freq = %d", __func__,
5204 hdd_device_modetoString(pAdapter->device_mode),
5205 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305206
5207 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5208 status = wlan_hdd_validate_context(pHddCtx);
5209
5210 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08005211 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305212 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5213 "%s: HDD context is not valid", __func__);
5214 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005215 }
5216
5217 /*
5218 * Do freq to chan conversion
5219 * TODO: for 11a
5220 */
5221
5222 channel = ieee80211_frequency_to_channel(freq);
5223
5224 /* Check freq range */
5225 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
5226 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
5227 {
5228 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005229 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08005230 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
5231 WNI_CFG_CURRENT_CHANNEL_STAMAX);
5232 return -EINVAL;
5233 }
5234
5235 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5236
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05305237 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
5238 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08005239 {
5240 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
5241 {
5242 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005243 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08005244 return -EINVAL;
5245 }
5246 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5247 "%s: set channel to [%d] for device mode =%d",
5248 __func__, channel,pAdapter->device_mode);
5249 }
5250 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08005251 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08005252 )
5253 {
5254 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5255 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
5256 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5257
5258 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
5259 {
5260 /* Link is up then return cant set channel*/
5261 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005262 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005263 return -EINVAL;
5264 }
5265
5266 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
5267 pHddStaCtx->conn_info.operationChannel = channel;
5268 pRoamProfile->ChannelInfo.ChannelList =
5269 &pHddStaCtx->conn_info.operationChannel;
5270 }
5271 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08005272 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08005273 )
5274 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305275 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5276 {
5277 if(VOS_STATUS_SUCCESS !=
5278 wlan_hdd_validate_operation_channel(pAdapter,channel))
5279 {
5280 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005281 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305282 return -EINVAL;
5283 }
5284 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5285 }
5286 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08005287 {
5288 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5289
5290 /* If auto channel selection is configured as enable/ 1 then ignore
5291 channel set by supplicant
5292 */
5293 if ( cfg_param->apAutoChannelSelection )
5294 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305295 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
5296 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08005297 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305298 "%s: set channel to auto channel (0) for device mode =%s (%d)",
5299 __func__, hdd_device_modetoString(pAdapter->device_mode),
5300 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08005301 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305302 else
5303 {
5304 if(VOS_STATUS_SUCCESS !=
5305 wlan_hdd_validate_operation_channel(pAdapter,channel))
5306 {
5307 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005308 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305309 return -EINVAL;
5310 }
5311 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5312 }
Viral Modi3a32cc52013-02-08 11:14:52 -08005313 }
5314 }
5315 else
5316 {
5317 hddLog(VOS_TRACE_LEVEL_FATAL,
5318 "%s: Invalid device mode failed to set valid channel", __func__);
5319 return -EINVAL;
5320 }
5321 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305322 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005323}
5324
Jeff Johnson295189b2012-06-20 16:38:30 -07005325#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5326static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5327 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005328#else
5329static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5330 struct cfg80211_beacon_data *params,
5331 const u8 *ssid, size_t ssid_len,
5332 enum nl80211_hidden_ssid hidden_ssid)
5333#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005334{
5335 tsap_Config_t *pConfig;
5336 beacon_data_t *pBeacon = NULL;
5337 struct ieee80211_mgmt *pMgmt_frame;
5338 v_U8_t *pIe=NULL;
5339 v_U16_t capab_info;
5340 eCsrAuthType RSNAuthType;
5341 eCsrEncryptionType RSNEncryptType;
5342 eCsrEncryptionType mcRSNEncryptType;
5343 int status = VOS_STATUS_SUCCESS;
5344 tpWLAN_SAPEventCB pSapEventCallback;
5345 hdd_hostapd_state_t *pHostapdState;
5346 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
5347 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305348 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005349 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305350 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07005351 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08005352 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Chet Lanctot40142442014-05-20 13:39:25 -07005353 v_BOOL_t MFPCapable = VOS_FALSE;
5354 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305355 eHddDot11Mode sapDot11Mode =
5356 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07005357
5358 ENTER();
5359
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305360 iniConfig = pHddCtx->cfg_ini;
5361
Jeff Johnson295189b2012-06-20 16:38:30 -07005362 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
5363
5364 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5365
5366 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5367
5368 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5369
5370 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
5371
5372 //channel is already set in the set_channel Call back
5373 //pConfig->channel = pCommitConfig->channel;
5374
5375 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305376 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07005377 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
5378
5379 pConfig->dtim_period = pBeacon->dtim_period;
5380
Arif Hussain6d2a3322013-11-17 19:50:10 -08005381 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07005382 pConfig->dtim_period);
5383
5384
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08005385 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07005386 {
5387 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005388 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05305389 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
5390 {
5391 tANI_BOOLEAN restartNeeded;
5392 pConfig->ieee80211d = 1;
5393 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
5394 sme_setRegInfo(hHal, pConfig->countryCode);
5395 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
5396 }
5397 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005398 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07005399 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07005400 pConfig->ieee80211d = 1;
5401 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
5402 sme_setRegInfo(hHal, pConfig->countryCode);
5403 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07005404 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005405 else
5406 {
5407 pConfig->ieee80211d = 0;
5408 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305409 /*
5410 * If auto channel is configured i.e. channel is 0,
5411 * so skip channel validation.
5412 */
5413 if( AUTO_CHANNEL_SELECT != pConfig->channel )
5414 {
5415 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
5416 {
5417 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005418 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305419 return -EINVAL;
5420 }
5421 }
5422 else
5423 {
5424 if(1 != pHddCtx->is_dynamic_channel_range_set)
5425 {
5426 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
5427 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
5428 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
5429 }
5430 pHddCtx->is_dynamic_channel_range_set = 0;
5431 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005432 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005433 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005434 {
5435 pConfig->ieee80211d = 0;
5436 }
5437 pConfig->authType = eSAP_AUTO_SWITCH;
5438
5439 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305440
5441 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07005442 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
5443
5444 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
5445
5446 /*Set wps station to configured*/
5447 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
5448
5449 if(pIe)
5450 {
5451 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
5452 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005453 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07005454 return -EINVAL;
5455 }
5456 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
5457 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005458 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07005459 /* Check 15 bit of WPS IE as it contain information for wps state
5460 * WPS state
5461 */
5462 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
5463 {
5464 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
5465 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
5466 {
5467 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
5468 }
5469 }
5470 }
5471 else
5472 {
5473 pConfig->wps_state = SAP_WPS_DISABLED;
5474 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305475 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07005476
c_hpothufe599e92014-06-16 11:38:55 +05305477 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5478 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5479 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
5480 eCSR_ENCRYPT_TYPE_NONE;
5481
Jeff Johnson295189b2012-06-20 16:38:30 -07005482 pConfig->RSNWPAReqIELength = 0;
5483 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305484 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005485 WLAN_EID_RSN);
5486 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305487 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005488 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5489 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5490 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305491 /* The actual processing may eventually be more extensive than
5492 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07005493 * by the app.
5494 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305495 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005496 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5497 &RSNEncryptType,
5498 &mcRSNEncryptType,
5499 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005500 &MFPCapable,
5501 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005502 pConfig->pRSNWPAReqIE[1]+2,
5503 pConfig->pRSNWPAReqIE );
5504
5505 if( VOS_STATUS_SUCCESS == status )
5506 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305507 /* Now copy over all the security attributes you have
5508 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005509 * */
5510 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5511 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5512 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5513 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305514 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005515 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005516 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5517 }
5518 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305519
Jeff Johnson295189b2012-06-20 16:38:30 -07005520 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5521 pBeacon->tail, pBeacon->tail_len);
5522
5523 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
5524 {
5525 if (pConfig->pRSNWPAReqIE)
5526 {
5527 /*Mixed mode WPA/WPA2*/
5528 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
5529 pConfig->RSNWPAReqIELength += pIe[1] + 2;
5530 }
5531 else
5532 {
5533 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5534 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5535 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305536 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005537 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5538 &RSNEncryptType,
5539 &mcRSNEncryptType,
5540 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005541 &MFPCapable,
5542 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005543 pConfig->pRSNWPAReqIE[1]+2,
5544 pConfig->pRSNWPAReqIE );
5545
5546 if( VOS_STATUS_SUCCESS == status )
5547 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305548 /* Now copy over all the security attributes you have
5549 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005550 * */
5551 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5552 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5553 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5554 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305555 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005556 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005557 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5558 }
5559 }
5560 }
5561
Jeff Johnson4416a782013-03-25 14:17:50 -07005562 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
5563 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
5564 return -EINVAL;
5565 }
5566
Jeff Johnson295189b2012-06-20 16:38:30 -07005567 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
5568
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005569#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005570 if (params->ssid != NULL)
5571 {
5572 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
5573 pConfig->SSIDinfo.ssid.length = params->ssid_len;
5574 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5575 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5576 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005577#else
5578 if (ssid != NULL)
5579 {
5580 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
5581 pConfig->SSIDinfo.ssid.length = ssid_len;
5582 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5583 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5584 }
5585#endif
5586
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305587 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07005588 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305589
Jeff Johnson295189b2012-06-20 16:38:30 -07005590 /* default value */
5591 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
5592 pConfig->num_accept_mac = 0;
5593 pConfig->num_deny_mac = 0;
5594
5595 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5596 pBeacon->tail, pBeacon->tail_len);
5597
5598 /* pIe for black list is following form:
5599 type : 1 byte
5600 length : 1 byte
5601 OUI : 4 bytes
5602 acl type : 1 byte
5603 no of mac addr in black list: 1 byte
5604 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305605 */
5606 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005607 {
5608 pConfig->SapMacaddr_acl = pIe[6];
5609 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08005610 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005611 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305612 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
5613 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005614 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
5615 for (i = 0; i < pConfig->num_deny_mac; i++)
5616 {
5617 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
5618 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305619 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005620 }
5621 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5622 pBeacon->tail, pBeacon->tail_len);
5623
5624 /* pIe for white list is following form:
5625 type : 1 byte
5626 length : 1 byte
5627 OUI : 4 bytes
5628 acl type : 1 byte
5629 no of mac addr in white list: 1 byte
5630 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305631 */
5632 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005633 {
5634 pConfig->SapMacaddr_acl = pIe[6];
5635 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08005636 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005637 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305638 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
5639 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005640 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
5641 for (i = 0; i < pConfig->num_accept_mac; i++)
5642 {
5643 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
5644 acl_entry++;
5645 }
5646 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305647
Jeff Johnson295189b2012-06-20 16:38:30 -07005648 wlan_hdd_set_sapHwmode(pHostapdAdapter);
5649
Jeff Johnsone7245742012-09-05 17:12:55 -07005650#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08005651 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05305652 * This is valid only if mode is set to 11n in hostapd, either AUTO or
5653 * 11ac in .ini and 11ac is supported by both host and firmware.
5654 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
5655 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08005656 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
5657 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305658 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
5659 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
5660 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
5661 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
5662 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07005663 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305664 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07005665 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305666 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005667
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305668 /* If ACS disable and selected channel <= 14
5669 * OR
5670 * ACS enabled and ACS operating band is choosen as 2.4
5671 * AND
5672 * VHT in 2.4G Disabled
5673 * THEN
5674 * Fallback to 11N mode
5675 */
5676 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
5677 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305678 operatingBand == RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305679 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005680 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305681 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
5682 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005683 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
5684 }
Jeff Johnsone7245742012-09-05 17:12:55 -07005685 }
5686#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305687
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07005688 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
5689 {
5690 sme_SelectCBMode(hHal,
5691 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
5692 pConfig->channel);
5693 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005694 // ht_capab is not what the name conveys,this is used for protection bitmap
5695 pConfig->ht_capab =
5696 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
5697
5698 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
5699 {
5700 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
5701 return -EINVAL;
5702 }
5703
5704 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305705 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07005706 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
5707 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305708 pConfig->obssProtEnabled =
5709 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07005710
Chet Lanctot8cecea22014-02-11 19:09:36 -08005711#ifdef WLAN_FEATURE_11W
5712 pConfig->mfpCapable = MFPCapable;
5713 pConfig->mfpRequired = MFPRequired;
5714 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
5715 pConfig->mfpCapable, pConfig->mfpRequired);
5716#endif
5717
Arif Hussain6d2a3322013-11-17 19:50:10 -08005718 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07005719 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08005720 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
5721 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
5722 (int)pConfig->channel);
5723 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
5724 pConfig->SapHw_mode, pConfig->privacy,
5725 pConfig->authType);
5726 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
5727 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
5728 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
5729 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07005730
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305731 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005732 {
5733 //Bss already started. just return.
5734 //TODO Probably it should update some beacon params.
5735 hddLog( LOGE, "Bss Already started...Ignore the request");
5736 EXIT();
5737 return 0;
5738 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305739
Agarwal Ashish51325b52014-06-16 16:50:49 +05305740 if (vos_max_concurrent_connections_reached()) {
5741 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
5742 return -EINVAL;
5743 }
5744
Jeff Johnson295189b2012-06-20 16:38:30 -07005745 pConfig->persona = pHostapdAdapter->device_mode;
5746
5747 pSapEventCallback = hdd_hostapd_SAPEventCB;
5748 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
5749 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
5750 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005751 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005752 return -EINVAL;
5753 }
5754
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305755 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07005756 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
5757
5758 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305759
Jeff Johnson295189b2012-06-20 16:38:30 -07005760 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305761 {
5762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005763 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07005764 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07005765 VOS_ASSERT(0);
5766 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305767
Jeff Johnson295189b2012-06-20 16:38:30 -07005768 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05305769 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005770
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005771#ifdef WLAN_FEATURE_P2P_DEBUG
5772 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
5773 {
5774 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
5775 {
5776 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
5777 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08005778 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005779 }
5780 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
5781 {
5782 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
5783 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08005784 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005785 }
5786 }
5787#endif
5788
Jeff Johnson295189b2012-06-20 16:38:30 -07005789 pHostapdState->bCommit = TRUE;
5790 EXIT();
5791
5792 return 0;
5793}
5794
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005795#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305796static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
5797 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005798 struct beacon_parameters *params)
5799{
5800 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305801 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305802 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005803
5804 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305805
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305806 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5807 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
5808 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305809 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
5810 hdd_device_modetoString(pAdapter->device_mode),
5811 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005812
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305813 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5814 status = wlan_hdd_validate_context(pHddCtx);
5815
5816 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005817 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305818 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5819 "%s: HDD context is not valid", __func__);
5820 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005821 }
5822
Agarwal Ashish51325b52014-06-16 16:50:49 +05305823 if (vos_max_concurrent_connections_reached()) {
5824 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
5825 return -EINVAL;
5826 }
5827
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305828 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005829 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005830 )
5831 {
5832 beacon_data_t *old,*new;
5833
5834 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305835
Jeff Johnson295189b2012-06-20 16:38:30 -07005836 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305837 {
5838 hddLog(VOS_TRACE_LEVEL_WARN,
5839 FL("already beacon info added to session(%d)"),
5840 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005841 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305842 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005843
5844 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
5845
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305846 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07005847 {
5848 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005849 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005850 return -EINVAL;
5851 }
5852
5853 pAdapter->sessionCtx.ap.beacon = new;
5854
5855 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
5856 }
5857
5858 EXIT();
5859 return status;
5860}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305861
5862static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005863 struct net_device *dev,
5864 struct beacon_parameters *params)
5865{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305866 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305867 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5868 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305869 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005870
5871 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305872 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5873 TRACE_CODE_HDD_CFG80211_SET_BEACON,
5874 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
5875 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5876 __func__, hdd_device_modetoString(pAdapter->device_mode),
5877 pAdapter->device_mode);
5878
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305879 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5880 status = wlan_hdd_validate_context(pHddCtx);
5881
5882 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005883 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305884 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5885 "%s: HDD context is not valid", __func__);
5886 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005887 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305888
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305889 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005890 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305891 )
Jeff Johnson295189b2012-06-20 16:38:30 -07005892 {
5893 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305894
Jeff Johnson295189b2012-06-20 16:38:30 -07005895 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305896
Jeff Johnson295189b2012-06-20 16:38:30 -07005897 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305898 {
5899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5900 FL("session(%d) old and new heads points to NULL"),
5901 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005902 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305903 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005904
5905 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
5906
5907 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305908 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005909 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005910 return -EINVAL;
5911 }
5912
5913 pAdapter->sessionCtx.ap.beacon = new;
5914
5915 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
5916 }
5917
5918 EXIT();
5919 return status;
5920}
5921
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005922#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5923
5924#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005925static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
5926 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005927#else
5928static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
5929 struct net_device *dev)
5930#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005931{
5932 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07005933 hdd_context_t *pHddCtx = NULL;
5934 hdd_scaninfo_t *pScanInfo = NULL;
5935 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305936 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305937 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005938
5939 ENTER();
5940
5941 if (NULL == pAdapter)
5942 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305943 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005944 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005945 return -ENODEV;
5946 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005947
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305948 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5949 TRACE_CODE_HDD_CFG80211_STOP_AP,
5950 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305951 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5952 status = wlan_hdd_validate_context(pHddCtx);
5953
5954 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005955 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5957 "%s: HDD context is not valid", __func__);
5958 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07005959 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005960
5961 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
5962 if (NULL == staAdapter)
5963 {
5964 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
5965 if (NULL == staAdapter)
5966 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07005967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5968 "%s: HDD adapter context for STA/P2P-CLI is Null",
5969 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005970 }
5971 }
5972
5973 pScanInfo = &pHddCtx->scan_info;
5974
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305975 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5976 __func__, hdd_device_modetoString(pAdapter->device_mode),
5977 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005978
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305979 ret = wlan_hdd_scan_abort(pAdapter);
5980
Girish Gowli4bf7a632014-06-12 13:42:11 +05305981 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07005982 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305983 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5984 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305985
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305986 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07005987 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5989 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08005990
Jeff Johnsone7245742012-09-05 17:12:55 -07005991 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305992 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07005993 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305994 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07005995 }
5996
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05305997 hdd_hostapd_stop(dev);
5998
Jeff Johnson295189b2012-06-20 16:38:30 -07005999 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006000 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006001 )
6002 {
6003 beacon_data_t *old;
6004
6005 old = pAdapter->sessionCtx.ap.beacon;
6006
6007 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306008 {
6009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6010 FL("session(%d) beacon data points to NULL"),
6011 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006012 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306013 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006014
Jeff Johnson295189b2012-06-20 16:38:30 -07006015 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006016
6017 mutex_lock(&pHddCtx->sap_lock);
6018 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6019 {
Jeff Johnson4416a782013-03-25 14:17:50 -07006020 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006021 {
6022 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6023
6024 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6025
6026 if (!VOS_IS_STATUS_SUCCESS(status))
6027 {
6028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006029 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006030 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306031 }
6032 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006033 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306034 /* BSS stopped, clear the active sessions for this device mode */
6035 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006036 }
6037 mutex_unlock(&pHddCtx->sap_lock);
6038
6039 if(status != VOS_STATUS_SUCCESS)
6040 {
6041 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006042 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006043 return -EINVAL;
6044 }
6045
Jeff Johnson4416a782013-03-25 14:17:50 -07006046 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006047 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
6048 ==eHAL_STATUS_FAILURE)
6049 {
6050 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006051 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006052 }
6053
Jeff Johnson4416a782013-03-25 14:17:50 -07006054 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006055 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6056 eANI_BOOLEAN_FALSE) )
6057 {
6058 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006059 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006060 }
6061
6062 // Reset WNI_CFG_PROBE_RSP Flags
6063 wlan_hdd_reset_prob_rspies(pAdapter);
6064
6065 pAdapter->sessionCtx.ap.beacon = NULL;
6066 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006067#ifdef WLAN_FEATURE_P2P_DEBUG
6068 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
6069 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
6070 {
6071 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
6072 "GO got removed");
6073 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
6074 }
6075#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006076 }
6077 EXIT();
6078 return status;
6079}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006080
6081#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6082
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306083static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
6084 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006085 struct cfg80211_ap_settings *params)
6086{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306087 hdd_adapter_t *pAdapter;
6088 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306089 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006090
6091 ENTER();
6092
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306093 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006094 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306096 "%s: Device is Null", __func__);
6097 return -ENODEV;
6098 }
6099
6100 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6101 if (NULL == pAdapter)
6102 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306104 "%s: HDD adapter is Null", __func__);
6105 return -ENODEV;
6106 }
6107
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306108 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6109 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
6110 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306111 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6112 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306114 "%s: HDD adapter magic is invalid", __func__);
6115 return -ENODEV;
6116 }
6117
6118 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306119 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306120
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306121 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306122 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6124 "%s: HDD context is not valid", __func__);
6125 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306126 }
6127
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306128 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
6129 __func__, hdd_device_modetoString(pAdapter->device_mode),
6130 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306131
6132 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006133 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006134 )
6135 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306136 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006137
6138 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306139
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006140 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306141 {
6142 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
6143 FL("already beacon info added to session(%d)"),
6144 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006145 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306146 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006147
6148 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
6149
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306150 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006151 {
6152 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306153 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006154 return -EINVAL;
6155 }
6156 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08006157#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07006158 wlan_hdd_cfg80211_set_channel(wiphy, dev,
6159#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
6160 params->channel, params->channel_type);
6161#else
6162 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
6163#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08006164#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006165 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
6166 params->ssid_len, params->hidden_ssid);
6167 }
6168
6169 EXIT();
6170 return status;
6171}
6172
6173
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306174static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006175 struct net_device *dev,
6176 struct cfg80211_beacon_data *params)
6177{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306178 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306179 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306180 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006181
6182 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306183
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306184 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6185 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
6186 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006187 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006188 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306189
6190 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6191 status = wlan_hdd_validate_context(pHddCtx);
6192
6193 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006194 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6196 "%s: HDD context is not valid", __func__);
6197 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006198 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006199
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306200 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006201 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306202 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006203 {
6204 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306205
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006206 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306207
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006208 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306209 {
6210 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6211 FL("session(%d) beacon data points to NULL"),
6212 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006213 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306214 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006215
6216 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
6217
6218 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306219 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006220 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006221 return -EINVAL;
6222 }
6223
6224 pAdapter->sessionCtx.ap.beacon = new;
6225
6226 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
6227 }
6228
6229 EXIT();
6230 return status;
6231}
6232
6233#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6234
Jeff Johnson295189b2012-06-20 16:38:30 -07006235
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306236static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006237 struct net_device *dev,
6238 struct bss_parameters *params)
6239{
6240 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6241
6242 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306243
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306244 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6245 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
6246 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306247 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6248 __func__, hdd_device_modetoString(pAdapter->device_mode),
6249 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006250
6251 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006252 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306253 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006254 {
6255 /* ap_isolate == -1 means that in change bss, upper layer doesn't
6256 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306257 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07006258 {
6259 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306260 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006261 }
6262
6263 EXIT();
6264 return 0;
6265}
6266
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306267static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
6268 struct net_device *dev,
6269 struct bss_parameters *params)
6270{
6271 int ret;
6272
6273 vos_ssr_protect(__func__);
6274 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
6275 vos_ssr_unprotect(__func__);
6276
6277 return ret;
6278}
Kiet Lam10841362013-11-01 11:36:50 +05306279/* FUNCTION: wlan_hdd_change_country_code_cd
6280* to wait for contry code completion
6281*/
6282void* wlan_hdd_change_country_code_cb(void *pAdapter)
6283{
6284 hdd_adapter_t *call_back_pAdapter = pAdapter;
6285 complete(&call_back_pAdapter->change_country_code);
6286 return NULL;
6287}
6288
Jeff Johnson295189b2012-06-20 16:38:30 -07006289/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306290 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07006291 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
6292 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306293int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006294 struct net_device *ndev,
6295 enum nl80211_iftype type,
6296 u32 *flags,
6297 struct vif_params *params
6298 )
6299{
6300 struct wireless_dev *wdev;
6301 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006302 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07006303 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006304 tCsrRoamProfile *pRoamProfile = NULL;
6305 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306306 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006307 eMib_dot11DesiredBssType connectedBssType;
6308 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306309 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006310
6311 ENTER();
6312
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306313 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006314 {
6315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6316 "%s: Adapter context is null", __func__);
6317 return VOS_STATUS_E_FAILURE;
6318 }
6319
6320 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6321 if (!pHddCtx)
6322 {
6323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6324 "%s: HDD context is null", __func__);
6325 return VOS_STATUS_E_FAILURE;
6326 }
6327
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306328 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6329 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
6330 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306331 status = wlan_hdd_validate_context(pHddCtx);
6332
6333 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006334 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306335 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6336 "%s: HDD context is not valid", __func__);
6337 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006338 }
6339
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306340 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6341 __func__, hdd_device_modetoString(pAdapter->device_mode),
6342 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006343
Agarwal Ashish51325b52014-06-16 16:50:49 +05306344 if (vos_max_concurrent_connections_reached()) {
6345 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6346 return -EINVAL;
6347 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306348 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006349 wdev = ndev->ieee80211_ptr;
6350
6351#ifdef WLAN_BTAMP_FEATURE
6352 if((NL80211_IFTYPE_P2P_CLIENT == type)||
6353 (NL80211_IFTYPE_ADHOC == type)||
6354 (NL80211_IFTYPE_AP == type)||
6355 (NL80211_IFTYPE_P2P_GO == type))
6356 {
6357 pHddCtx->isAmpAllowed = VOS_FALSE;
6358 // stop AMP traffic
6359 status = WLANBAP_StopAmp();
6360 if(VOS_STATUS_SUCCESS != status )
6361 {
6362 pHddCtx->isAmpAllowed = VOS_TRUE;
6363 hddLog(VOS_TRACE_LEVEL_FATAL,
6364 "%s: Failed to stop AMP", __func__);
6365 return -EINVAL;
6366 }
6367 }
6368#endif //WLAN_BTAMP_FEATURE
6369 /* Reset the current device mode bit mask*/
6370 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6371
6372 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07006373 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07006374 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07006375 )
6376 {
6377 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006378 if (!pWextState)
6379 {
6380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6381 "%s: pWextState is null", __func__);
6382 return VOS_STATUS_E_FAILURE;
6383 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006384 pRoamProfile = &pWextState->roamProfile;
6385 LastBSSType = pRoamProfile->BSSType;
6386
6387 switch (type)
6388 {
6389 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006390 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006391 hddLog(VOS_TRACE_LEVEL_INFO,
6392 "%s: setting interface Type to INFRASTRUCTURE", __func__);
6393 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07006394#ifdef WLAN_FEATURE_11AC
6395 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
6396 {
6397 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
6398 }
6399#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306400 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07006401 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006402 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006403 //Check for sub-string p2p to confirm its a p2p interface
6404 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306405 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006406 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6407 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6408 }
6409 else
6410 {
6411 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006412 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006413 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306414#ifdef FEATURE_WLAN_TDLS
6415 /* The open adapter for the p2p shall skip initializations in
6416 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
6417 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
6418 * tdls_init when the change_iface sets the device mode to
6419 * WLAN_HDD_P2P_CLIENT.
6420 */
6421
6422 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
6423 {
Agarwal Ashish4b87f922014-06-18 03:03:21 +05306424 if (0 != wlan_hdd_sta_tdls_init (pAdapter))
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306425 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306426 hddLog(VOS_TRACE_LEVEL_ERROR,
6427 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306428 return -EINVAL;
6429 }
6430 }
6431#endif
6432
Jeff Johnson295189b2012-06-20 16:38:30 -07006433 break;
6434 case NL80211_IFTYPE_ADHOC:
6435 hddLog(VOS_TRACE_LEVEL_INFO,
6436 "%s: setting interface Type to ADHOC", __func__);
6437 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
6438 pRoamProfile->phyMode =
6439 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07006440 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006441 wdev->iftype = type;
6442 break;
6443
6444 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006445 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006446 {
6447 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6448 "%s: setting interface Type to %s", __func__,
6449 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
6450
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006451 //Cancel any remain on channel for GO mode
6452 if (NL80211_IFTYPE_P2P_GO == type)
6453 {
6454 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
6455 }
Mohit Khanna0f232092012-09-11 14:46:08 -07006456 if (NL80211_IFTYPE_AP == type)
6457 {
6458 /* As Loading WLAN Driver one interface being created for p2p device
6459 * address. This will take one HW STA and the max number of clients
6460 * that can connect to softAP will be reduced by one. so while changing
6461 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
6462 * interface as it is not required in SoftAP mode.
6463 */
6464
6465 // Get P2P Adapter
6466 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
6467
6468 if (pP2pAdapter)
6469 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306470 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07006471 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
6472 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
6473 }
6474 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05306475 //Disable IMPS & BMPS for SAP/GO
6476 if(VOS_STATUS_E_FAILURE ==
6477 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
6478 {
6479 //Fail to Exit BMPS
6480 VOS_ASSERT(0);
6481 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306482#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07006483
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306484 /* A Mutex Lock is introduced while changing the mode to
6485 * protect the concurrent access for the Adapters by TDLS
6486 * module.
6487 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306488 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306489#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006490 //De-init the adapter.
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306491 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006492 hdd_deinit_adapter( pHddCtx, pAdapter );
6493 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07006494 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6495 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306496#ifdef FEATURE_WLAN_TDLS
6497 mutex_unlock(&pHddCtx->tdls_lock);
6498#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006499 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
6500 (pConfig->apRandomBssidEnabled))
6501 {
6502 /* To meet Android requirements create a randomized
6503 MAC address of the form 02:1A:11:Fx:xx:xx */
6504 get_random_bytes(&ndev->dev_addr[3], 3);
6505 ndev->dev_addr[0] = 0x02;
6506 ndev->dev_addr[1] = 0x1A;
6507 ndev->dev_addr[2] = 0x11;
6508 ndev->dev_addr[3] |= 0xF0;
6509 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
6510 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08006511 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
6512 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006513 }
6514
Jeff Johnson295189b2012-06-20 16:38:30 -07006515 hdd_set_ap_ops( pAdapter->dev );
6516
Kiet Lam10841362013-11-01 11:36:50 +05306517 /* This is for only SAP mode where users can
6518 * control country through ini.
6519 * P2P GO follows station country code
6520 * acquired during the STA scanning. */
6521 if((NL80211_IFTYPE_AP == type) &&
6522 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
6523 {
6524 int status = 0;
6525 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
6526 "%s: setting country code from INI ", __func__);
6527 init_completion(&pAdapter->change_country_code);
6528 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
6529 (void *)(tSmeChangeCountryCallback)
6530 wlan_hdd_change_country_code_cb,
6531 pConfig->apCntryCode, pAdapter,
6532 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05306533 eSIR_FALSE,
6534 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05306535 if (eHAL_STATUS_SUCCESS == status)
6536 {
6537 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306538 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05306539 &pAdapter->change_country_code,
6540 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306541 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05306542 {
6543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306544 FL("SME Timed out while setting country code %ld"),
6545 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08006546
6547 if (pHddCtx->isLogpInProgress)
6548 {
6549 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6550 "%s: LOGP in Progress. Ignore!!!", __func__);
6551 return -EAGAIN;
6552 }
Kiet Lam10841362013-11-01 11:36:50 +05306553 }
6554 }
6555 else
6556 {
6557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006558 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05306559 return -EINVAL;
6560 }
6561 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006562 status = hdd_init_ap_mode(pAdapter);
6563 if(status != VOS_STATUS_SUCCESS)
6564 {
6565 hddLog(VOS_TRACE_LEVEL_FATAL,
6566 "%s: Error initializing the ap mode", __func__);
6567 return -EINVAL;
6568 }
6569 hdd_set_conparam(1);
6570
Jeff Johnson295189b2012-06-20 16:38:30 -07006571 /*interface type changed update in wiphy structure*/
6572 if(wdev)
6573 {
6574 wdev->iftype = type;
6575 pHddCtx->change_iface = type;
6576 }
6577 else
6578 {
6579 hddLog(VOS_TRACE_LEVEL_ERROR,
6580 "%s: ERROR !!!! Wireless dev is NULL", __func__);
6581 return -EINVAL;
6582 }
6583 goto done;
6584 }
6585
6586 default:
6587 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
6588 __func__);
6589 return -EOPNOTSUPP;
6590 }
6591 }
6592 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006593 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006594 )
6595 {
6596 switch(type)
6597 {
6598 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006599 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006600 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306601#ifdef FEATURE_WLAN_TDLS
6602
6603 /* A Mutex Lock is introduced while changing the mode to
6604 * protect the concurrent access for the Adapters by TDLS
6605 * module.
6606 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306607 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306608#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306609 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson32d95a32012-09-10 13:15:23 -07006610 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006611 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006612 //Check for sub-string p2p to confirm its a p2p interface
6613 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006614 {
6615 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6616 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6617 }
6618 else
6619 {
6620 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006621 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006622 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006623 hdd_set_conparam(0);
6624 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006625 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
6626 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306627#ifdef FEATURE_WLAN_TDLS
6628 mutex_unlock(&pHddCtx->tdls_lock);
6629#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306630 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006631 if( VOS_STATUS_SUCCESS != status )
6632 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07006633 /* In case of JB, for P2P-GO, only change interface will be called,
6634 * This is the right place to enable back bmps_imps()
6635 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306636 if (pHddCtx->hdd_wlan_suspended)
6637 {
6638 hdd_set_pwrparams(pHddCtx);
6639 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006640 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006641 goto done;
6642 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006643 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006644 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006645 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6646 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006647 goto done;
6648 default:
6649 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
6650 __func__);
6651 return -EOPNOTSUPP;
6652
6653 }
6654
6655 }
6656 else
6657 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306658 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
6659 __func__, hdd_device_modetoString(pAdapter->device_mode),
6660 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006661 return -EOPNOTSUPP;
6662 }
6663
6664
6665 if(pRoamProfile)
6666 {
6667 if ( LastBSSType != pRoamProfile->BSSType )
6668 {
6669 /*interface type changed update in wiphy structure*/
6670 wdev->iftype = type;
6671
6672 /*the BSS mode changed, We need to issue disconnect
6673 if connected or in IBSS disconnect state*/
6674 if ( hdd_connGetConnectedBssType(
6675 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
6676 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
6677 {
6678 /*need to issue a disconnect to CSR.*/
6679 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6680 if( eHAL_STATUS_SUCCESS ==
6681 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6682 pAdapter->sessionId,
6683 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6684 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306685 ret = wait_for_completion_interruptible_timeout(
6686 &pAdapter->disconnect_comp_var,
6687 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6688 if (ret <= 0)
6689 {
6690 hddLog(VOS_TRACE_LEVEL_ERROR,
6691 FL("wait on disconnect_comp_var failed %ld"), ret);
6692 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006693 }
6694 }
6695 }
6696 }
6697
6698done:
6699 /*set bitmask based on updated value*/
6700 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07006701
6702 /* Only STA mode support TM now
6703 * all other mode, TM feature should be disabled */
6704 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
6705 (~VOS_STA & pHddCtx->concurrency_mode) )
6706 {
6707 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
6708 }
6709
Jeff Johnson295189b2012-06-20 16:38:30 -07006710#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306711 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05306712 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07006713 {
6714 //we are ok to do AMP
6715 pHddCtx->isAmpAllowed = VOS_TRUE;
6716 }
6717#endif //WLAN_BTAMP_FEATURE
6718 EXIT();
6719 return 0;
6720}
6721
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306722/*
6723 * FUNCTION: wlan_hdd_cfg80211_change_iface
6724 * wrapper function to protect the actual implementation from SSR.
6725 */
6726int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
6727 struct net_device *ndev,
6728 enum nl80211_iftype type,
6729 u32 *flags,
6730 struct vif_params *params
6731 )
6732{
6733 int ret;
6734
6735 vos_ssr_protect(__func__);
6736 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
6737 vos_ssr_unprotect(__func__);
6738
6739 return ret;
6740}
6741
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006742#ifdef FEATURE_WLAN_TDLS
6743static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
6744 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
6745{
6746 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6747 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6748 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006749 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306750 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306751 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006752
6753 ENTER();
6754
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306755 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006756 {
6757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6758 "Invalid arguments");
6759 return -EINVAL;
6760 }
Hoonki Lee27511902013-03-14 18:19:06 -07006761
6762 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
6763 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
6764 {
6765 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6766 "%s: TDLS mode is disabled OR not enabled in FW."
6767 MAC_ADDRESS_STR " Request declined.",
6768 __func__, MAC_ADDR_ARRAY(mac));
6769 return -ENOTSUPP;
6770 }
6771
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006772 if (pHddCtx->isLogpInProgress)
6773 {
6774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6775 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006776 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006777 return -EBUSY;
6778 }
6779
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05306780 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006781
6782 if ( NULL == pTdlsPeer ) {
6783 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6784 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
6785 __func__, MAC_ADDR_ARRAY(mac), update);
6786 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006787 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006788
6789 /* in add station, we accept existing valid staId if there is */
6790 if ((0 == update) &&
6791 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
6792 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006793 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006794 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006795 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006796 " link_status %d. staId %d. add station ignored.",
6797 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
6798 return 0;
6799 }
6800 /* in change station, we accept only when staId is valid */
6801 if ((1 == update) &&
6802 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
6803 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
6804 {
6805 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6806 "%s: " MAC_ADDRESS_STR
6807 " link status %d. staId %d. change station %s.",
6808 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
6809 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
6810 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006811 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006812
6813 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306814 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006815 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006816 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6817 "%s: " MAC_ADDRESS_STR
6818 " TDLS setup is ongoing. Request declined.",
6819 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07006820 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006821 }
6822
6823 /* first to check if we reached to maximum supported TDLS peer.
6824 TODO: for now, return -EPERM looks working fine,
6825 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306826 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
6827 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006828 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006829 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6830 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306831 " TDLS Max peer already connected. Request declined."
6832 " Num of peers (%d), Max allowed (%d).",
6833 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
6834 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006835 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006836 }
6837 else
6838 {
6839 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306840 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006841 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006842 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6844 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
6845 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006846 return -EPERM;
6847 }
6848 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006849 if (0 == update)
6850 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006851
Jeff Johnsond75fe012013-04-06 10:53:06 -07006852 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306853 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006854 {
6855 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6856 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07006857 if(StaParams->htcap_present)
6858 {
6859 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6860 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
6861 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6862 "ht_capa->extended_capabilities: %0x",
6863 StaParams->HTCap.extendedHtCapInfo);
6864 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006865 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6866 "params->capability: %0x",StaParams->capability);
6867 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006868 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07006869 if(StaParams->vhtcap_present)
6870 {
6871 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6872 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
6873 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
6874 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
6875 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006876 {
6877 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006878 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006879 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
6880 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6881 "[%d]: %x ", i, StaParams->supported_rates[i]);
6882 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07006883 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306884 else if ((1 == update) && (NULL == StaParams))
6885 {
6886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6887 "%s : update is true, but staParams is NULL. Error!", __func__);
6888 return -EPERM;
6889 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006890
6891 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
6892
6893 if (!update)
6894 {
6895 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6896 pAdapter->sessionId, mac);
6897 }
6898 else
6899 {
6900 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6901 pAdapter->sessionId, mac, StaParams);
6902 }
6903
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306904 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006905 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
6906
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306907 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006908 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006909 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306910 "%s: timeout waiting for tdls add station indication %ld",
6911 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006912 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006913 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306914
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006915 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
6916 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006918 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006919 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006920 }
6921
6922 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07006923
6924error:
6925 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
6926 return -EPERM;
6927
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006928}
6929#endif
6930
Jeff Johnson295189b2012-06-20 16:38:30 -07006931static int wlan_hdd_change_station(struct wiphy *wiphy,
6932 struct net_device *dev,
6933 u8 *mac,
6934 struct station_parameters *params)
6935{
6936 VOS_STATUS status = VOS_STATUS_SUCCESS;
6937 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05306938 hdd_context_t *pHddCtx;
6939 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006940 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07006941#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006942 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006943 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05306944 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07006945#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07006946 ENTER();
6947
Gopichand Nakkala29149562013-05-10 21:43:41 +05306948 if ((NULL == pAdapter))
6949 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306950 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05306951 "invalid adapter ");
6952 return -EINVAL;
6953 }
6954
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306955 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6956 TRACE_CODE_HDD_CHANGE_STATION,
6957 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05306958 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6959 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6960
6961 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
6962 {
6963 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6964 "invalid HDD state or HDD station context");
6965 return -EINVAL;
6966 }
6967
6968 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006969 {
6970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6971 "%s:LOGP in Progress. Ignore!!!", __func__);
6972 return -EAGAIN;
6973 }
6974
Jeff Johnson295189b2012-06-20 16:38:30 -07006975 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
6976
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006977 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
6978 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07006979 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006980 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07006981 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306982 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07006983 WLANTL_STA_AUTHENTICATED);
6984
Gopichand Nakkala29149562013-05-10 21:43:41 +05306985 if (status != VOS_STATUS_SUCCESS)
6986 {
6987 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6988 "%s: Not able to change TL state to AUTHENTICATED", __func__);
6989 return -EINVAL;
6990 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006991 }
6992 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07006993 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6994 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05306995#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006996 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6997 StaParams.capability = params->capability;
6998 StaParams.uapsd_queues = params->uapsd_queues;
6999 StaParams.max_sp = params->max_sp;
7000
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307001 /* Convert (first channel , number of channels) tuple to
7002 * the total list of channels. This goes with the assumption
7003 * that if the first channel is < 14, then the next channels
7004 * are an incremental of 1 else an incremental of 4 till the number
7005 * of channels.
7006 */
7007 if (0 != params->supported_channels_len) {
7008 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
7009 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
7010 {
7011 int wifi_chan_index;
7012 StaParams.supported_channels[j] = params->supported_channels[i];
7013 wifi_chan_index =
7014 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
7015 no_of_channels = params->supported_channels[i+1];
7016 for(k=1; k <= no_of_channels; k++)
7017 {
7018 StaParams.supported_channels[j+1] =
7019 StaParams.supported_channels[j] + wifi_chan_index;
7020 j+=1;
7021 }
7022 }
7023 StaParams.supported_channels_len = j;
7024 }
7025 vos_mem_copy(StaParams.supported_oper_classes,
7026 params->supported_oper_classes,
7027 params->supported_oper_classes_len);
7028 StaParams.supported_oper_classes_len =
7029 params->supported_oper_classes_len;
7030
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007031 if (0 != params->ext_capab_len)
7032 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
7033 sizeof(StaParams.extn_capability));
7034
7035 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007036 {
7037 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007038 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007039 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007040
7041 StaParams.supported_rates_len = params->supported_rates_len;
7042
7043 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
7044 * The supported_rates array , for all the structures propogating till Add Sta
7045 * to the firmware has to be modified , if the supplicant (ieee80211) is
7046 * modified to send more rates.
7047 */
7048
7049 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
7050 */
7051 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
7052 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
7053
7054 if (0 != StaParams.supported_rates_len) {
7055 int i = 0;
7056 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
7057 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007059 "Supported Rates with Length %d", StaParams.supported_rates_len);
7060 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007061 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007062 "[%d]: %0x", i, StaParams.supported_rates[i]);
7063 }
7064
7065 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007066 {
7067 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007068 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007069 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007070
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007071 if (0 != params->ext_capab_len ) {
7072 /*Define A Macro : TODO Sunil*/
7073 if ((1<<4) & StaParams.extn_capability[3]) {
7074 isBufSta = 1;
7075 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307076 /* TDLS Channel Switching Support */
7077 if ((1<<6) & StaParams.extn_capability[3]) {
7078 isOffChannelSupported = 1;
7079 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007080 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307081 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
7082 &StaParams, isBufSta,
7083 isOffChannelSupported);
7084
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307085 if (VOS_STATUS_SUCCESS != status) {
7086 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7087 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
7088 return -EINVAL;
7089 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007090 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
7091
7092 if (VOS_STATUS_SUCCESS != status) {
7093 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7094 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
7095 return -EINVAL;
7096 }
7097 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007098#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05307099 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007100 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007101 return status;
7102}
7103
7104/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307105 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007106 * This function is used to initialize the key information
7107 */
7108#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307109static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007110 struct net_device *ndev,
7111 u8 key_index, bool pairwise,
7112 const u8 *mac_addr,
7113 struct key_params *params
7114 )
7115#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307116static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007117 struct net_device *ndev,
7118 u8 key_index, const u8 *mac_addr,
7119 struct key_params *params
7120 )
7121#endif
7122{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007123 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007124 tCsrRoamSetKey setKey;
7125 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307126 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007127 v_U32_t roamId= 0xFF;
7128 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007129 hdd_hostapd_state_t *pHostapdState;
7130 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007131 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307132 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007133
7134 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307135
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307136 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7137 TRACE_CODE_HDD_CFG80211_ADD_KEY,
7138 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307139 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7140 status = wlan_hdd_validate_context(pHddCtx);
7141
7142 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007143 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7145 "%s: HDD context is not valid", __func__);
7146 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007147 }
7148
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307149 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7150 __func__, hdd_device_modetoString(pAdapter->device_mode),
7151 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007152
7153 if (CSR_MAX_NUM_KEY <= key_index)
7154 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007155 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007156 key_index);
7157
7158 return -EINVAL;
7159 }
7160
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007161 if (CSR_MAX_KEY_LEN < params->key_len)
7162 {
7163 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
7164 params->key_len);
7165
7166 return -EINVAL;
7167 }
7168
7169 hddLog(VOS_TRACE_LEVEL_INFO,
7170 "%s: called with key index = %d & key length %d",
7171 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07007172
7173 /*extract key idx, key len and key*/
7174 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7175 setKey.keyId = key_index;
7176 setKey.keyLength = params->key_len;
7177 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
7178
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007179 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07007180 {
7181 case WLAN_CIPHER_SUITE_WEP40:
7182 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
7183 break;
7184
7185 case WLAN_CIPHER_SUITE_WEP104:
7186 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
7187 break;
7188
7189 case WLAN_CIPHER_SUITE_TKIP:
7190 {
7191 u8 *pKey = &setKey.Key[0];
7192 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
7193
7194 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
7195
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007196 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07007197
7198 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007199 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007200 |--------------|----------|----------|
7201 <---16bytes---><--8bytes--><--8bytes-->
7202
7203 */
7204 /*Sme expects the 32 bytes key to be in the below order
7205
7206 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007207 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007208 |--------------|----------|----------|
7209 <---16bytes---><--8bytes--><--8bytes-->
7210 */
7211 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007212 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07007213
7214 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007215 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007216
7217 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007218 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007219
7220
7221 break;
7222 }
7223
7224 case WLAN_CIPHER_SUITE_CCMP:
7225 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
7226 break;
7227
7228#ifdef FEATURE_WLAN_WAPI
7229 case WLAN_CIPHER_SUITE_SMS4:
7230 {
7231 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7232 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
7233 params->key, params->key_len);
7234 return 0;
7235 }
7236#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007237
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007238#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07007239 case WLAN_CIPHER_SUITE_KRK:
7240 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
7241 break;
7242#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007243
7244#ifdef WLAN_FEATURE_11W
7245 case WLAN_CIPHER_SUITE_AES_CMAC:
7246 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07007247 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07007248#endif
7249
Jeff Johnson295189b2012-06-20 16:38:30 -07007250 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007251 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07007252 __func__, params->cipher);
7253 return -EOPNOTSUPP;
7254 }
7255
7256 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
7257 __func__, setKey.encType);
7258
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007259 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07007260#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7261 (!pairwise)
7262#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007263 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07007264#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007265 )
7266 {
7267 /* set group key*/
7268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7269 "%s- %d: setting Broadcast key",
7270 __func__, __LINE__);
7271 setKey.keyDirection = eSIR_RX_ONLY;
7272 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7273 }
7274 else
7275 {
7276 /* set pairwise key*/
7277 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7278 "%s- %d: setting pairwise key",
7279 __func__, __LINE__);
7280 setKey.keyDirection = eSIR_TX_RX;
7281 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7282 }
7283 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
7284 {
7285 setKey.keyDirection = eSIR_TX_RX;
7286 /*Set the group key*/
7287 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7288 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07007289
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007290 if ( 0 != status )
7291 {
7292 hddLog(VOS_TRACE_LEVEL_ERROR,
7293 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7294 return -EINVAL;
7295 }
7296 /*Save the keys here and call sme_RoamSetKey for setting
7297 the PTK after peer joins the IBSS network*/
7298 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
7299 &setKey, sizeof(tCsrRoamSetKey));
7300 return status;
7301 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05307302 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
7303 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
7304 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007305 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007306 if( pHostapdState->bssState == BSS_START )
7307 {
c_hpothu7c55da62014-01-23 18:34:02 +05307308 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7309 vos_status = wlan_hdd_check_ula_done(pAdapter);
7310
7311 if ( vos_status != VOS_STATUS_SUCCESS )
7312 {
7313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7314 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7315 __LINE__, vos_status );
7316
7317 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7318
7319 return -EINVAL;
7320 }
7321
Jeff Johnson295189b2012-06-20 16:38:30 -07007322 status = WLANSAP_SetKeySta( pVosContext, &setKey);
7323
7324 if ( status != eHAL_STATUS_SUCCESS )
7325 {
7326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7327 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7328 __LINE__, status );
7329 }
7330 }
7331
7332 /* Saving WEP keys */
7333 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
7334 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
7335 {
7336 //Save the wep key in ap context. Issue setkey after the BSS is started.
7337 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7338 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
7339 }
7340 else
7341 {
7342 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007343 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007344 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
7345 }
7346 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007347 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
7348 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007349 {
7350 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7351 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7352
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307353#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7354 if (!pairwise)
7355#else
7356 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
7357#endif
7358 {
7359 /* set group key*/
7360 if (pHddStaCtx->roam_info.deferKeyComplete)
7361 {
7362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7363 "%s- %d: Perform Set key Complete",
7364 __func__, __LINE__);
7365 hdd_PerformRoamSetKeyComplete(pAdapter);
7366 }
7367 }
7368
Jeff Johnson295189b2012-06-20 16:38:30 -07007369 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
7370
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08007371 pWextState->roamProfile.Keys.defaultIndex = key_index;
7372
7373
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007374 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007375 params->key, params->key_len);
7376
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307377
Jeff Johnson295189b2012-06-20 16:38:30 -07007378 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7379
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307380 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007381 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307382 __func__, setKey.peerMac[0], setKey.peerMac[1],
7383 setKey.peerMac[2], setKey.peerMac[3],
7384 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007385 setKey.keyDirection);
7386
7387 vos_status = wlan_hdd_check_ula_done(pAdapter);
7388
7389 if ( vos_status != VOS_STATUS_SUCCESS )
7390 {
7391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7392 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7393 __LINE__, vos_status );
7394
7395 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7396
7397 return -EINVAL;
7398
7399 }
7400
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007401#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307402 /* The supplicant may attempt to set the PTK once pre-authentication
7403 is done. Save the key in the UMAC and include it in the ADD BSS
7404 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007405 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307406 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007407 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307408 hddLog(VOS_TRACE_LEVEL_INFO_MED,
7409 "%s: Update PreAuth Key success", __func__);
7410 return 0;
7411 }
7412 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
7413 {
7414 hddLog(VOS_TRACE_LEVEL_ERROR,
7415 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05307416 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007417 }
7418#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07007419
7420 /* issue set key request to SME*/
7421 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7422 pAdapter->sessionId, &setKey, &roamId );
7423
7424 if ( 0 != status )
7425 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307426 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007427 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7428 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7429 return -EINVAL;
7430 }
7431
7432
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307433 /* in case of IBSS as there was no information available about WEP keys during
7434 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07007435 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307436 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
7437 !( ( IW_AUTH_KEY_MGMT_802_1X
7438 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07007439 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
7440 )
7441 &&
7442 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
7443 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
7444 )
7445 )
7446 {
7447 setKey.keyDirection = eSIR_RX_ONLY;
7448 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7449
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307450 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007451 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307452 __func__, setKey.peerMac[0], setKey.peerMac[1],
7453 setKey.peerMac[2], setKey.peerMac[3],
7454 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007455 setKey.keyDirection);
7456
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307457 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007458 pAdapter->sessionId, &setKey, &roamId );
7459
7460 if ( 0 != status )
7461 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307462 hddLog(VOS_TRACE_LEVEL_ERROR,
7463 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007464 __func__, status);
7465 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7466 return -EINVAL;
7467 }
7468 }
7469 }
7470
7471 return 0;
7472}
7473
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307474#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7475static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7476 struct net_device *ndev,
7477 u8 key_index, bool pairwise,
7478 const u8 *mac_addr,
7479 struct key_params *params
7480 )
7481#else
7482static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7483 struct net_device *ndev,
7484 u8 key_index, const u8 *mac_addr,
7485 struct key_params *params
7486 )
7487#endif
7488{
7489 int ret;
7490 vos_ssr_protect(__func__);
7491#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7492 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
7493 mac_addr, params);
7494#else
7495 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
7496 params);
7497#endif
7498 vos_ssr_unprotect(__func__);
7499
7500 return ret;
7501}
7502
Jeff Johnson295189b2012-06-20 16:38:30 -07007503/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307504 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007505 * This function is used to get the key information
7506 */
7507#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307508static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307509 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007510 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307511 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007512 const u8 *mac_addr, void *cookie,
7513 void (*callback)(void *cookie, struct key_params*)
7514 )
7515#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307516static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307517 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007518 struct net_device *ndev,
7519 u8 key_index, const u8 *mac_addr, void *cookie,
7520 void (*callback)(void *cookie, struct key_params*)
7521 )
7522#endif
7523{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307524 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307525 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7526 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Jeff Johnson295189b2012-06-20 16:38:30 -07007527 struct key_params params;
7528
7529 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307530
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307531 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7532 __func__, hdd_device_modetoString(pAdapter->device_mode),
7533 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307534
Jeff Johnson295189b2012-06-20 16:38:30 -07007535 memset(&params, 0, sizeof(params));
7536
7537 if (CSR_MAX_NUM_KEY <= key_index)
7538 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307539 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007540 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307541 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007542
7543 switch(pRoamProfile->EncryptionType.encryptionType[0])
7544 {
7545 case eCSR_ENCRYPT_TYPE_NONE:
7546 params.cipher = IW_AUTH_CIPHER_NONE;
7547 break;
7548
7549 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
7550 case eCSR_ENCRYPT_TYPE_WEP40:
7551 params.cipher = WLAN_CIPHER_SUITE_WEP40;
7552 break;
7553
7554 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
7555 case eCSR_ENCRYPT_TYPE_WEP104:
7556 params.cipher = WLAN_CIPHER_SUITE_WEP104;
7557 break;
7558
7559 case eCSR_ENCRYPT_TYPE_TKIP:
7560 params.cipher = WLAN_CIPHER_SUITE_TKIP;
7561 break;
7562
7563 case eCSR_ENCRYPT_TYPE_AES:
7564 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
7565 break;
7566
7567 default:
7568 params.cipher = IW_AUTH_CIPHER_NONE;
7569 break;
7570 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307571
c_hpothuaaf19692014-05-17 17:01:48 +05307572 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7573 TRACE_CODE_HDD_CFG80211_GET_KEY,
7574 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307575
Jeff Johnson295189b2012-06-20 16:38:30 -07007576 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
7577 params.seq_len = 0;
7578 params.seq = NULL;
7579 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
7580 callback(cookie, &params);
7581 return 0;
7582}
7583
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307584#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7585static int wlan_hdd_cfg80211_get_key(
7586 struct wiphy *wiphy,
7587 struct net_device *ndev,
7588 u8 key_index, bool pairwise,
7589 const u8 *mac_addr, void *cookie,
7590 void (*callback)(void *cookie, struct key_params*)
7591 )
7592#else
7593static int wlan_hdd_cfg80211_get_key(
7594 struct wiphy *wiphy,
7595 struct net_device *ndev,
7596 u8 key_index, const u8 *mac_addr, void *cookie,
7597 void (*callback)(void *cookie, struct key_params*)
7598 )
7599#endif
7600{
7601 int ret;
7602
7603 vos_ssr_protect(__func__);
7604#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7605 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
7606 mac_addr, cookie, callback);
7607#else
7608 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
7609 callback);
7610#endif
7611 vos_ssr_unprotect(__func__);
7612
7613 return ret;
7614}
7615
Jeff Johnson295189b2012-06-20 16:38:30 -07007616/*
7617 * FUNCTION: wlan_hdd_cfg80211_del_key
7618 * This function is used to delete the key information
7619 */
7620#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307621static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007622 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307623 u8 key_index,
7624 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007625 const u8 *mac_addr
7626 )
7627#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307628static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007629 struct net_device *ndev,
7630 u8 key_index,
7631 const u8 *mac_addr
7632 )
7633#endif
7634{
7635 int status = 0;
7636
7637 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307638 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07007639 //it is observed that this is invalidating peer
7640 //key index whenever re-key is done. This is affecting data link.
7641 //It should be ok to ignore del_key.
7642#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307643 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
7644 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007645 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7646 tCsrRoamSetKey setKey;
7647 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307648
Jeff Johnson295189b2012-06-20 16:38:30 -07007649 ENTER();
7650
7651 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
7652 __func__,pAdapter->device_mode);
7653
7654 if (CSR_MAX_NUM_KEY <= key_index)
7655 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307656 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007657 key_index);
7658
7659 return -EINVAL;
7660 }
7661
7662 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7663 setKey.keyId = key_index;
7664
7665 if (mac_addr)
7666 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7667 else
7668 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
7669
7670 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
7671
7672 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007673 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307674 )
7675 {
7676
7677 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07007678 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7679 if( pHostapdState->bssState == BSS_START)
7680 {
7681 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307682
Jeff Johnson295189b2012-06-20 16:38:30 -07007683 if ( status != eHAL_STATUS_SUCCESS )
7684 {
7685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7686 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7687 __LINE__, status );
7688 }
7689 }
7690 }
7691 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307692 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07007693 )
7694 {
7695 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7696
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307697 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7698
7699 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007700 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307701 __func__, setKey.peerMac[0], setKey.peerMac[1],
7702 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07007703 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307704 if(pAdapter->sessionCtx.station.conn_info.connState ==
7705 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07007706 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307707 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007708 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307709
Jeff Johnson295189b2012-06-20 16:38:30 -07007710 if ( 0 != status )
7711 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307712 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007713 "%s: sme_RoamSetKey failure, returned %d",
7714 __func__, status);
7715 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7716 return -EINVAL;
7717 }
7718 }
7719 }
7720#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007721 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007722 return status;
7723}
7724
7725/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307726 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007727 * This function is used to set the default tx key index
7728 */
7729#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307730static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007731 struct net_device *ndev,
7732 u8 key_index,
7733 bool unicast, bool multicast)
7734#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307735static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007736 struct net_device *ndev,
7737 u8 key_index)
7738#endif
7739{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307740 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307741 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05307742 hdd_wext_state_t *pWextState;
7743 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307744 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007745
7746 ENTER();
7747
Gopichand Nakkala29149562013-05-10 21:43:41 +05307748 if ((NULL == pAdapter))
7749 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05307751 "invalid adapter");
7752 return -EINVAL;
7753 }
7754
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307755 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7756 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
7757 pAdapter->sessionId, key_index));
7758
Gopichand Nakkala29149562013-05-10 21:43:41 +05307759 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7760 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7761
7762 if ((NULL == pWextState) || (NULL == pHddStaCtx))
7763 {
7764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7765 "invalid Wext state or HDD context");
7766 return -EINVAL;
7767 }
7768
Arif Hussain6d2a3322013-11-17 19:50:10 -08007769 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007770 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307771
Jeff Johnson295189b2012-06-20 16:38:30 -07007772 if (CSR_MAX_NUM_KEY <= key_index)
7773 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307774 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007775 key_index);
7776
7777 return -EINVAL;
7778 }
7779
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307780 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7781 status = wlan_hdd_validate_context(pHddCtx);
7782
7783 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007784 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307785 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7786 "%s: HDD context is not valid", __func__);
7787 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007788 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307789
Jeff Johnson295189b2012-06-20 16:38:30 -07007790 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007791 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307792 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007793 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05307794 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08007795 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307796 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08007797 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07007798 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307799 {
7800 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07007801 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307802
Jeff Johnson295189b2012-06-20 16:38:30 -07007803 tCsrRoamSetKey setKey;
7804 v_U32_t roamId= 0xFF;
7805 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307806
7807 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007808 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307809
Jeff Johnson295189b2012-06-20 16:38:30 -07007810 Keys->defaultIndex = (u8)key_index;
7811 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7812 setKey.keyId = key_index;
7813 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307814
7815 vos_mem_copy(&setKey.Key[0],
7816 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007817 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307818
Gopichand Nakkala29149562013-05-10 21:43:41 +05307819 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307820
7821 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07007822 &pHddStaCtx->conn_info.bssId[0],
7823 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307824
Gopichand Nakkala29149562013-05-10 21:43:41 +05307825 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
7826 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
7827 eCSR_ENCRYPT_TYPE_WEP104)
7828 {
7829 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
7830 even though ap is configured for WEP-40 encryption. In this canse the key length
7831 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
7832 type(104) and switching encryption type to 40*/
7833 pWextState->roamProfile.EncryptionType.encryptionType[0] =
7834 eCSR_ENCRYPT_TYPE_WEP40;
7835 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
7836 eCSR_ENCRYPT_TYPE_WEP40;
7837 }
7838
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307839 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07007840 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307841
Jeff Johnson295189b2012-06-20 16:38:30 -07007842 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307843 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007844 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307845
Jeff Johnson295189b2012-06-20 16:38:30 -07007846 if ( 0 != status )
7847 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307848 hddLog(VOS_TRACE_LEVEL_ERROR,
7849 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007850 status);
7851 return -EINVAL;
7852 }
7853 }
7854 }
7855
7856 /* In SoftAp mode setting key direction for default mode */
7857 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
7858 {
7859 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
7860 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
7861 (eCSR_ENCRYPT_TYPE_AES !=
7862 pWextState->roamProfile.EncryptionType.encryptionType[0])
7863 )
7864 {
7865 /* Saving key direction for default key index to TX default */
7866 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7867 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
7868 }
7869 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307870
Jeff Johnson295189b2012-06-20 16:38:30 -07007871 return status;
7872}
7873
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307874#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7875static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
7876 struct net_device *ndev,
7877 u8 key_index,
7878 bool unicast, bool multicast)
7879#else
7880static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
7881 struct net_device *ndev,
7882 u8 key_index)
7883#endif
7884{
7885 int ret;
7886 vos_ssr_protect(__func__);
7887#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7888 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
7889 multicast);
7890#else
7891 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
7892#endif
7893 vos_ssr_unprotect(__func__);
7894
7895 return ret;
7896}
7897
Jeff Johnson295189b2012-06-20 16:38:30 -07007898/*
7899 * FUNCTION: wlan_hdd_cfg80211_inform_bss
7900 * This function is used to inform the BSS details to nl80211 interface.
7901 */
7902static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
7903 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
7904{
7905 struct net_device *dev = pAdapter->dev;
7906 struct wireless_dev *wdev = dev->ieee80211_ptr;
7907 struct wiphy *wiphy = wdev->wiphy;
7908 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
7909 int chan_no;
7910 int ie_length;
7911 const char *ie;
7912 unsigned int freq;
7913 struct ieee80211_channel *chan;
7914 int rssi = 0;
7915 struct cfg80211_bss *bss = NULL;
7916
7917 ENTER();
7918
7919 if( NULL == pBssDesc )
7920 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007921 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007922 return bss;
7923 }
7924
7925 chan_no = pBssDesc->channelId;
7926 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
7927 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
7928
7929 if( NULL == ie )
7930 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007931 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007932 return bss;
7933 }
7934
7935#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
7936 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
7937 {
7938 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
7939 }
7940 else
7941 {
7942 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
7943 }
7944#else
7945 freq = ieee80211_channel_to_frequency(chan_no);
7946#endif
7947
7948 chan = __ieee80211_get_channel(wiphy, freq);
7949
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05307950 if (!chan) {
7951 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
7952 return NULL;
7953 }
7954
Abhishek Singhaee43942014-06-16 18:55:47 +05307955 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07007956
Abhishek Singhaee43942014-06-16 18:55:47 +05307957 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307958 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07007959 pBssDesc->capabilityInfo,
7960 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05307961 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07007962}
7963
7964
7965
7966/*
7967 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
7968 * This function is used to inform the BSS details to nl80211 interface.
7969 */
7970struct cfg80211_bss*
7971wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
7972 tSirBssDescription *bss_desc
7973 )
7974{
7975 /*
7976 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
7977 already exists in bss data base of cfg80211 for that particular BSS ID.
7978 Using cfg80211_inform_bss_frame to update the bss entry instead of
7979 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
7980 now there is no possibility to get the mgmt(probe response) frame from PE,
7981 converting bss_desc to ieee80211_mgmt(probe response) and passing to
7982 cfg80211_inform_bss_frame.
7983 */
7984 struct net_device *dev = pAdapter->dev;
7985 struct wireless_dev *wdev = dev->ieee80211_ptr;
7986 struct wiphy *wiphy = wdev->wiphy;
7987 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007988#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
7989 qcom_ie_age *qie_age = NULL;
7990 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
7991#else
Jeff Johnson295189b2012-06-20 16:38:30 -07007992 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007993#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007994 const char *ie =
7995 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
7996 unsigned int freq;
7997 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05307998 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007999 struct cfg80211_bss *bss_status = NULL;
8000 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
8001 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07008002 hdd_context_t *pHddCtx;
8003 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07008004#ifdef WLAN_OPEN_SOURCE
8005 struct timespec ts;
8006#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008007
Wilson Yangf80a0542013-10-07 13:02:37 -07008008 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8009 status = wlan_hdd_validate_context(pHddCtx);
8010
8011 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308012 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008013 {
8014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8015 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8016 return NULL;
8017 }
8018
8019
8020 if (0 != status)
8021 {
8022 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8023 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008024 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008025 }
8026
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05308027 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07008028 if (!mgmt)
8029 {
8030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8031 "%s: memory allocation failed ", __func__);
8032 return NULL;
8033 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008034
Jeff Johnson295189b2012-06-20 16:38:30 -07008035 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07008036
8037#ifdef WLAN_OPEN_SOURCE
8038 /* Android does not want the timestamp from the frame.
8039 Instead it wants a monotonic increasing value */
8040 get_monotonic_boottime(&ts);
8041 mgmt->u.probe_resp.timestamp =
8042 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
8043#else
8044 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07008045 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
8046 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07008047
8048#endif
8049
Jeff Johnson295189b2012-06-20 16:38:30 -07008050 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
8051 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008052
8053#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8054 /* GPS Requirement: need age ie per entry. Using vendor specific. */
8055 /* Assuming this is the last IE, copy at the end */
8056 ie_length -=sizeof(qcom_ie_age);
8057 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
8058 qie_age->element_id = QCOM_VENDOR_IE_ID;
8059 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
8060 qie_age->oui_1 = QCOM_OUI1;
8061 qie_age->oui_2 = QCOM_OUI2;
8062 qie_age->oui_3 = QCOM_OUI3;
8063 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
8064 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
8065#endif
8066
Jeff Johnson295189b2012-06-20 16:38:30 -07008067 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05308068 if (bss_desc->fProbeRsp)
8069 {
8070 mgmt->frame_control |=
8071 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
8072 }
8073 else
8074 {
8075 mgmt->frame_control |=
8076 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
8077 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008078
8079#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308080 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008081 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
8082 {
8083 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8084 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308085 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008086 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
8087
8088 {
8089 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8090 }
8091 else
8092 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308093 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
8094 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07008095 kfree(mgmt);
8096 return NULL;
8097 }
8098#else
8099 freq = ieee80211_channel_to_frequency(chan_no);
8100#endif
8101 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008102 /*when the band is changed on the fly using the GUI, three things are done
8103 * 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)
8104 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
8105 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
8106 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
8107 * and discards the channels correponding to previous band and calls back with zero bss results.
8108 * 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
8109 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
8110 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
8111 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
8112 * So drop the bss and continue to next bss.
8113 */
8114 if(chan == NULL)
8115 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308116 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07008117 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008118 return NULL;
8119 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008120 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308121 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07008122 * */
8123 if (( eConnectionState_Associated ==
8124 pAdapter->sessionCtx.station.conn_info.connState ) &&
8125 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
8126 pAdapter->sessionCtx.station.conn_info.bssId,
8127 WNI_CFG_BSSID_LEN)))
8128 {
8129 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
8130 rssi = (pAdapter->rssi * 100);
8131 }
8132 else
8133 {
8134 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
8135 }
8136
Nirav Shah20ac06f2013-12-12 18:14:06 +05308137 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
8138 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
8139 chan->center_freq, (int)(rssi/100));
8140
Jeff Johnson295189b2012-06-20 16:38:30 -07008141 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
8142 frame_len, rssi, GFP_KERNEL);
8143 kfree(mgmt);
8144 return bss_status;
8145}
8146
8147/*
8148 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
8149 * This function is used to update the BSS data base of CFG8011
8150 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308151struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008152 tCsrRoamInfo *pRoamInfo
8153 )
8154{
8155 tCsrRoamConnectedProfile roamProfile;
8156 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8157 struct cfg80211_bss *bss = NULL;
8158
8159 ENTER();
8160
8161 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
8162 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
8163
8164 if (NULL != roamProfile.pBssDesc)
8165 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308166 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008167 &roamProfile);
8168
8169 if (NULL == bss)
8170 {
8171 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
8172 __func__);
8173 }
8174
8175 sme_RoamFreeConnectProfile(hHal, &roamProfile);
8176 }
8177 else
8178 {
8179 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
8180 __func__);
8181 }
8182 return bss;
8183}
8184
8185/*
8186 * FUNCTION: wlan_hdd_cfg80211_update_bss
8187 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308188static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
8189 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07008190 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308191{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308192 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008193 tCsrScanResultInfo *pScanResult;
8194 eHalStatus status = 0;
8195 tScanResultHandle pResult;
8196 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008197 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008198
8199 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308200
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308201 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8202 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
8203 NO_SESSION, pAdapter->sessionId));
8204
Wilson Yangf80a0542013-10-07 13:02:37 -07008205 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8206
8207 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07008208 {
Wilson Yangf80a0542013-10-07 13:02:37 -07008209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8210 "%s:LOGP in Progress. Ignore!!!",__func__);
8211 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008212 }
8213
Wilson Yangf80a0542013-10-07 13:02:37 -07008214
8215 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308216 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008217 {
8218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8219 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8220 return VOS_STATUS_E_PERM;
8221 }
8222
8223
Jeff Johnson295189b2012-06-20 16:38:30 -07008224 /*
8225 * start getting scan results and populate cgf80211 BSS database
8226 */
8227 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
8228
8229 /* no scan results */
8230 if (NULL == pResult)
8231 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308232 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
8233 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008234 return status;
8235 }
8236
8237 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
8238
8239 while (pScanResult)
8240 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308241 /*
8242 * cfg80211_inform_bss() is not updating ie field of bss entry, if
8243 * entry already exists in bss data base of cfg80211 for that
8244 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
8245 * bss entry instead of cfg80211_inform_bss, But this call expects
8246 * mgmt packet as input. As of now there is no possibility to get
8247 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07008248 * ieee80211_mgmt(probe response) and passing to c
8249 * fg80211_inform_bss_frame.
8250 * */
8251
8252 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
8253 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308254
Jeff Johnson295189b2012-06-20 16:38:30 -07008255
8256 if (NULL == bss_status)
8257 {
8258 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008259 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008260 }
8261 else
8262 {
Yue Maf49ba872013-08-19 12:04:25 -07008263 cfg80211_put_bss(
8264#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
8265 wiphy,
8266#endif
8267 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008268 }
8269
8270 pScanResult = sme_ScanResultGetNext(hHal, pResult);
8271 }
8272
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308273 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07008274
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308275 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008276}
8277
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008278void
8279hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
8280{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308281 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08008282 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008283} /****** end hddPrintMacAddr() ******/
8284
8285void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008286hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008287{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308288 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008289 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008290 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
8291 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
8292 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008293} /****** end hddPrintPmkId() ******/
8294
8295//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
8296//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
8297
8298//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
8299//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
8300
8301#define dump_bssid(bssid) \
8302 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008303 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
8304 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008305 }
8306
8307#define dump_pmkid(pMac, pmkid) \
8308 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008309 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
8310 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008311 }
8312
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008313#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008314/*
8315 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
8316 * This function is used to notify the supplicant of a new PMKSA candidate.
8317 */
8318int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308319 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008320 int index, bool preauth )
8321{
Jeff Johnsone7245742012-09-05 17:12:55 -07008322#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008323 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008324 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008325
8326 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07008327 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008328
8329 if( NULL == pRoamInfo )
8330 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008331 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008332 return -EINVAL;
8333 }
8334
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008335 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
8336 {
8337 dump_bssid(pRoamInfo->bssid);
8338 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008339 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008340 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008341#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308342 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008343}
8344#endif //FEATURE_WLAN_LFR
8345
Yue Maef608272013-04-08 23:09:17 -07008346#ifdef FEATURE_WLAN_LFR_METRICS
8347/*
8348 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
8349 * 802.11r/LFR metrics reporting function to report preauth initiation
8350 *
8351 */
8352#define MAX_LFR_METRICS_EVENT_LENGTH 100
8353VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
8354 tCsrRoamInfo *pRoamInfo)
8355{
8356 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8357 union iwreq_data wrqu;
8358
8359 ENTER();
8360
8361 if (NULL == pAdapter)
8362 {
8363 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8364 return VOS_STATUS_E_FAILURE;
8365 }
8366
8367 /* create the event */
8368 memset(&wrqu, 0, sizeof(wrqu));
8369 memset(metrics_notification, 0, sizeof(metrics_notification));
8370
8371 wrqu.data.pointer = metrics_notification;
8372 wrqu.data.length = scnprintf(metrics_notification,
8373 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
8374 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8375
8376 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8377
8378 EXIT();
8379
8380 return VOS_STATUS_SUCCESS;
8381}
8382
8383/*
8384 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
8385 * 802.11r/LFR metrics reporting function to report preauth completion
8386 * or failure
8387 */
8388VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
8389 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
8390{
8391 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8392 union iwreq_data wrqu;
8393
8394 ENTER();
8395
8396 if (NULL == pAdapter)
8397 {
8398 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8399 return VOS_STATUS_E_FAILURE;
8400 }
8401
8402 /* create the event */
8403 memset(&wrqu, 0, sizeof(wrqu));
8404 memset(metrics_notification, 0, sizeof(metrics_notification));
8405
8406 scnprintf(metrics_notification, sizeof(metrics_notification),
8407 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
8408 MAC_ADDR_ARRAY(pRoamInfo->bssid));
8409
8410 if (1 == preauth_status)
8411 strncat(metrics_notification, " TRUE", 5);
8412 else
8413 strncat(metrics_notification, " FALSE", 6);
8414
8415 wrqu.data.pointer = metrics_notification;
8416 wrqu.data.length = strlen(metrics_notification);
8417
8418 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8419
8420 EXIT();
8421
8422 return VOS_STATUS_SUCCESS;
8423}
8424
8425/*
8426 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
8427 * 802.11r/LFR metrics reporting function to report handover initiation
8428 *
8429 */
8430VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
8431 tCsrRoamInfo *pRoamInfo)
8432{
8433 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8434 union iwreq_data wrqu;
8435
8436 ENTER();
8437
8438 if (NULL == pAdapter)
8439 {
8440 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8441 return VOS_STATUS_E_FAILURE;
8442 }
8443
8444 /* create the event */
8445 memset(&wrqu, 0, sizeof(wrqu));
8446 memset(metrics_notification, 0, sizeof(metrics_notification));
8447
8448 wrqu.data.pointer = metrics_notification;
8449 wrqu.data.length = scnprintf(metrics_notification,
8450 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
8451 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8452
8453 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8454
8455 EXIT();
8456
8457 return VOS_STATUS_SUCCESS;
8458}
8459#endif
8460
Jeff Johnson295189b2012-06-20 16:38:30 -07008461/*
8462 * FUNCTION: hdd_cfg80211_scan_done_callback
8463 * scanning callback function, called after finishing scan
8464 *
8465 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308466static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07008467 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
8468{
8469 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308470 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008471 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008472 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8473 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07008474 struct cfg80211_scan_request *req = NULL;
8475 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308476 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308477 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008478
8479 ENTER();
8480
8481 hddLog(VOS_TRACE_LEVEL_INFO,
8482 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08008483 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008484 __func__, halHandle, pContext, (int) scanId, (int) status);
8485
Kiet Lamac06e2c2013-10-23 16:25:07 +05308486 pScanInfo->mScanPendingCounter = 0;
8487
Jeff Johnson295189b2012-06-20 16:38:30 -07008488 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308489 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008490 &pScanInfo->scan_req_completion_event,
8491 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308492 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008493 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308494 hddLog(VOS_TRACE_LEVEL_ERROR,
8495 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07008496 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008497 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008498 }
8499
Yue Maef608272013-04-08 23:09:17 -07008500 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008501 {
8502 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008503 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008504 }
8505
8506 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308507 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07008508 {
8509 hddLog(VOS_TRACE_LEVEL_INFO,
8510 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08008511 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07008512 (int) scanId);
8513 }
8514
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308515 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008516 pAdapter);
8517
8518 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308519 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008520
8521
8522 /* If any client wait scan result through WEXT
8523 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008524 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07008525 {
8526 /* The other scan request waiting for current scan finish
8527 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008528 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008529 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008530 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07008531 }
8532 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008533 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008534 {
8535 struct net_device *dev = pAdapter->dev;
8536 union iwreq_data wrqu;
8537 int we_event;
8538 char *msg;
8539
8540 memset(&wrqu, '\0', sizeof(wrqu));
8541 we_event = SIOCGIWSCAN;
8542 msg = NULL;
8543 wireless_send_event(dev, we_event, &wrqu, msg);
8544 }
8545 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008546 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008547
8548 /* Get the Scan Req */
8549 req = pAdapter->request;
8550
8551 if (!req)
8552 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008553 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008554 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008555 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008556 }
8557
8558 /*
8559 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308560 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008561 req->n_ssids = 0;
8562 req->n_channels = 0;
8563 req->ie = 0;
8564
Jeff Johnson295189b2012-06-20 16:38:30 -07008565 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008566 /* Scan is no longer pending */
8567 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008568
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07008569 /*
8570 * cfg80211_scan_done informing NL80211 about completion
8571 * of scanning
8572 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308573 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
8574 {
8575 aborted = true;
8576 }
8577 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008578 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07008579
Jeff Johnsone7245742012-09-05 17:12:55 -07008580allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008581 /* release the wake lock at the end of the scan*/
8582 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07008583
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008584 /* Acquire wakelock to handle the case where APP's tries to suspend
8585 * immediatly after the driver gets connect request(i.e after scan)
8586 * from supplicant, this result in app's is suspending and not able
8587 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308588 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008589
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008590#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05308591 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
8592 {
8593 wlan_hdd_tdls_scan_done_callback(pAdapter);
8594 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008595#endif
8596
Jeff Johnson295189b2012-06-20 16:38:30 -07008597 EXIT();
8598 return 0;
8599}
8600
8601/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05308602 * FUNCTION: hdd_isConnectionInProgress
8603 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008604 *
8605 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05308606v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008607{
8608 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8609 hdd_station_ctx_t *pHddStaCtx = NULL;
8610 hdd_adapter_t *pAdapter = NULL;
8611 VOS_STATUS status = 0;
8612 v_U8_t staId = 0;
8613 v_U8_t *staMac = NULL;
8614
c_hpothu9b781ba2013-12-30 20:57:45 +05308615 if (TRUE == pHddCtx->btCoexModeSet)
8616 {
8617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05308618 FL("BTCoex Mode operation in progress"));
8619 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05308620 }
8621
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008622 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8623
8624 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8625 {
8626 pAdapter = pAdapterNode->pAdapter;
8627
8628 if( pAdapter )
8629 {
8630 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308631 "%s: Adapter with device mode %s (%d) exists",
8632 __func__, hdd_device_modetoString(pAdapter->device_mode),
8633 pAdapter->device_mode);
Rashmi Ramannab1429032014-04-26 14:59:09 +05308634 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8635 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8636 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
8637 (eConnectionState_Connecting ==
8638 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
8639 {
8640 hddLog(VOS_TRACE_LEVEL_ERROR,
8641 "%s: %p(%d) Connection is in progress", __func__,
8642 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
8643 return VOS_TRUE;
8644 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008645 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308646 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8647 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008648 {
8649 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8650 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308651 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008652 {
8653 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
8654 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08008655 "%s: client " MAC_ADDRESS_STR
8656 " is in the middle of WPS/EAPOL exchange.", __func__,
8657 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05308658 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008659 }
8660 }
8661 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
8662 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
8663 {
8664 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
8665 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308666 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008667 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
8668 {
8669 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
8670
8671 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08008672 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
8673 "middle of WPS/EAPOL exchange.", __func__,
8674 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05308675 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008676 }
8677 }
8678 }
8679 }
8680 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8681 pAdapterNode = pNext;
8682 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05308683 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308684}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008685
8686/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05308687 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07008688 * this scan respond to scan trigger and update cfg80211 scan database
8689 * later, scan dump command can be used to recieve scan results
8690 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05308691int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08008692#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
8693 struct net_device *dev,
8694#endif
8695 struct cfg80211_scan_request *request)
8696{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308697 hdd_adapter_t *pAdapter = NULL;
8698 hdd_context_t *pHddCtx = NULL;
8699 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308700 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008701 tCsrScanRequest scanRequest;
8702 tANI_U8 *channelList = NULL, i;
8703 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308704 int status;
8705 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008706 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008707
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308708#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8709 struct net_device *dev = NULL;
8710 if (NULL == request)
8711 {
8712 hddLog(VOS_TRACE_LEVEL_ERROR,
8713 "%s: scan req param null", __func__);
8714 return -EINVAL;
8715 }
8716 dev = request->wdev->netdev;
8717#endif
8718
8719 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
8720 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
8721 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8722
Jeff Johnson295189b2012-06-20 16:38:30 -07008723 ENTER();
8724
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308725
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308726 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8727 __func__, hdd_device_modetoString(pAdapter->device_mode),
8728 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308729
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308730 status = wlan_hdd_validate_context(pHddCtx);
8731
8732 if (0 != status)
8733 {
8734 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8735 "%s: HDD context is not valid", __func__);
8736 return status;
8737 }
8738
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308739 if (NULL == pwextBuf)
8740 {
8741 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
8742 __func__);
8743 return -EIO;
8744 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308745 cfg_param = pHddCtx->cfg_ini;
8746 pScanInfo = &pHddCtx->scan_info;
8747
Jeff Johnson295189b2012-06-20 16:38:30 -07008748#ifdef WLAN_BTAMP_FEATURE
8749 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008750 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07008751 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08008752 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008753 "%s: No scanning when AMP is on", __func__);
8754 return -EOPNOTSUPP;
8755 }
8756#endif
8757 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008758 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008759 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008760 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308761 "%s: Not scanning on device_mode = %s (%d)",
8762 __func__, hdd_device_modetoString(pAdapter->device_mode),
8763 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008764 return -EOPNOTSUPP;
8765 }
8766
8767 if (TRUE == pScanInfo->mScanPending)
8768 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05308769 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
8770 {
8771 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
8772 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008773 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07008774 }
8775
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308776 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07008777 //Channel and action frame is pending
8778 //Otherwise Cancel Remain On Channel and allow Scan
8779 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008780 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07008781 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05308782 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07008783 return -EBUSY;
8784 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008785#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008786 /* if tdls disagree scan right now, return immediately.
8787 tdls will schedule the scan when scan is allowed. (return SUCCESS)
8788 or will reject the scan if any TDLS is in progress. (return -EBUSY)
8789 */
8790 status = wlan_hdd_tdls_scan_callback (pAdapter,
8791 wiphy,
8792#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
8793 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07008794#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008795 request);
8796 if(status <= 0)
8797 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308798 if(!status)
8799 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
8800 "scan rejected %d", __func__, status);
8801 else
8802 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
8803 __func__, status);
8804
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008805 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008806 }
8807#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07008808
Jeff Johnson295189b2012-06-20 16:38:30 -07008809 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
8810 {
8811 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08008812 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008813 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308814 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008815 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
8816 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308817 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008818 "%s: MAX TM Level Scan not allowed", __func__);
8819 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308820 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07008821 }
8822 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
8823
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008824 /* Check if scan is allowed at this point of time.
8825 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05308826 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008827 {
8828 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
8829 return -EBUSY;
8830 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308831
Jeff Johnson295189b2012-06-20 16:38:30 -07008832 vos_mem_zero( &scanRequest, sizeof(scanRequest));
8833
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308834 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
8835 (int)request->n_ssids);
8836
8837 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
8838 * Becasue of this, driver is assuming that this is not wildcard scan and so
8839 * is not aging out the scan results.
8840 */
8841 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07008842 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308843 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008844 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308845
8846 if ((request->ssids) && (0 < request->n_ssids))
8847 {
8848 tCsrSSIDInfo *SsidInfo;
8849 int j;
8850 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
8851 /* Allocate num_ssid tCsrSSIDInfo structure */
8852 SsidInfo = scanRequest.SSIDs.SSIDList =
8853 ( tCsrSSIDInfo *)vos_mem_malloc(
8854 request->n_ssids*sizeof(tCsrSSIDInfo));
8855
8856 if(NULL == scanRequest.SSIDs.SSIDList)
8857 {
8858 hddLog(VOS_TRACE_LEVEL_ERROR,
8859 "%s: memory alloc failed SSIDInfo buffer", __func__);
8860 return -ENOMEM;
8861 }
8862
8863 /* copy all the ssid's and their length */
8864 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
8865 {
8866 /* get the ssid length */
8867 SsidInfo->SSID.length = request->ssids[j].ssid_len;
8868 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
8869 SsidInfo->SSID.length);
8870 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
8871 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
8872 j, SsidInfo->SSID.ssId);
8873 }
8874 /* set the scan type to active */
8875 scanRequest.scanType = eSIR_ACTIVE_SCAN;
8876 }
8877 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07008878 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308879 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8880 TRACE_CODE_HDD_CFG80211_SCAN,
8881 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07008882 /* set the scan type to active */
8883 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008884 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308885 else
8886 {
8887 /*Set the scan type to default type, in this case it is ACTIVE*/
8888 scanRequest.scanType = pScanInfo->scan_mode;
8889 }
8890 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
8891 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07008892
8893 /* set BSSType to default type */
8894 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
8895
8896 /*TODO: scan the requested channels only*/
8897
8898 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308899 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -07008900 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308901 hddLog(VOS_TRACE_LEVEL_WARN,
8902 "No of Scan Channels exceeded limit: %d", request->n_channels);
8903 request->n_channels = MAX_CHANNEL;
8904 }
8905
8906 hddLog(VOS_TRACE_LEVEL_INFO,
8907 "No of Scan Channels: %d", request->n_channels);
8908
8909
8910 if( request->n_channels )
8911 {
8912 char chList [(request->n_channels*5)+1];
8913 int len;
8914 channelList = vos_mem_malloc( request->n_channels );
8915 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +05308916 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308917 hddLog(VOS_TRACE_LEVEL_ERROR,
8918 "%s: memory alloc failed channelList", __func__);
8919 status = -ENOMEM;
8920 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +05308921 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308922
8923 for( i = 0, len = 0; i < request->n_channels ; i++ )
8924 {
8925 channelList[i] = request->channels[i]->hw_value;
8926 len += snprintf(chList+len, 5, "%d ", channelList[i]);
8927 }
8928
Nirav Shah20ac06f2013-12-12 18:14:06 +05308929 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308930 "Channel-List: %s ", chList);
8931 }
c_hpothu53512302014-04-15 18:49:53 +05308932
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308933 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
8934 scanRequest.ChannelInfo.ChannelList = channelList;
8935
8936 /* set requestType to full scan */
8937 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8938
8939 /* Flush the scan results(only p2p beacons) for STA scan and P2P
8940 * search (Flush on both full scan and social scan but not on single
8941 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
8942 */
8943
8944 /* Supplicant does single channel scan after 8-way handshake
8945 * and in that case driver shoudnt flush scan results. If
8946 * driver flushes the scan results here and unfortunately if
8947 * the AP doesnt respond to our probe req then association
8948 * fails which is not desired
8949 */
8950
8951 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
8952 {
8953 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
8954 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
8955 pAdapter->sessionId );
8956 }
8957
8958 if( request->ie_len )
8959 {
8960 /* save this for future association (join requires this) */
8961 /*TODO: Array needs to be converted to dynamic allocation,
8962 * as multiple ie.s can be sent in cfg80211_scan_request structure
8963 * CR 597966
8964 */
8965 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
8966 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
8967 pScanInfo->scanAddIE.length = request->ie_len;
8968
8969 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8970 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8971 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07008972 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308973 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -07008974 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308975 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
8976 memcpy( pwextBuf->roamProfile.addIEScan,
8977 request->ie, request->ie_len);
8978 }
8979 else
8980 {
8981 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
8982 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008983 }
8984
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308985 }
8986 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
8987 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
8988
8989 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
8990 request->ie_len);
8991 if (pP2pIe != NULL)
8992 {
8993#ifdef WLAN_FEATURE_P2P_DEBUG
8994 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
8995 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
8996 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +05308997 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308998 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
8999 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9000 "Go nego completed to Connection is started");
9001 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9002 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +05309003 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309004 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
9005 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07009006 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309007 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
9008 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9009 "Disconnected state to Connection is started");
9010 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9011 "for 4way Handshake");
9012 }
9013#endif
9014
9015 /* no_cck will be set during p2p find to disable 11b rates */
9016 if(TRUE == request->no_cck)
9017 {
9018 hddLog(VOS_TRACE_LEVEL_INFO,
9019 "%s: This is a P2P Search", __func__);
9020 scanRequest.p2pSearch = 1;
9021
9022 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +05309023 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309024 /* set requestType to P2P Discovery */
9025 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
9026 }
9027
9028 /*
9029 Skip Dfs Channel in case of P2P Search
9030 if it is set in ini file
9031 */
9032 if(cfg_param->skipDfsChnlInP2pSearch)
9033 {
9034 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309035 }
9036 else
9037 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309038 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309039 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009040
Agarwal Ashish4f616132013-12-30 23:32:50 +05309041 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009042 }
9043 }
9044
9045 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
9046
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009047 /* acquire the wakelock to avoid the apps suspend during the scan. To
9048 * address the following issues.
9049 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
9050 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
9051 * for long time, this result in apps running at full power for long time.
9052 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
9053 * be stuck in full power because of resume BMPS
9054 */
9055 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009056
Nirav Shah20ac06f2013-12-12 18:14:06 +05309057 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9058 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309059 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
9060 scanRequest.requestType, scanRequest.scanType,
9061 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05309062 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
9063
Jeff Johnsone7245742012-09-05 17:12:55 -07009064 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009065 pAdapter->sessionId, &scanRequest, &scanId,
9066 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07009067
Jeff Johnson295189b2012-06-20 16:38:30 -07009068 if (eHAL_STATUS_SUCCESS != status)
9069 {
9070 hddLog(VOS_TRACE_LEVEL_ERROR,
9071 "%s: sme_ScanRequest returned error %d", __func__, status);
9072 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009073 if(eHAL_STATUS_RESOURCES == status)
9074 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309075 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
9076 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009077 status = -EBUSY;
9078 } else {
9079 status = -EIO;
9080 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009081 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009082 goto free_mem;
9083 }
9084
9085 pScanInfo->mScanPending = TRUE;
9086 pAdapter->request = request;
9087 pScanInfo->scanId = scanId;
9088
9089 complete(&pScanInfo->scan_req_completion_event);
9090
9091free_mem:
9092 if( scanRequest.SSIDs.SSIDList )
9093 {
9094 vos_mem_free(scanRequest.SSIDs.SSIDList);
9095 }
9096
9097 if( channelList )
9098 vos_mem_free( channelList );
9099
9100 EXIT();
9101
9102 return status;
9103}
9104
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309105int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
9106#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9107 struct net_device *dev,
9108#endif
9109 struct cfg80211_scan_request *request)
9110{
9111 int ret;
9112
9113 vos_ssr_protect(__func__);
9114 ret = __wlan_hdd_cfg80211_scan(wiphy,
9115#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9116 dev,
9117#endif
9118 request);
9119 vos_ssr_unprotect(__func__);
9120
9121 return ret;
9122}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009123
9124void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
9125{
9126 v_U8_t iniDot11Mode =
9127 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
9128 eHddDot11Mode hddDot11Mode = iniDot11Mode;
9129
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309130 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
9131 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009132 switch ( iniDot11Mode )
9133 {
9134 case eHDD_DOT11_MODE_AUTO:
9135 case eHDD_DOT11_MODE_11ac:
9136 case eHDD_DOT11_MODE_11ac_ONLY:
9137#ifdef WLAN_FEATURE_11AC
9138 hddDot11Mode = eHDD_DOT11_MODE_11ac;
9139#else
9140 hddDot11Mode = eHDD_DOT11_MODE_11n;
9141#endif
9142 break;
9143 case eHDD_DOT11_MODE_11n:
9144 case eHDD_DOT11_MODE_11n_ONLY:
9145 hddDot11Mode = eHDD_DOT11_MODE_11n;
9146 break;
9147 default:
9148 hddDot11Mode = iniDot11Mode;
9149 break;
9150 }
9151 /* This call decides required channel bonding mode */
9152 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
9153 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
9154 operationChannel);
9155}
9156
Jeff Johnson295189b2012-06-20 16:38:30 -07009157/*
9158 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309159 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07009160 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309161int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009162 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009163{
9164 int status = 0;
9165 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08009166 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009167 v_U32_t roamId;
9168 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07009169 eCsrAuthType RSNAuthType;
9170
9171 ENTER();
9172
9173 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08009174 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9175
9176 status = wlan_hdd_validate_context(pHddCtx);
9177 if (status)
9178 {
9179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9180 "%s: HDD context is not valid!", __func__);
9181 return status;
9182 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309183
Jeff Johnson295189b2012-06-20 16:38:30 -07009184 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
9185 {
9186 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
9187 return -EINVAL;
9188 }
9189
9190 pRoamProfile = &pWextState->roamProfile;
9191
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309192 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07009193 {
Jeff Johnsone7245742012-09-05 17:12:55 -07009194 hdd_station_ctx_t *pHddStaCtx;
9195 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009196
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309197 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07009198 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
9199 {
9200 /*QoS not enabled in cfg file*/
9201 pRoamProfile->uapsd_mask = 0;
9202 }
9203 else
9204 {
9205 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309206 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07009207 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
9208 }
9209
9210 pRoamProfile->SSIDs.numOfSSIDs = 1;
9211 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
9212 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309213 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07009214 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
9215 ssid, ssid_len);
9216
9217 if (bssid)
9218 {
9219 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
9220 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
9221 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309222 /* Save BSSID in seperate variable as well, as RoamProfile
9223 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07009224 case of join failure we should send valid BSSID to supplicant
9225 */
9226 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
9227 WNI_CFG_BSSID_LEN);
9228 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07009229 else
9230 {
9231 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
9232 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009233
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309234 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
9235 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07009236 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
9237 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309238 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009239 /*set gen ie*/
9240 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
9241 /*set auth*/
9242 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
9243 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009244#ifdef FEATURE_WLAN_WAPI
9245 if (pAdapter->wapi_info.nWapiMode)
9246 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009247 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009248 switch (pAdapter->wapi_info.wapiAuthMode)
9249 {
9250 case WAPI_AUTH_MODE_PSK:
9251 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009252 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009253 pAdapter->wapi_info.wapiAuthMode);
9254 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
9255 break;
9256 }
9257 case WAPI_AUTH_MODE_CERT:
9258 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009259 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009260 pAdapter->wapi_info.wapiAuthMode);
9261 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
9262 break;
9263 }
9264 } // End of switch
9265 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
9266 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
9267 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009268 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009269 pRoamProfile->AuthType.numEntries = 1;
9270 pRoamProfile->EncryptionType.numEntries = 1;
9271 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9272 pRoamProfile->mcEncryptionType.numEntries = 1;
9273 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9274 }
9275 }
9276#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309277#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309278 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309279 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9280 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
9281 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309282 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
9283 sizeof (tSirGtkOffloadParams));
9284 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309285 }
9286#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009287 pRoamProfile->csrPersona = pAdapter->device_mode;
9288
Jeff Johnson32d95a32012-09-10 13:15:23 -07009289 if( operatingChannel )
9290 {
9291 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
9292 pRoamProfile->ChannelInfo.numOfChannels = 1;
9293 }
Chet Lanctot186b5732013-03-18 10:26:30 -07009294 else
9295 {
9296 pRoamProfile->ChannelInfo.ChannelList = NULL;
9297 pRoamProfile->ChannelInfo.numOfChannels = 0;
9298 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009299 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
9300 {
9301 hdd_select_cbmode(pAdapter,operatingChannel);
9302 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309303
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009304 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
9305 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309306 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009307 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009308 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
9309 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309310 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9311 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +05309312 {
9313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9314 "%s: Set HDD connState to eConnectionState_Connecting",
9315 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009316 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
9317 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +05309318 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309319 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009320 pAdapter->sessionId, pRoamProfile, &roamId);
9321
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309322 if ((eHAL_STATUS_SUCCESS != status) &&
9323 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9324 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309325
9326 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009327 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
9328 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
9329 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309330 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009331 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309332 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009333
9334 pRoamProfile->ChannelInfo.ChannelList = NULL;
9335 pRoamProfile->ChannelInfo.numOfChannels = 0;
9336
Jeff Johnson295189b2012-06-20 16:38:30 -07009337 }
9338 else
9339 {
9340 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
9341 return -EINVAL;
9342 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009343 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009344 return status;
9345}
9346
9347/*
9348 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
9349 * This function is used to set the authentication type (OPEN/SHARED).
9350 *
9351 */
9352static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
9353 enum nl80211_auth_type auth_type)
9354{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309355 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009356 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9357
9358 ENTER();
9359
9360 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309361 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07009362 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009363 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309364 hddLog(VOS_TRACE_LEVEL_INFO,
9365 "%s: set authentication type to AUTOSWITCH", __func__);
9366 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
9367 break;
9368
9369 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009370#ifdef WLAN_FEATURE_VOWIFI_11R
9371 case NL80211_AUTHTYPE_FT:
9372#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309373 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009374 "%s: set authentication type to OPEN", __func__);
9375 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9376 break;
9377
9378 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309379 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009380 "%s: set authentication type to SHARED", __func__);
9381 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
9382 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009383#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009384 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309385 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009386 "%s: set authentication type to CCKM WPA", __func__);
9387 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
9388 break;
9389#endif
9390
9391
9392 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309393 hddLog(VOS_TRACE_LEVEL_ERROR,
9394 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009395 auth_type);
9396 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
9397 return -EINVAL;
9398 }
9399
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309400 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009401 pHddStaCtx->conn_info.authType;
9402 return 0;
9403}
9404
9405/*
9406 * FUNCTION: wlan_hdd_set_akm_suite
9407 * This function is used to set the key mgmt type(PSK/8021x).
9408 *
9409 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309410static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009411 u32 key_mgmt
9412 )
9413{
9414 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9415 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309416
Jeff Johnson295189b2012-06-20 16:38:30 -07009417 /*set key mgmt type*/
9418 switch(key_mgmt)
9419 {
9420 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309421#ifdef WLAN_FEATURE_VOWIFI_11R
9422 case WLAN_AKM_SUITE_FT_PSK:
9423#endif
9424 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07009425 __func__);
9426 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
9427 break;
9428
9429 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309430#ifdef WLAN_FEATURE_VOWIFI_11R
9431 case WLAN_AKM_SUITE_FT_8021X:
9432#endif
9433 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009434 __func__);
9435 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9436 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009437#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009438#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
9439#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
9440 case WLAN_AKM_SUITE_CCKM:
9441 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
9442 __func__);
9443 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
9444 break;
9445#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -07009446#ifndef WLAN_AKM_SUITE_OSEN
9447#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
9448 case WLAN_AKM_SUITE_OSEN:
9449 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
9450 __func__);
9451 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9452 break;
9453#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009454
9455 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309456 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009457 __func__, key_mgmt);
9458 return -EINVAL;
9459
9460 }
9461 return 0;
9462}
9463
9464/*
9465 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309466 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07009467 * (NONE/WEP40/WEP104/TKIP/CCMP).
9468 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309469static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
9470 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07009471 bool ucast
9472 )
9473{
9474 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309475 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009476 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9477
9478 ENTER();
9479
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309480 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009481 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309482 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07009483 __func__, cipher);
9484 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9485 }
9486 else
9487 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309488
Jeff Johnson295189b2012-06-20 16:38:30 -07009489 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309490 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009491 {
9492 case IW_AUTH_CIPHER_NONE:
9493 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9494 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309495
Jeff Johnson295189b2012-06-20 16:38:30 -07009496 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309497 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07009498 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309499
Jeff Johnson295189b2012-06-20 16:38:30 -07009500 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309501 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07009502 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309503
Jeff Johnson295189b2012-06-20 16:38:30 -07009504 case WLAN_CIPHER_SUITE_TKIP:
9505 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
9506 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309507
Jeff Johnson295189b2012-06-20 16:38:30 -07009508 case WLAN_CIPHER_SUITE_CCMP:
9509 encryptionType = eCSR_ENCRYPT_TYPE_AES;
9510 break;
9511#ifdef FEATURE_WLAN_WAPI
9512 case WLAN_CIPHER_SUITE_SMS4:
9513 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
9514 break;
9515#endif
9516
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009517#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009518 case WLAN_CIPHER_SUITE_KRK:
9519 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
9520 break;
9521#endif
9522 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309523 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009524 __func__, cipher);
9525 return -EOPNOTSUPP;
9526 }
9527 }
9528
9529 if (ucast)
9530 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309531 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009532 __func__, encryptionType);
9533 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
9534 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309535 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009536 encryptionType;
9537 }
9538 else
9539 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309540 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009541 __func__, encryptionType);
9542 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
9543 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
9544 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
9545 }
9546
9547 return 0;
9548}
9549
9550
9551/*
9552 * FUNCTION: wlan_hdd_cfg80211_set_ie
9553 * This function is used to parse WPA/RSN IE's.
9554 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309555int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
9556 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07009557 size_t ie_len
9558 )
9559{
9560 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9561 u8 *genie = ie;
9562 v_U16_t remLen = ie_len;
9563#ifdef FEATURE_WLAN_WAPI
9564 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
9565 u16 *tmp;
9566 v_U16_t akmsuiteCount;
9567 int *akmlist;
9568#endif
9569 ENTER();
9570
9571 /* clear previous assocAddIE */
9572 pWextState->assocAddIE.length = 0;
9573 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009574 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009575
9576 while (remLen >= 2)
9577 {
9578 v_U16_t eLen = 0;
9579 v_U8_t elementId;
9580 elementId = *genie++;
9581 eLen = *genie++;
9582 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309583
Arif Hussain6d2a3322013-11-17 19:50:10 -08009584 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009585 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309586
9587 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309589 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009590 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 -07009591 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309592 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009593 "%s: Invalid WPA IE", __func__);
9594 return -EINVAL;
9595 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309596 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07009597 {
9598 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309599 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009600 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309601
Jeff Johnson295189b2012-06-20 16:38:30 -07009602 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9603 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009604 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
9605 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009606 VOS_ASSERT(0);
9607 return -ENOMEM;
9608 }
9609 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
9610 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9611 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309612
Jeff Johnson295189b2012-06-20 16:38:30 -07009613 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
9614 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9615 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9616 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309617 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
9618 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009619 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
9620 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
9621 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
9622 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
9623 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
9624 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309625 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05309626 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009627 {
9628 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309629 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009630 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309631
Jeff Johnson295189b2012-06-20 16:38:30 -07009632 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9633 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009634 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9635 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009636 VOS_ASSERT(0);
9637 return -ENOMEM;
9638 }
9639 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
9640 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9641 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309642
Jeff Johnson295189b2012-06-20 16:38:30 -07009643 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9644 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9645 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009646#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309647 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
9648 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009649 /*Consider WFD IE, only for P2P Client */
9650 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9651 {
9652 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309653 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009654 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309655
Jeff Johnson295189b2012-06-20 16:38:30 -07009656 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9657 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009658 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9659 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009660 VOS_ASSERT(0);
9661 return -ENOMEM;
9662 }
9663 // WFD IE is saved to Additional IE ; it should be accumulated to handle
9664 // WPS IE + P2P IE + WFD IE
9665 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9666 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309667
Jeff Johnson295189b2012-06-20 16:38:30 -07009668 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9669 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9670 }
9671#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009672 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309673 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009674 HS20_OUI_TYPE_SIZE)) )
9675 {
9676 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309677 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009678 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009679
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009680 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9681 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009682 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9683 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009684 VOS_ASSERT(0);
9685 return -ENOMEM;
9686 }
9687 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9688 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009689
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009690 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9691 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9692 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009693 /* Appending OSEN Information Element in Assiciation Request */
9694 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
9695 OSEN_OUI_TYPE_SIZE)) )
9696 {
9697 v_U16_t curAddIELen = pWextState->assocAddIE.length;
9698 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
9699 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009700
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009701 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9702 {
9703 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9704 "Need bigger buffer space");
9705 VOS_ASSERT(0);
9706 return -ENOMEM;
9707 }
9708 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9709 pWextState->assocAddIE.length += eLen + 2;
9710
9711 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
9712 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9713 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9714 }
9715
9716 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07009717 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
9718
9719 /* populating as ADDIE in beacon frames */
9720 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9721 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
9722 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
9723 {
9724 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
9725 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9726 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9727 {
9728 hddLog(LOGE,
9729 "Coldn't pass "
9730 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
9731 }
9732 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
9733 else
9734 hddLog(LOGE,
9735 "Could not pass on "
9736 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
9737
9738 /* IBSS mode doesn't contain params->proberesp_ies still
9739 beaconIE's need to be populated in probe response frames */
9740 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
9741 {
9742 u16 rem_probe_resp_ie_len = eLen + 2;
9743 u8 probe_rsp_ie_len[3] = {0};
9744 u8 counter = 0;
9745
9746 /* Check Probe Resp Length if it is greater then 255 then
9747 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
9748 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
9749 not able Store More then 255 bytes into One Variable */
9750
9751 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9752 {
9753 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9754 {
9755 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9756 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9757 }
9758 else
9759 {
9760 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9761 rem_probe_resp_ie_len = 0;
9762 }
9763 }
9764
9765 rem_probe_resp_ie_len = 0;
9766
9767 if (probe_rsp_ie_len[0] > 0)
9768 {
9769 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9770 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
9771 (tANI_U8*)(genie - 2),
9772 probe_rsp_ie_len[0], NULL,
9773 eANI_BOOLEAN_FALSE)
9774 == eHAL_STATUS_FAILURE)
9775 {
9776 hddLog(LOGE,
9777 "Could not pass"
9778 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
9779 }
9780 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9781 }
9782
9783 if (probe_rsp_ie_len[1] > 0)
9784 {
9785 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9786 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
9787 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
9788 probe_rsp_ie_len[1], NULL,
9789 eANI_BOOLEAN_FALSE)
9790 == eHAL_STATUS_FAILURE)
9791 {
9792 hddLog(LOGE,
9793 "Could not pass"
9794 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
9795 }
9796 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9797 }
9798
9799 if (probe_rsp_ie_len[2] > 0)
9800 {
9801 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9802 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
9803 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
9804 probe_rsp_ie_len[2], NULL,
9805 eANI_BOOLEAN_FALSE)
9806 == eHAL_STATUS_FAILURE)
9807 {
9808 hddLog(LOGE,
9809 "Could not pass"
9810 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
9811 }
9812 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9813 }
9814
9815 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
9816 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9817 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9818 {
9819 hddLog(LOGE,
9820 "Could not pass"
9821 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
9822 }
9823 }
9824 else
9825 {
9826 // Reset WNI_CFG_PROBE_RSP Flags
9827 wlan_hdd_reset_prob_rspies(pAdapter);
9828
9829 hddLog(VOS_TRACE_LEVEL_INFO,
9830 "%s: No Probe Response IE received in set beacon",
9831 __func__);
9832 }
9833 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009834 break;
9835 case DOT11F_EID_RSN:
9836 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
9837 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
9838 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
9839 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
9840 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
9841 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009842 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
9843 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309844 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009845 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309846 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009847 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309848
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009849 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9850 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009851 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9852 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009853 VOS_ASSERT(0);
9854 return -ENOMEM;
9855 }
9856 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9857 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309858
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009859 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9860 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9861 break;
9862 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009863#ifdef FEATURE_WLAN_WAPI
9864 case WLAN_EID_WAPI:
9865 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009866 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009867 pAdapter->wapi_info.nWapiMode);
9868 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309869 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07009870 akmsuiteCount = WPA_GET_LE16(tmp);
9871 tmp = tmp + 1;
9872 akmlist = (int *)(tmp);
9873 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
9874 {
9875 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
9876 }
9877 else
9878 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009879 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07009880 VOS_ASSERT(0);
9881 return -EINVAL;
9882 }
9883
9884 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
9885 {
9886 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009887 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009888 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309889 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009890 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309891 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009892 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009893 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009894 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
9895 }
9896 break;
9897#endif
9898 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309899 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009900 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009901 /* when Unknown IE is received we should break and continue
9902 * to the next IE in the buffer instead we were returning
9903 * so changing this to break */
9904 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009905 }
9906 genie += eLen;
9907 remLen -= eLen;
9908 }
9909 EXIT();
9910 return 0;
9911}
9912
9913/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05309914 * FUNCTION: hdd_isWPAIEPresent
9915 * Parse the received IE to find the WPA IE
9916 *
9917 */
9918static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
9919{
9920 v_U8_t eLen = 0;
9921 v_U16_t remLen = ie_len;
9922 v_U8_t elementId = 0;
9923
9924 while (remLen >= 2)
9925 {
9926 elementId = *ie++;
9927 eLen = *ie++;
9928 remLen -= 2;
9929 if (eLen > remLen)
9930 {
9931 hddLog(VOS_TRACE_LEVEL_ERROR,
9932 "%s: IE length is wrong %d", __func__, eLen);
9933 return FALSE;
9934 }
9935 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
9936 {
9937 /* OUI - 0x00 0X50 0XF2
9938 WPA Information Element - 0x01
9939 WPA version - 0x01*/
9940 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
9941 return TRUE;
9942 }
9943 ie += eLen;
9944 remLen -= eLen;
9945 }
9946 return FALSE;
9947}
9948
9949/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009950 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309951 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07009952 * parameters during connect operation.
9953 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309954int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009955 struct cfg80211_connect_params *req
9956 )
9957{
9958 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309959 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009960 ENTER();
9961
9962 /*set wpa version*/
9963 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
9964
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309965 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07009966 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05309967 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07009968 {
9969 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
9970 }
9971 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
9972 {
9973 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
9974 }
9975 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309976
9977 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009978 pWextState->wpaVersion);
9979
9980 /*set authentication type*/
9981 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
9982
9983 if (0 > status)
9984 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309985 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009986 "%s: failed to set authentication type ", __func__);
9987 return status;
9988 }
9989
9990 /*set key mgmt type*/
9991 if (req->crypto.n_akm_suites)
9992 {
9993 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
9994 if (0 > status)
9995 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309996 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07009997 __func__);
9998 return status;
9999 }
10000 }
10001
10002 /*set pairwise cipher type*/
10003 if (req->crypto.n_ciphers_pairwise)
10004 {
10005 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
10006 req->crypto.ciphers_pairwise[0], true);
10007 if (0 > status)
10008 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010009 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010010 "%s: failed to set unicast cipher type", __func__);
10011 return status;
10012 }
10013 }
10014 else
10015 {
10016 /*Reset previous cipher suite to none*/
10017 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
10018 if (0 > status)
10019 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010020 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010021 "%s: failed to set unicast cipher type", __func__);
10022 return status;
10023 }
10024 }
10025
10026 /*set group cipher type*/
10027 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
10028 false);
10029
10030 if (0 > status)
10031 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010032 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070010033 __func__);
10034 return status;
10035 }
10036
Chet Lanctot186b5732013-03-18 10:26:30 -070010037#ifdef WLAN_FEATURE_11W
10038 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
10039#endif
10040
Jeff Johnson295189b2012-06-20 16:38:30 -070010041 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
10042 if (req->ie_len)
10043 {
10044 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
10045 if ( 0 > status)
10046 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010047 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 __func__);
10049 return status;
10050 }
10051 }
10052
10053 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010054 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010055 {
10056 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
10057 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
10058 )
10059 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010060 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070010061 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
10062 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010063 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070010064 __func__);
10065 return -EOPNOTSUPP;
10066 }
10067 else
10068 {
10069 u8 key_len = req->key_len;
10070 u8 key_idx = req->key_idx;
10071
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010072 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010073 && (CSR_MAX_NUM_KEY > key_idx)
10074 )
10075 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010076 hddLog(VOS_TRACE_LEVEL_INFO,
10077 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010078 __func__, key_idx, key_len);
10079 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010080 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010081 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010082 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010083 (u8)key_len;
10084 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
10085 }
10086 }
10087 }
10088 }
10089
10090 return status;
10091}
10092
10093/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010094 * FUNCTION: wlan_hdd_try_disconnect
10095 * This function is used to disconnect from previous
10096 * connection
10097 */
10098static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
10099{
10100 long ret = 0;
10101 hdd_station_ctx_t *pHddStaCtx;
10102 eMib_dot11DesiredBssType connectedBssType;
10103
10104 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10105
10106 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
10107
10108 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
10109 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
10110 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
10111 {
10112 /* Issue disconnect to CSR */
10113 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10114 if( eHAL_STATUS_SUCCESS ==
10115 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10116 pAdapter->sessionId,
10117 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10118 {
10119 ret = wait_for_completion_interruptible_timeout(
10120 &pAdapter->disconnect_comp_var,
10121 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10122 if (0 >= ret)
10123 {
10124 hddLog(LOGE, FL("Failed to receive disconnect event"));
10125 return -EALREADY;
10126 }
10127 }
10128 }
10129 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
10130 {
10131 ret = wait_for_completion_interruptible_timeout(
10132 &pAdapter->disconnect_comp_var,
10133 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10134 if (0 >= ret)
10135 {
10136 hddLog(LOGE, FL("Failed to receive disconnect event"));
10137 return -EALREADY;
10138 }
10139 }
10140
10141 return 0;
10142}
10143
10144/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053010145 * FUNCTION: __wlan_hdd_cfg80211_connect
10146 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010147 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010148static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010149 struct net_device *ndev,
10150 struct cfg80211_connect_params *req
10151 )
10152{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010153 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010154 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Sushant Kaushikba6764e2014-06-30 19:52:09 +053010155 hdd_adapter_t *pHostapdAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010156 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053010157 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010158
10159 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010160
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010161 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10162 TRACE_CODE_HDD_CFG80211_CONNECT,
10163 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010164 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010165 "%s: device_mode = %s (%d)", __func__,
10166 hdd_device_modetoString(pAdapter->device_mode),
10167 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010168
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010169 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010170 if (!pHddCtx)
10171 {
10172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10173 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010174 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010175 }
10176
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010177 status = wlan_hdd_validate_context(pHddCtx);
10178
10179 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010180 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010181 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10182 "%s: HDD context is not valid", __func__);
10183 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010184 }
10185
Agarwal Ashish51325b52014-06-16 16:50:49 +053010186 if (vos_max_concurrent_connections_reached()) {
10187 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10188 return -ECONNREFUSED;
10189 }
10190
Jeff Johnson295189b2012-06-20 16:38:30 -070010191#ifdef WLAN_BTAMP_FEATURE
10192 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010193 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070010194 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010195 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010196 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010197 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070010198 }
10199#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010200
10201 //If Device Mode is Station Concurrent Sessions Exit BMps
10202 //P2P Mode will be taken care in Open/close adapter
10203 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010204 (vos_concurrent_open_sessions_running())) {
10205 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
10206 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010207 }
10208
10209 /*Try disconnecting if already in connected state*/
10210 status = wlan_hdd_try_disconnect(pAdapter);
10211 if ( 0 > status)
10212 {
10213 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10214 " connection"));
10215 return -EALREADY;
10216 }
10217
Jeff Johnson295189b2012-06-20 16:38:30 -070010218 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010219 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070010220
10221 if ( 0 > status)
10222 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010223 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070010224 __func__);
10225 return status;
10226 }
Sushant Kaushikba6764e2014-06-30 19:52:09 +053010227 /* For SAP + STA concurrency , driver only supports SCC.
10228 * if SAP is ON, driver will stop it and after assoc completion,
10229 * or failure, SAP will be started on STA channel to force SCC.
10230 */
10231 pHostapdAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_SOFTAP);
10232 if (pHostapdAdapter != NULL)
10233 {
10234 hddLog(VOS_TRACE_LEVEL_INFO, "Close SAP until STA is connected");
10235 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
10236 {
10237 WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext);
10238 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
10239 }
10240 }
Mohit Khanna765234a2012-09-11 15:08:35 -070010241 if ( req->channel )
10242 {
10243 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
10244 req->ssid_len, req->bssid,
10245 req->channel->hw_value);
10246 }
10247 else
10248 {
10249 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010250 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070010251 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010252
10253 if (0 > status)
10254 {
10255 //ReEnable BMPS if disabled
10256 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
10257 (NULL != pHddCtx))
10258 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010259 if (pHddCtx->hdd_wlan_suspended)
10260 {
10261 hdd_set_pwrparams(pHddCtx);
10262 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010263 //ReEnable Bmps and Imps back
10264 hdd_enable_bmps_imps(pHddCtx);
10265 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010266 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010267 return status;
10268 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010269 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010270 EXIT();
10271 return status;
10272}
10273
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010274static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
10275 struct net_device *ndev,
10276 struct cfg80211_connect_params *req)
10277{
10278 int ret;
10279 vos_ssr_protect(__func__);
10280 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
10281 vos_ssr_unprotect(__func__);
10282
10283 return ret;
10284}
Jeff Johnson295189b2012-06-20 16:38:30 -070010285
10286/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010287 * FUNCTION: wlan_hdd_disconnect
10288 * This function is used to issue a disconnect request to SME
10289 */
10290int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10291{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010292 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010293 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010294 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010295 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010296
10297 status = wlan_hdd_validate_context(pHddCtx);
10298
10299 if (0 != status)
10300 {
10301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10302 "%s: HDD context is not valid", __func__);
10303 return status;
10304 }
10305
10306 pHddCtx->isAmpAllowed = VOS_TRUE;
Abhishek Singhf4669da2014-05-26 15:07:49 +053010307 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10308 "%s: Set HDD connState to eConnectionState_Disconnecting",
10309 __func__);
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010310 pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010311 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010312
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010313 /*issue disconnect*/
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010314
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010315 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10316 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010317 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10318 {
10319 hddLog(VOS_TRACE_LEVEL_INFO,
10320 FL("status = %d, already disconnected"),
10321 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010322
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010323 }
10324 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010325 {
10326 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010327 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010328 __func__, (int)status );
10329 return -EINVAL;
10330 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010331 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010332 &pAdapter->disconnect_comp_var,
10333 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010334 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010335 {
10336 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010337 "%s: Failed to disconnect, timed out", __func__);
10338 return -ETIMEDOUT;
10339 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010340 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010341 {
10342 hddLog(VOS_TRACE_LEVEL_ERROR,
10343 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010344 return ret;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010345 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10347 FL("Set HDD connState to eConnectionState_NotConnected"));
10348 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10349
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010350 /*stop tx queues*/
10351 netif_tx_disable(pAdapter->dev);
10352 netif_carrier_off(pAdapter->dev);
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010353 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010354}
10355
10356
10357/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010358 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070010359 * This function is used to issue a disconnect request to SME
10360 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010361static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010362 struct net_device *dev,
10363 u16 reason
10364 )
10365{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010366 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010367 tCsrRoamProfile *pRoamProfile =
10368 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010369 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010370 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10371 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010372#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010373 tANI_U8 staIdx;
10374#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010375
Jeff Johnson295189b2012-06-20 16:38:30 -070010376 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010377
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010378 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10379 TRACE_CODE_HDD_CFG80211_DISCONNECT,
10380 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010381 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
10382 __func__, hdd_device_modetoString(pAdapter->device_mode),
10383 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010384
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010385 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
10386 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070010387
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010388 status = wlan_hdd_validate_context(pHddCtx);
10389
10390 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010391 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010392 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10393 "%s: HDD context is not valid", __func__);
10394 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010395 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010396
Jeff Johnson295189b2012-06-20 16:38:30 -070010397 if (NULL != pRoamProfile)
10398 {
10399 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010400 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
10401 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070010402 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010403 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070010404 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010405 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010406 switch(reason)
10407 {
10408 case WLAN_REASON_MIC_FAILURE:
10409 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
10410 break;
10411
10412 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
10413 case WLAN_REASON_DISASSOC_AP_BUSY:
10414 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
10415 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
10416 break;
10417
10418 case WLAN_REASON_PREV_AUTH_NOT_VALID:
10419 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053010420 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070010421 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
10422 break;
10423
Jeff Johnson295189b2012-06-20 16:38:30 -070010424 default:
10425 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
10426 break;
10427 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010428 pScanInfo = &pHddCtx->scan_info;
10429 if (pScanInfo->mScanPending)
10430 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010431 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010432 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010433 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
10434 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010435 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010436
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010437#ifdef FEATURE_WLAN_TDLS
10438 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010439 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010440 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010441 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
10442 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010443 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010444 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010445 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010446 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010447 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010448 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010449 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010450 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010451 pAdapter->sessionId,
10452 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010453 }
10454 }
10455#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010456 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010457 status = wlan_hdd_disconnect(pAdapter, reasonCode);
10458 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070010459 {
10460 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010461 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010462 __func__, (int)status );
10463 return -EINVAL;
10464 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010465 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010466 else
10467 {
10468 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
10469 "called while in %d state", __func__,
10470 pHddStaCtx->conn_info.connState);
10471 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010472 }
10473 else
10474 {
10475 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
10476 }
10477
10478 return status;
10479}
10480
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010481static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
10482 struct net_device *dev,
10483 u16 reason
10484 )
10485{
10486 int ret;
10487 vos_ssr_protect(__func__);
10488 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
10489 vos_ssr_unprotect(__func__);
10490
10491 return ret;
10492}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010493
Jeff Johnson295189b2012-06-20 16:38:30 -070010494/*
10495 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010496 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010497 * settings in IBSS mode.
10498 */
10499static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010500 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010501 struct cfg80211_ibss_params *params
10502 )
10503{
10504 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010505 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010506 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10507 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010508
Jeff Johnson295189b2012-06-20 16:38:30 -070010509 ENTER();
10510
10511 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070010512 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070010513
10514 if (params->ie_len && ( NULL != params->ie) )
10515 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010516 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10517 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010518 {
10519 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
10520 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10521 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010522 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010523 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010524 tDot11fIEWPA dot11WPAIE;
10525 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010526 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010527
Wilson Yang00256342013-10-10 23:13:38 -070010528 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010529 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10530 params->ie_len, DOT11F_EID_WPA);
10531 if ( NULL != ie )
10532 {
10533 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
10534 // Unpack the WPA IE
10535 //Skip past the EID byte and length byte - and four byte WiFi OUI
10536 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
10537 &ie[2+4],
10538 ie[1] - 4,
10539 &dot11WPAIE);
10540 /*Extract the multicast cipher, the encType for unicast
10541 cipher for wpa-none is none*/
10542 encryptionType =
10543 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
10544 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010545 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010546
Jeff Johnson295189b2012-06-20 16:38:30 -070010547 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
10548
10549 if (0 > status)
10550 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010551 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010552 __func__);
10553 return status;
10554 }
10555 }
10556
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010557 pWextState->roamProfile.AuthType.authType[0] =
10558 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070010559 eCSR_AUTH_TYPE_OPEN_SYSTEM;
10560
10561 if (params->privacy)
10562 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010563 /* Security enabled IBSS, At this time there is no information available
10564 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070010565 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010566 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070010567 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010568 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070010569 *enable privacy bit in beacons */
10570
10571 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
10572 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010573 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
10574 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070010575 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10576 pWextState->roamProfile.EncryptionType.numEntries = 1;
10577 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070010578 return status;
10579}
10580
10581/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010582 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010583 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070010584 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010585static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010586 struct net_device *dev,
10587 struct cfg80211_ibss_params *params
10588 )
10589{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010590 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010591 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10592 tCsrRoamProfile *pRoamProfile;
10593 int status;
krunal sonie9002db2013-11-25 14:24:17 -080010594 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010595 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10596 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010597
10598 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010599
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010600 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10601 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
10602 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010603 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010604 "%s: device_mode = %s (%d)", __func__,
10605 hdd_device_modetoString(pAdapter->device_mode),
10606 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010607
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010608 status = wlan_hdd_validate_context(pHddCtx);
10609
10610 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010611 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010612 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10613 "%s: HDD context is not valid", __func__);
10614 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010615 }
10616
10617 if (NULL == pWextState)
10618 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010619 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070010620 __func__);
10621 return -EIO;
10622 }
10623
Agarwal Ashish51325b52014-06-16 16:50:49 +053010624 if (vos_max_concurrent_connections_reached()) {
10625 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10626 return -ECONNREFUSED;
10627 }
10628
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010629 /*Try disconnecting if already in connected state*/
10630 status = wlan_hdd_try_disconnect(pAdapter);
10631 if ( 0 > status)
10632 {
10633 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10634 " IBSS connection"));
10635 return -EALREADY;
10636 }
10637
Jeff Johnson295189b2012-06-20 16:38:30 -070010638 pRoamProfile = &pWextState->roamProfile;
10639
10640 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
10641 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010642 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010643 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010644 return -EINVAL;
10645 }
10646
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070010647 /* BSSID is provided by upper layers hence no need to AUTO generate */
10648 if (NULL != params->bssid) {
10649 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
10650 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
10651 hddLog (VOS_TRACE_LEVEL_ERROR,
10652 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
10653 return -EIO;
10654 }
10655 }
krunal sonie9002db2013-11-25 14:24:17 -080010656 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
10657 {
10658 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
10659 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
10660 {
10661 hddLog (VOS_TRACE_LEVEL_ERROR,
10662 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
10663 return -EIO;
10664 }
10665 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
10666 if (!params->bssid)
10667 {
10668 hddLog (VOS_TRACE_LEVEL_ERROR,
10669 "%s:Failed memory allocation", __func__);
10670 return -EIO;
10671 }
10672 vos_mem_copy((v_U8_t *)params->bssid,
10673 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
10674 VOS_MAC_ADDR_SIZE);
10675 alloc_bssid = VOS_TRUE;
10676 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070010677
Jeff Johnson295189b2012-06-20 16:38:30 -070010678 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070010679 if (NULL !=
10680#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
10681 params->chandef.chan)
10682#else
10683 params->channel)
10684#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010685 {
10686 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010687 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10688 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10689 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10690 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010691
10692 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010693 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070010694 ieee80211_frequency_to_channel(
10695#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
10696 params->chandef.chan->center_freq);
10697#else
10698 params->channel->center_freq);
10699#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010700
10701 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10702 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070010703 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010704 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
10705 __func__);
10706 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010707 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010708
10709 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010710 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010711 if (channelNum == validChan[indx])
10712 {
10713 break;
10714 }
10715 }
10716 if (indx >= numChans)
10717 {
10718 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010719 __func__, channelNum);
10720 return -EINVAL;
10721 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010722 /* Set the Operational Channel */
10723 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
10724 channelNum);
10725 pRoamProfile->ChannelInfo.numOfChannels = 1;
10726 pHddStaCtx->conn_info.operationChannel = channelNum;
10727 pRoamProfile->ChannelInfo.ChannelList =
10728 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070010729 }
10730
10731 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010732 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070010733 if (status < 0)
10734 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010735 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070010736 __func__);
10737 return status;
10738 }
10739
10740 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010741 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010742 params->ssid_len, params->bssid,
10743 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010744
10745 if (0 > status)
10746 {
10747 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
10748 return status;
10749 }
10750
krunal sonie9002db2013-11-25 14:24:17 -080010751 if (NULL != params->bssid &&
10752 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
10753 alloc_bssid == VOS_TRUE)
10754 {
10755 vos_mem_free(params->bssid);
10756 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010757 return 0;
10758}
10759
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010760static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
10761 struct net_device *dev,
10762 struct cfg80211_ibss_params *params
10763 )
10764{
10765 int ret = 0;
10766
10767 vos_ssr_protect(__func__);
10768 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
10769 vos_ssr_unprotect(__func__);
10770
10771 return ret;
10772}
10773
Jeff Johnson295189b2012-06-20 16:38:30 -070010774/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010775 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010776 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070010777 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010778static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010779 struct net_device *dev
10780 )
10781{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010782 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010783 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10784 tCsrRoamProfile *pRoamProfile;
10785 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010786 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010787
10788 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010789
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010790 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10791 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
10792 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010793 status = wlan_hdd_validate_context(pHddCtx);
10794
10795 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010796 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010797 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10798 "%s: HDD context is not valid", __func__);
10799 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010800 }
10801
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010802 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
10803 hdd_device_modetoString(pAdapter->device_mode),
10804 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010805 if (NULL == pWextState)
10806 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010807 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070010808 __func__);
10809 return -EIO;
10810 }
10811
10812 pRoamProfile = &pWextState->roamProfile;
10813
10814 /* Issue disconnect only if interface type is set to IBSS */
10815 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
10816 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010817 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070010818 __func__);
10819 return -EINVAL;
10820 }
10821
10822 /* Issue Disconnect request */
10823 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10824 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
10825 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
10826
10827 return 0;
10828}
10829
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010830static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
10831 struct net_device *dev
10832 )
10833{
10834 int ret = 0;
10835
10836 vos_ssr_protect(__func__);
10837 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
10838 vos_ssr_unprotect(__func__);
10839
10840 return ret;
10841}
10842
Jeff Johnson295189b2012-06-20 16:38:30 -070010843/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010844 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070010845 * This function is used to set the phy parameters
10846 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
10847 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010848static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010849 u32 changed)
10850{
10851 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
10852 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010853 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010854
10855 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010856 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10857 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
10858 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010859 status = wlan_hdd_validate_context(pHddCtx);
10860
10861 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010862 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10864 "%s: HDD context is not valid", __func__);
10865 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010866 }
10867
Jeff Johnson295189b2012-06-20 16:38:30 -070010868 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
10869 {
10870 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
10871 WNI_CFG_RTS_THRESHOLD_STAMAX :
10872 wiphy->rts_threshold;
10873
10874 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010875 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070010876 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010877 hddLog(VOS_TRACE_LEVEL_ERROR,
10878 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010879 __func__, rts_threshold);
10880 return -EINVAL;
10881 }
10882
10883 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
10884 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010885 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010886 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010887 hddLog(VOS_TRACE_LEVEL_ERROR,
10888 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010889 __func__, rts_threshold);
10890 return -EIO;
10891 }
10892
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010893 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010894 rts_threshold);
10895 }
10896
10897 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
10898 {
10899 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
10900 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
10901 wiphy->frag_threshold;
10902
10903 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010904 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010905 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010906 hddLog(VOS_TRACE_LEVEL_ERROR,
10907 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010908 frag_threshold);
10909 return -EINVAL;
10910 }
10911
10912 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
10913 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010914 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010915 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010916 hddLog(VOS_TRACE_LEVEL_ERROR,
10917 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010918 __func__, frag_threshold);
10919 return -EIO;
10920 }
10921
10922 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
10923 frag_threshold);
10924 }
10925
10926 if ((changed & WIPHY_PARAM_RETRY_SHORT)
10927 || (changed & WIPHY_PARAM_RETRY_LONG))
10928 {
10929 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
10930 wiphy->retry_short :
10931 wiphy->retry_long;
10932
10933 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
10934 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
10935 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010936 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010937 __func__, retry_value);
10938 return -EINVAL;
10939 }
10940
10941 if (changed & WIPHY_PARAM_RETRY_SHORT)
10942 {
10943 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
10944 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010945 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010946 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010947 hddLog(VOS_TRACE_LEVEL_ERROR,
10948 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010949 __func__, retry_value);
10950 return -EIO;
10951 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010952 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010953 __func__, retry_value);
10954 }
10955 else if (changed & WIPHY_PARAM_RETRY_SHORT)
10956 {
10957 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
10958 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010959 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010960 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010961 hddLog(VOS_TRACE_LEVEL_ERROR,
10962 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010963 __func__, retry_value);
10964 return -EIO;
10965 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010966 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010967 __func__, retry_value);
10968 }
10969 }
10970
10971 return 0;
10972}
10973
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010974static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
10975 u32 changed)
10976{
10977 int ret;
10978
10979 vos_ssr_protect(__func__);
10980 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
10981 vos_ssr_unprotect(__func__);
10982
10983 return ret;
10984}
10985
Jeff Johnson295189b2012-06-20 16:38:30 -070010986/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010987 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070010988 * This function is used to set the txpower
10989 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010990static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070010991#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
10992 struct wireless_dev *wdev,
10993#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010994#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010995 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070010996#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010997 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070010998#endif
10999 int dbm)
11000{
11001 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011002 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011003 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11004 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011005 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011006
11007 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011008 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11009 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
11010 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011011 status = wlan_hdd_validate_context(pHddCtx);
11012
11013 if (0 != status)
11014 {
11015 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11016 "%s: HDD context is not valid", __func__);
11017 return status;
11018 }
11019
11020 hHal = pHddCtx->hHal;
11021
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011022 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
11023 dbm, ccmCfgSetCallback,
11024 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011025 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011026 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011027 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
11028 return -EIO;
11029 }
11030
11031 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
11032 dbm);
11033
11034 switch(type)
11035 {
11036 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
11037 /* Fall through */
11038 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
11039 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
11040 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011041 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
11042 __func__);
11043 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011044 }
11045 break;
11046 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011047 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011048 __func__);
11049 return -EOPNOTSUPP;
11050 break;
11051 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011052 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
11053 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070011054 return -EIO;
11055 }
11056
11057 return 0;
11058}
11059
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011060static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
11061#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11062 struct wireless_dev *wdev,
11063#endif
11064#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11065 enum tx_power_setting type,
11066#else
11067 enum nl80211_tx_power_setting type,
11068#endif
11069 int dbm)
11070{
11071 int ret;
11072 vos_ssr_protect(__func__);
11073 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
11074#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11075 wdev,
11076#endif
11077#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11078 type,
11079#else
11080 type,
11081#endif
11082 dbm);
11083 vos_ssr_unprotect(__func__);
11084
11085 return ret;
11086}
11087
Jeff Johnson295189b2012-06-20 16:38:30 -070011088/*
11089 * FUNCTION: wlan_hdd_cfg80211_get_txpower
11090 * This function is used to read the txpower
11091 */
Yue Maf49ba872013-08-19 12:04:25 -070011092static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
11093#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11094 struct wireless_dev *wdev,
11095#endif
11096 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070011097{
11098
11099 hdd_adapter_t *pAdapter;
11100 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011101 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011102
Jeff Johnsone7245742012-09-05 17:12:55 -070011103 ENTER();
11104
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011105 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011106
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011107 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011108 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11110 "%s: HDD context is not valid", __func__);
11111 *dbm = 0;
11112 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011113 }
11114
Jeff Johnson295189b2012-06-20 16:38:30 -070011115 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
11116 if (NULL == pAdapter)
11117 {
11118 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
11119 return -ENOENT;
11120 }
11121
11122 wlan_hdd_get_classAstats(pAdapter);
11123 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
11124
Jeff Johnsone7245742012-09-05 17:12:55 -070011125 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011126 return 0;
11127}
11128
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011129static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011130 u8* mac, struct station_info *sinfo)
11131{
11132 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11133 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11134 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053011135 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070011136
11137 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
11138 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011139
11140 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
11141 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
11142 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
11143 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
11144 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
11145 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
11146 tANI_U16 maxRate = 0;
11147 tANI_U16 myRate;
11148 tANI_U16 currentRate = 0;
11149 tANI_U8 maxSpeedMCS = 0;
11150 tANI_U8 maxMCSIdx = 0;
11151 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053011152 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070011153 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011154 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011155
Leo Chang6f8870f2013-03-26 18:11:36 -070011156#ifdef WLAN_FEATURE_11AC
11157 tANI_U32 vht_mcs_map;
11158 eDataRate11ACMaxMcs vhtMaxMcs;
11159#endif /* WLAN_FEATURE_11AC */
11160
Jeff Johnsone7245742012-09-05 17:12:55 -070011161 ENTER();
11162
Jeff Johnson295189b2012-06-20 16:38:30 -070011163 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
11164 (0 == ssidlen))
11165 {
11166 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
11167 " Invalid ssidlen, %d", __func__, ssidlen);
11168 /*To keep GUI happy*/
11169 return 0;
11170 }
11171
Mukul Sharma811205f2014-07-09 21:07:30 +053011172 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
11173 {
11174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11175 "%s: Roaming in progress, so unable to proceed this request", __func__);
11176 return 0;
11177 }
11178
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011179 status = wlan_hdd_validate_context(pHddCtx);
11180
11181 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011182 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11184 "%s: HDD context is not valid", __func__);
11185 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011186 }
11187
Jeff Johnson295189b2012-06-20 16:38:30 -070011188
Kiet Lam3b17fc82013-09-27 05:24:08 +053011189 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
11190 sinfo->filled |= STATION_INFO_SIGNAL;
11191
c_hpothu09f19542014-05-30 21:53:31 +053011192 wlan_hdd_get_station_stats(pAdapter);
11193 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
11194
11195 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053011196 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
11197 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053011198 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053011199 {
11200 rate_flags = pAdapter->maxRateFlags;
11201 }
c_hpothu44ff4e02014-05-08 00:13:57 +053011202
Jeff Johnson295189b2012-06-20 16:38:30 -070011203 //convert to the UI units of 100kbps
11204 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
11205
11206#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070011207 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 -070011208 sinfo->signal,
11209 pCfg->reportMaxLinkSpeed,
11210 myRate,
11211 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011212 (int) pCfg->linkSpeedRssiMid,
11213 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070011214 (int) rate_flags,
11215 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011216#endif //LINKSPEED_DEBUG_ENABLED
11217
11218 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
11219 {
11220 // we do not want to necessarily report the current speed
11221 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
11222 {
11223 // report the max possible speed
11224 rssidx = 0;
11225 }
11226 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
11227 {
11228 // report the max possible speed with RSSI scaling
11229 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
11230 {
11231 // report the max possible speed
11232 rssidx = 0;
11233 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011234 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070011235 {
11236 // report middle speed
11237 rssidx = 1;
11238 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011239 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
11240 {
11241 // report middle speed
11242 rssidx = 2;
11243 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011244 else
11245 {
11246 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011247 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070011248 }
11249 }
11250 else
11251 {
11252 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
11253 hddLog(VOS_TRACE_LEVEL_ERROR,
11254 "%s: Invalid value for reportMaxLinkSpeed: %u",
11255 __func__, pCfg->reportMaxLinkSpeed);
11256 rssidx = 0;
11257 }
11258
11259 maxRate = 0;
11260
11261 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011262 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
11263 OperationalRates, &ORLeng))
11264 {
11265 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11266 /*To keep GUI happy*/
11267 return 0;
11268 }
11269
Jeff Johnson295189b2012-06-20 16:38:30 -070011270 for (i = 0; i < ORLeng; i++)
11271 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011272 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011273 {
11274 /* Validate Rate Set */
11275 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
11276 {
11277 currentRate = supported_data_rate[j].supported_rate[rssidx];
11278 break;
11279 }
11280 }
11281 /* Update MAX rate */
11282 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11283 }
11284
11285 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011286 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
11287 ExtendedRates, &ERLeng))
11288 {
11289 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11290 /*To keep GUI happy*/
11291 return 0;
11292 }
11293
Jeff Johnson295189b2012-06-20 16:38:30 -070011294 for (i = 0; i < ERLeng; i++)
11295 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011296 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011297 {
11298 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
11299 {
11300 currentRate = supported_data_rate[j].supported_rate[rssidx];
11301 break;
11302 }
11303 }
11304 /* Update MAX rate */
11305 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11306 }
c_hpothu79aab322014-07-14 21:11:01 +053011307
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011308 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053011309 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011310 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053011311 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070011312 {
c_hpothu79aab322014-07-14 21:11:01 +053011313 if (rate_flags & eHAL_TX_RATE_VHT80)
11314 mode = 2;
11315 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
11316 mode = 1;
11317 else
11318 mode = 0;
11319
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011320 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
11321 MCSRates, &MCSLeng))
11322 {
11323 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11324 /*To keep GUI happy*/
11325 return 0;
11326 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011327 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070011328#ifdef WLAN_FEATURE_11AC
11329 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011330 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070011331 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011332 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011333 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070011334 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070011335 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011336 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070011337 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011338 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070011339 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011340 maxMCSIdx = 7;
11341 }
11342 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
11343 {
11344 maxMCSIdx = 8;
11345 }
11346 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
11347 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011348 //VHT20 is supporting 0~8
11349 if (rate_flags & eHAL_TX_RATE_VHT20)
11350 maxMCSIdx = 8;
11351 else
11352 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070011353 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011354
c_hpothu79aab322014-07-14 21:11:01 +053011355 if (0 != rssidx)/*check for scaled */
11356 {
11357 //get middle rate MCS index if rssi=1/2
11358 for (i=0; i <= maxMCSIdx; i++)
11359 {
11360 if (sinfo->signal <= rssiMcsTbl[mode][i])
11361 {
11362 maxMCSIdx = i;
11363 break;
11364 }
11365 }
11366 }
11367
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011368 if (rate_flags & eHAL_TX_RATE_VHT80)
11369 {
11370 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
11371 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
11372 }
11373 else if (rate_flags & eHAL_TX_RATE_VHT40)
11374 {
11375 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
11376 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
11377 }
11378 else if (rate_flags & eHAL_TX_RATE_VHT20)
11379 {
11380 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
11381 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
11382 }
11383
Leo Chang6f8870f2013-03-26 18:11:36 -070011384 maxSpeedMCS = 1;
11385 if (currentRate > maxRate)
11386 {
11387 maxRate = currentRate;
11388 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011389
Leo Chang6f8870f2013-03-26 18:11:36 -070011390 }
11391 else
11392#endif /* WLAN_FEATURE_11AC */
11393 {
11394 if (rate_flags & eHAL_TX_RATE_HT40)
11395 {
11396 rateFlag |= 1;
11397 }
11398 if (rate_flags & eHAL_TX_RATE_SGI)
11399 {
11400 rateFlag |= 2;
11401 }
11402
c_hpothu79aab322014-07-14 21:11:01 +053011403 if (rssidx == 1 || rssidx == 2)
11404 {
11405 //get middle rate MCS index if rssi=1/2
11406 for (i=0; i <= 7; i++)
11407 {
11408 if (sinfo->signal <= rssiMcsTbl[mode][i])
11409 {
11410 temp = i+1;
11411 break;
11412 }
11413 }
11414 }
11415 else
Leo Chang6f8870f2013-03-26 18:11:36 -070011416 {
11417 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053011418 }
11419
11420 for (i = 0; i < MCSLeng; i++)
11421 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011422 for (j = 0; j < temp; j++)
11423 {
11424 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
11425 {
11426 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
11427 break;
11428 }
11429 }
11430 if ((j < temp) && (currentRate > maxRate))
11431 {
11432 maxRate = currentRate;
11433 maxSpeedMCS = 1;
11434 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
11435 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011436 }
11437 }
11438 }
11439
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011440 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
11441 {
11442 maxRate = myRate;
11443 maxSpeedMCS = 1;
11444 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11445 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011446 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053011447 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070011448 {
11449 maxRate = myRate;
11450 if (rate_flags & eHAL_TX_RATE_LEGACY)
11451 {
11452 maxSpeedMCS = 0;
11453 }
11454 else
11455 {
11456 maxSpeedMCS = 1;
11457 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11458 }
11459 }
11460
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011461 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070011462 {
11463 sinfo->txrate.legacy = maxRate;
11464#ifdef LINKSPEED_DEBUG_ENABLED
11465 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
11466#endif //LINKSPEED_DEBUG_ENABLED
11467 }
11468 else
11469 {
11470 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070011471#ifdef WLAN_FEATURE_11AC
11472 sinfo->txrate.nss = 1;
11473 if (rate_flags & eHAL_TX_RATE_VHT80)
11474 {
11475 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011476 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070011477 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011478 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070011479 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011480 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11481 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11482 }
11483 else if (rate_flags & eHAL_TX_RATE_VHT20)
11484 {
11485 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11486 }
11487#endif /* WLAN_FEATURE_11AC */
11488 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
11489 {
11490 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11491 if (rate_flags & eHAL_TX_RATE_HT40)
11492 {
11493 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11494 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011495 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011496 if (rate_flags & eHAL_TX_RATE_SGI)
11497 {
11498 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11499 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011500
Jeff Johnson295189b2012-06-20 16:38:30 -070011501#ifdef LINKSPEED_DEBUG_ENABLED
11502 pr_info("Reporting MCS rate %d flags %x\n",
11503 sinfo->txrate.mcs,
11504 sinfo->txrate.flags );
11505#endif //LINKSPEED_DEBUG_ENABLED
11506 }
11507 }
11508 else
11509 {
11510 // report current rate instead of max rate
11511
11512 if (rate_flags & eHAL_TX_RATE_LEGACY)
11513 {
11514 //provide to the UI in units of 100kbps
11515 sinfo->txrate.legacy = myRate;
11516#ifdef LINKSPEED_DEBUG_ENABLED
11517 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
11518#endif //LINKSPEED_DEBUG_ENABLED
11519 }
11520 else
11521 {
11522 //must be MCS
11523 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070011524#ifdef WLAN_FEATURE_11AC
11525 sinfo->txrate.nss = 1;
11526 if (rate_flags & eHAL_TX_RATE_VHT80)
11527 {
11528 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11529 }
11530 else
11531#endif /* WLAN_FEATURE_11AC */
11532 {
11533 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11534 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011535 if (rate_flags & eHAL_TX_RATE_SGI)
11536 {
11537 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11538 }
11539 if (rate_flags & eHAL_TX_RATE_HT40)
11540 {
11541 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11542 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011543#ifdef WLAN_FEATURE_11AC
11544 else if (rate_flags & eHAL_TX_RATE_VHT80)
11545 {
11546 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
11547 }
11548#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070011549#ifdef LINKSPEED_DEBUG_ENABLED
11550 pr_info("Reporting actual MCS rate %d flags %x\n",
11551 sinfo->txrate.mcs,
11552 sinfo->txrate.flags );
11553#endif //LINKSPEED_DEBUG_ENABLED
11554 }
11555 }
11556 sinfo->filled |= STATION_INFO_TX_BITRATE;
11557
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070011558 sinfo->tx_packets =
11559 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
11560 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
11561 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
11562 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
11563
11564 sinfo->tx_retries =
11565 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
11566 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
11567 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
11568 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
11569
11570 sinfo->tx_failed =
11571 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
11572 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
11573 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
11574 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
11575
11576 sinfo->filled |=
11577 STATION_INFO_TX_PACKETS |
11578 STATION_INFO_TX_RETRIES |
11579 STATION_INFO_TX_FAILED;
11580
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011581 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11582 TRACE_CODE_HDD_CFG80211_GET_STA,
11583 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070011584 EXIT();
11585 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011586}
11587
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011588static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
11589 u8* mac, struct station_info *sinfo)
11590{
11591 int ret;
11592
11593 vos_ssr_protect(__func__);
11594 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
11595 vos_ssr_unprotect(__func__);
11596
11597 return ret;
11598}
11599
11600static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070011601 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070011602{
11603 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011604 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011605 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011606 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011607
Jeff Johnsone7245742012-09-05 17:12:55 -070011608 ENTER();
11609
Jeff Johnson295189b2012-06-20 16:38:30 -070011610 if (NULL == pAdapter)
11611 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011612 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011613 return -ENODEV;
11614 }
11615
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011616 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11617 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
11618 pAdapter->sessionId, timeout));
11619
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011620 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011621 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011622
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011623 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011624 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11626 "%s: HDD context is not valid", __func__);
11627 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011628 }
11629
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011630 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
11631 (TRUE == pHddCtx->hdd_wlan_suspended) &&
11632 (pHddCtx->cfg_ini->fhostArpOffload) &&
11633 (eConnectionState_Associated ==
11634 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
11635 {
Amar Singhald53568e2013-09-26 11:03:45 -070011636
11637 hddLog(VOS_TRACE_LEVEL_INFO,
11638 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053011639 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011640 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11641 {
11642 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011643 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011644 __func__, vos_status);
11645 }
11646 }
11647
Jeff Johnson295189b2012-06-20 16:38:30 -070011648 /**The get power cmd from the supplicant gets updated by the nl only
11649 *on successful execution of the function call
11650 *we are oppositely mapped w.r.t mode in the driver
11651 **/
11652 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
11653
Jeff Johnsone7245742012-09-05 17:12:55 -070011654 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011655 if (VOS_STATUS_E_FAILURE == vos_status)
11656 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011657 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11658 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011659 return -EINVAL;
11660 }
11661 return 0;
11662}
11663
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011664static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
11665 struct net_device *dev, bool mode, int timeout)
11666{
11667 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011668
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011669 vos_ssr_protect(__func__);
11670 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
11671 vos_ssr_unprotect(__func__);
11672
11673 return ret;
11674}
Jeff Johnson295189b2012-06-20 16:38:30 -070011675#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11676static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
11677 struct net_device *netdev,
11678 u8 key_index)
11679{
Jeff Johnsone7245742012-09-05 17:12:55 -070011680 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011681 return 0;
11682}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011683#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070011684
11685#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
11686static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
11687 struct net_device *dev,
11688 struct ieee80211_txq_params *params)
11689{
Jeff Johnsone7245742012-09-05 17:12:55 -070011690 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011691 return 0;
11692}
11693#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11694static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
11695 struct ieee80211_txq_params *params)
11696{
Jeff Johnsone7245742012-09-05 17:12:55 -070011697 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011698 return 0;
11699}
11700#endif //LINUX_VERSION_CODE
11701
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011702static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011703 struct net_device *dev, u8 *mac)
11704{
11705 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011706 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011707 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011708 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011709 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011710
Jeff Johnsone7245742012-09-05 17:12:55 -070011711 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011712
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011713 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070011714 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011715 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011716 return -EINVAL;
11717 }
11718
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011719 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11720 TRACE_CODE_HDD_CFG80211_DEL_STA,
11721 pAdapter->sessionId, pAdapter->device_mode));
11722
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011723 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11724 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011725
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011726 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011727 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11729 "%s: HDD context is not valid", __func__);
11730 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011731 }
11732
Jeff Johnson295189b2012-06-20 16:38:30 -070011733 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011734 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011735 )
11736 {
11737 if( NULL == mac )
11738 {
11739 v_U16_t i;
11740 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
11741 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011742 if ((pAdapter->aStaInfo[i].isUsed) &&
11743 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070011744 {
11745 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
11746 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011747 "%s: Delete STA with MAC::"
11748 MAC_ADDRESS_STR,
11749 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011750 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
11751 if (VOS_IS_STATUS_SUCCESS(vos_status))
11752 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011753 }
11754 }
11755 }
11756 else
11757 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011758
11759 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
11760 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11761 {
11762 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011763 "%s: Skip this DEL STA as this is not used::"
11764 MAC_ADDRESS_STR,
11765 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011766 return -ENOENT;
11767 }
11768
11769 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
11770 {
11771 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011772 "%s: Skip this DEL STA as deauth is in progress::"
11773 MAC_ADDRESS_STR,
11774 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011775 return -ENOENT;
11776 }
11777
11778 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
11779
Jeff Johnson295189b2012-06-20 16:38:30 -070011780 hddLog(VOS_TRACE_LEVEL_INFO,
11781 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080011782 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011783 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080011784 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011785
11786 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
11787 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11788 {
11789 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
11790 hddLog(VOS_TRACE_LEVEL_INFO,
11791 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080011792 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011793 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080011794 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011795 return -ENOENT;
11796 }
11797
Jeff Johnson295189b2012-06-20 16:38:30 -070011798 }
11799 }
11800
11801 EXIT();
11802
11803 return 0;
11804}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011805static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
11806 struct net_device *dev, u8 *mac)
11807{
11808 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011809
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011810 vos_ssr_protect(__func__);
11811 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, mac);
11812 vos_ssr_unprotect(__func__);
11813
11814 return ret;
11815}
11816
11817static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011818 struct net_device *dev, u8 *mac, struct station_parameters *params)
11819{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011820 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080011821 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011822#ifdef FEATURE_WLAN_TDLS
11823 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011824 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011825
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011826 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11827 TRACE_CODE_HDD_CFG80211_ADD_STA,
11828 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011829 mask = params->sta_flags_mask;
11830
11831 set = params->sta_flags_set;
11832
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011833#ifdef WLAN_FEATURE_TDLS_DEBUG
11834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11835 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
11836 __func__, mask, set, MAC_ADDR_ARRAY(mac));
11837#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011838
11839 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11840 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011841 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011842 }
11843 }
11844#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080011845 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011846}
11847
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011848static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
11849 struct net_device *dev, u8 *mac, struct station_parameters *params)
11850{
11851 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011852
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011853 vos_ssr_protect(__func__);
11854 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
11855 vos_ssr_unprotect(__func__);
11856
11857 return ret;
11858}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011859#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070011860
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011861static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070011862 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011863{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011864 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011865 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011866 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011867 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011868 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011869 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011870 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011871 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011872 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
11873 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -070011874
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011875 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011876 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011877 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011878 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011879 return -EINVAL;
11880 }
11881
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011882 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11883 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011884
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011885 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011886 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11888 "%s: HDD context is not valid", __func__);
11889 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011890 }
11891
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011892 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011893 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011894 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011895
Agarwal Ashish3da95242014-05-21 14:57:17 +053011896 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011897 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011898 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011899 pmksa->bssid, WNI_CFG_BSSID_LEN))
11900 {
11901 /* BSSID matched previous entry. Overwrite it. */
11902 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053011903 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011904 pmksa->bssid, WNI_CFG_BSSID_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011905 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011906 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011907 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011908 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011909 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011910 dump_bssid(pmksa->bssid);
11911 dump_pmkid(halHandle, pmksa->pmkid);
11912 break;
11913 }
11914 }
11915
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070011916 /* Check we compared all entries,if then take the first slot now */
Agarwal Ashish3da95242014-05-21 14:57:17 +053011917 if (j == MAX_PMKSAIDS_IN_CACHE) pHddStaCtx->PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070011918
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011919 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011920 {
11921 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Agarwal Ashish3da95242014-05-21 14:57:17 +053011922 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011923 pmksa->bssid, ETHER_ADDR_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011924 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011925 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011926 CSR_RSN_PMKID_SIZE);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011927 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Adding a new cache entry %d.",
11928 __func__, pHddStaCtx->PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011929 dump_bssid(pmksa->bssid);
11930 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011931 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011932 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Agarwal Ashish3da95242014-05-21 14:57:17 +053011933 if (pHddStaCtx->PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1))
11934 pHddStaCtx->PMKIDCacheIndex++;
11935 else
11936 pHddStaCtx->PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011937 }
11938
11939
11940 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Agarwal Ashish3da95242014-05-21 14:57:17 +053011941 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
11942 __func__, pHddStaCtx->PMKIDCacheIndex );
11943
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011944 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011945 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Agarwal Ashish3da95242014-05-21 14:57:17 +053011946 pHddStaCtx->PMKIDCache,
11947 pHddStaCtx->PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011948 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11949 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
11950 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011951 return 0;
11952}
11953
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011954static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
11955 struct cfg80211_pmksa *pmksa)
11956{
11957 int ret;
11958
11959 vos_ssr_protect(__func__);
11960 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
11961 vos_ssr_unprotect(__func__);
11962
11963 return ret;
11964}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011965
Wilson Yang6507c4e2013-10-01 20:11:19 -070011966
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011967static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070011968 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011969{
Wilson Yang6507c4e2013-10-01 20:11:19 -070011970 tANI_U32 j=0;
11971 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011972 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011973 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011974 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011975 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080011976 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011977
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011978 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
11979 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070011980
11981 /* Validate pAdapter */
11982 if (NULL == pAdapter)
11983 {
11984 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
11985 return -EINVAL;
11986 }
11987
11988 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11989 status = wlan_hdd_validate_context(pHddCtx);
11990
11991 if (0 != status)
11992 {
11993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11994 "%s: HDD context is not valid", __func__);
11995 return status;
11996 }
11997
11998 /*Retrieve halHandle*/
11999 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012000 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012001
12002 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012003 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012004 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012005 hddLog(VOS_TRACE_LEVEL_INFO, FL("No entries to flush"));
12006 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012007 }
12008
12009 /*find the matching PMKSA entry from j=0 to (index-1),
12010 * and delete the matched one
12011 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012012 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012013 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012014 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Wilson Yang6507c4e2013-10-01 20:11:19 -070012015 pmksa->bssid,
12016 WNI_CFG_BSSID_LEN))
12017 {
12018 /* BSSID matched entry */
12019 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053012020 if (j < pHddStaCtx->PMKIDCacheIndex-1)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012021 {
12022 /*replace the matching entry with the last entry in HDD local cache*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012023 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
12024 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
12025 VOS_MAC_ADDR_SIZE);
12026 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
12027 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
12028 CSR_RSN_PMKID_SIZE);
12029 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070012030
12031 /*clear the last entry in HDD cache ---[index-1]*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012032 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
12033 VOS_MAC_ADDR_SIZE);
12034 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
12035 CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012036 /*reduce the PMKID array index*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012037 pHddStaCtx->PMKIDCacheIndex--;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012038 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080012039 if (eHAL_STATUS_SUCCESS !=
12040 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -070012041 {
12042 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
Agarwal Ashish3da95242014-05-21 14:57:17 +053012043 __func__, pHddStaCtx->PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -080012044 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012045 }
12046
12047 dump_bssid(pmksa->bssid);
12048 dump_pmkid(halHandle,pmksa->pmkid);
12049
12050 break;
12051 }
12052 }
12053
12054 /* we compare all entries,but cannot find matching entry */
12055 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
12056 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012057 hddLog(VOS_TRACE_LEVEL_FATAL,
12058 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
12059 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070012060 dump_bssid(pmksa->bssid);
12061 dump_pmkid(halHandle, pmksa->pmkid);
12062 return -EINVAL;
12063 }
Wilson Yangef657d32014-01-15 19:19:23 -080012064 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012065}
12066
Wilson Yang6507c4e2013-10-01 20:11:19 -070012067
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012068static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
12069 struct cfg80211_pmksa *pmksa)
12070{
12071 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012072
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012073 vos_ssr_protect(__func__);
12074 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
12075 vos_ssr_unprotect(__func__);
12076
12077 return ret;
12078
12079}
12080
12081static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012082{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012083 tANI_U32 j=0;
12084 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012085 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012086 tHalHandle halHandle;
12087 hdd_context_t *pHddCtx;
12088 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -080012089 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012090
12091 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
12092
12093 /* Validate pAdapter */
12094 if (NULL == pAdapter)
12095 {
12096 hddLog(VOS_TRACE_LEVEL_ERROR,
12097 "%s: Invalid Adapter" ,__func__);
12098 return -EINVAL;
12099 }
12100
12101 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12102 status = wlan_hdd_validate_context(pHddCtx);
12103
12104 if (0 != status)
12105 {
12106 hddLog(VOS_TRACE_LEVEL_ERROR,
12107 "%s: HDD context is not valid", __func__);
12108 return status;
12109 }
12110
12111 /*Retrieve halHandle*/
12112 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012113 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012114
12115 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012116 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012117 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012118 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Agarwal Ashish3da95242014-05-21 14:57:17 +053012119 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012120 }
12121
12122 /*delete all the PMKSA one by one */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012123 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012124 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012125 pBSSId =(tANI_U8 *)(pHddStaCtx->PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012126 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080012127 if (eHAL_STATUS_SUCCESS !=
12128 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -070012129 {
12130 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
12131 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -080012132 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012133 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +053012134 /*clear the entry in HDD cache 0--index-1 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012135 vos_mem_zero(pHddStaCtx->PMKIDCache[j].BSSID, VOS_MAC_ADDR_SIZE);
12136 vos_mem_zero(pHddStaCtx->PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
12137 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070012138
Agarwal Ashish3da95242014-05-21 14:57:17 +053012139 pHddStaCtx->PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -080012140 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012141}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012142
12143static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
12144{
12145 int ret;
12146
12147 vos_ssr_protect(__func__);
12148 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
12149 vos_ssr_unprotect(__func__);
12150
12151 return ret;
12152}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012153#endif
12154
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012155#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012156static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12157 struct net_device *dev,
12158 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012159{
12160 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12161 hdd_station_ctx_t *pHddStaCtx;
12162
12163 if (NULL == pAdapter)
12164 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012165 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012166 return -ENODEV;
12167 }
12168
12169 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12170
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012171 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12172 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
12173 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012174 // Added for debug on reception of Re-assoc Req.
12175 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
12176 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012177 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012178 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080012179 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012180 }
12181
12182#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080012183 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012184 ftie->ie_len);
12185#endif
12186
12187 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012188 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12189 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012190 ftie->ie_len);
12191 return 0;
12192}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012193
12194static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12195 struct net_device *dev,
12196 struct cfg80211_update_ft_ies_params *ftie)
12197{
12198 int ret;
12199
12200 vos_ssr_protect(__func__);
12201 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
12202 vos_ssr_unprotect(__func__);
12203
12204 return ret;
12205}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012206#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012207
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012208#ifdef FEATURE_WLAN_SCAN_PNO
12209
12210void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
12211 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
12212{
12213 int ret;
12214 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
12215 hdd_context_t *pHddCtx;
12216
Nirav Shah80830bf2013-12-31 16:35:12 +053012217 ENTER();
12218
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012219 if (NULL == pAdapter)
12220 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053012221 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012222 "%s: HDD adapter is Null", __func__);
12223 return ;
12224 }
12225
12226 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12227 if (NULL == pHddCtx)
12228 {
12229 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12230 "%s: HDD context is Null!!!", __func__);
12231 return ;
12232 }
12233
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012234 spin_lock(&pHddCtx->schedScan_lock);
12235 if (TRUE == pHddCtx->isWiphySuspended)
12236 {
12237 pHddCtx->isSchedScanUpdatePending = TRUE;
12238 spin_unlock(&pHddCtx->schedScan_lock);
12239 hddLog(VOS_TRACE_LEVEL_INFO,
12240 "%s: Update cfg80211 scan database after it resume", __func__);
12241 return ;
12242 }
12243 spin_unlock(&pHddCtx->schedScan_lock);
12244
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012245 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
12246
12247 if (0 > ret)
12248 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
12249
12250 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12252 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012253}
12254
12255/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012256 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012257 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012258 */
12259static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
12260{
12261 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12262 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012263 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012264 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12265 int status = 0;
12266 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12267
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012268 /* The current firmware design does not allow PNO during any
12269 * active sessions. Hence, determine the active sessions
12270 * and return a failure.
12271 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012272 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
12273 {
12274 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012275 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012276
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012277 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
12278 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
12279 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
12280 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
12281 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
12282 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012283 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012284 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012285 }
12286 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12287 pAdapterNode = pNext;
12288 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012289 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012290}
12291
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012292void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
12293{
12294 hdd_adapter_t *pAdapter = callbackContext;
12295 hdd_context_t *pHddCtx;
12296
12297 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
12298 {
12299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12300 FL("Invalid adapter or adapter has invalid magic"));
12301 return;
12302 }
12303
12304 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12305 if (0 != wlan_hdd_validate_context(pHddCtx))
12306 {
12307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12308 FL("HDD context is not valid"));
12309 return;
12310 }
12311
12312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12313 FL("PNO enable response status = %d"), status);
12314
12315 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
12316 complete(&pAdapter->pno_comp_var);
12317}
12318
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012319/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012320 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
12321 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012322 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012323static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012324 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12325{
12326 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12327 tpSirPNOScanReq pPnoRequest = NULL;
12328 hdd_context_t *pHddCtx;
12329 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053012330 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053012331 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
12332 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012333 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12334 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012335 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012336
12337 if (NULL == pAdapter)
12338 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012339 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012340 "%s: HDD adapter is Null", __func__);
12341 return -ENODEV;
12342 }
12343
12344 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012345 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012346
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012347 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012348 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012349 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12350 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012351 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012352 }
12353
12354 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12355 if (NULL == hHal)
12356 {
12357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12358 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012359 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012360 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012361
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012362 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053012363 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012364 {
12365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12366 "%s: aborting the existing scan is unsuccessfull", __func__);
12367 return -EBUSY;
12368 }
12369
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012370 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012371 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012372 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012373 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012374 return -EBUSY;
12375 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012376
c_hpothu37f21312014-04-09 21:49:54 +053012377 if (TRUE == pHddCtx->isPnoEnable)
12378 {
12379 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12380 FL("already PNO is enabled"));
12381 return -EBUSY;
12382 }
12383 pHddCtx->isPnoEnable = TRUE;
12384
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012385 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12386 if (NULL == pPnoRequest)
12387 {
12388 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12389 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053012390 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012391 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012392 }
12393
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053012394 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012395 pPnoRequest->enable = 1; /*Enable PNO */
12396 pPnoRequest->ucNetworksCount = request->n_match_sets;
12397
12398 if (( !pPnoRequest->ucNetworksCount ) ||
12399 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
12400 {
12401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012402 "%s: Network input is not correct %d Max Network supported is %d",
12403 __func__, pPnoRequest->ucNetworksCount,
12404 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012405 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012406 goto error;
12407 }
12408
12409 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
12410 {
12411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012412 "%s: Incorrect number of channels %d",
12413 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012414 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012415 goto error;
12416 }
12417
12418 /* Framework provides one set of channels(all)
12419 * common for all saved profile */
12420 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12421 channels_allowed, &num_channels_allowed))
12422 {
12423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12424 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012425 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012426 goto error;
12427 }
12428 /* Checking each channel against allowed channel list */
12429 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053012430 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012431 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012432 char chList [(request->n_channels*5)+1];
12433 int len;
12434 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012435 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012436 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012437 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012438 if (request->channels[i]->hw_value == channels_allowed[indx])
12439 {
12440 valid_ch[num_ch++] = request->channels[i]->hw_value;
12441 len += snprintf(chList+len, 5, "%d ",
12442 request->channels[i]->hw_value);
12443 break ;
12444 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012445 }
12446 }
Nirav Shah80830bf2013-12-31 16:35:12 +053012447 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
12448 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012449
12450 /* Filling per profile params */
12451 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
12452 {
12453 pPnoRequest->aNetworks[i].ssId.length =
12454 request->match_sets[i].ssid.ssid_len;
12455
12456 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
12457 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
12458 {
12459 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012460 "%s: SSID Len %d is not correct for network %d",
12461 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012462 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012463 goto error;
12464 }
12465
12466 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
12467 request->match_sets[i].ssid.ssid,
12468 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12470 "%s: SSID of network %d is %s ", __func__,
12471 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012472 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
12473 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
12474 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
12475
12476 /*Copying list of valid channel into request */
12477 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
12478 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
12479
12480 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
12481 }
12482
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053012483 for (i = 0; i < request->n_ssids; i++)
12484 {
12485 j = 0;
12486 while (j < pPnoRequest->ucNetworksCount)
12487 {
12488 if ((pPnoRequest->aNetworks[j].ssId.length ==
12489 request->ssids[i].ssid_len) &&
12490 (0 == memcmp(pPnoRequest->aNetworks[j].ssId.ssId,
12491 request->ssids[i].ssid,
12492 pPnoRequest->aNetworks[j].ssId.length)))
12493 {
12494 pPnoRequest->aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
12495 break;
12496 }
12497 j++;
12498 }
12499 }
12500 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12501 "Number of hidden networks being Configured = %d",
12502 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080012504 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012505 if ((0 < request->ie_len) && (NULL != request->ie))
12506 {
12507 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
12508 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
12509 pPnoRequest->us24GProbeTemplateLen);
12510
12511 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
12512 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
12513 pPnoRequest->us5GProbeTemplateLen);
12514 }
12515
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053012516 /* Driver gets only one time interval which is hardcoded in
12517 * supplicant for 10000ms. Taking power consumption into account 6 timers
12518 * will be used, Timervalue is increased exponentially i.e 10,20,40,
12519 * 80,160,320 secs. And number of scan cycle for each timer
12520 * is configurable through INI param gPNOScanTimerRepeatValue.
12521 * If it is set to 0 only one timer will be used and PNO scan cycle
12522 * will be repeated after each interval specified by supplicant
12523 * till PNO is disabled.
12524 */
12525 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
12526 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
12527 else
12528 pPnoRequest->scanTimers.ucScanTimersCount =
12529 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
12530
12531 tempInterval = (request->interval)/1000;
12532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12533 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
12534 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
12535 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
12536 {
12537 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
12538 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
12539 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
12540 tempInterval *= 2;
12541 }
12542 //Repeat last timer until pno disabled.
12543 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
12544
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053012545 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012546
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012547 INIT_COMPLETION(pAdapter->pno_comp_var);
12548 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
12549 pPnoRequest->callbackContext = pAdapter;
12550 pAdapter->pno_req_status = 0;
12551
Nirav Shah80830bf2013-12-31 16:35:12 +053012552 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12553 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
12554 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
12555 pPnoRequest->scanTimers.ucScanTimersCount);
12556
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012557 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
12558 pPnoRequest, pAdapter->sessionId,
12559 hdd_cfg80211_sched_scan_done_callback, pAdapter);
12560 if (eHAL_STATUS_SUCCESS != status)
12561 {
12562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012563 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012564 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012565 goto error;
12566 }
12567
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012568 ret = wait_for_completion_timeout(
12569 &pAdapter->pno_comp_var,
12570 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
12571 if (0 >= ret)
12572 {
12573 // Did not receive the response for PNO enable in time.
12574 // Assuming the PNO enable was success.
12575 // Returning error from here, because we timeout, results
12576 // in side effect of Wifi (Wifi Setting) not to work.
12577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12578 FL("Timed out waiting for PNO to be Enabled"));
12579 ret = 0;
12580 goto error;
12581 }
12582
c_hpothu3c986b22014-07-09 14:45:09 +053012583 vos_mem_free(pPnoRequest);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012584 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053012585 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012586
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012587error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12589 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012590 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053012591 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012592 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012593}
12594
12595/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012596 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
12597 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012598 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012599static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
12600 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12601{
12602 int ret;
12603
12604 vos_ssr_protect(__func__);
12605 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
12606 vos_ssr_unprotect(__func__);
12607
12608 return ret;
12609}
12610
12611/*
12612 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
12613 * Function to disable PNO
12614 */
12615static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012616 struct net_device *dev)
12617{
12618 eHalStatus status = eHAL_STATUS_FAILURE;
12619 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12620 hdd_context_t *pHddCtx;
12621 tHalHandle hHal;
12622 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012623 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012624
12625 ENTER();
12626
12627 if (NULL == pAdapter)
12628 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012630 "%s: HDD adapter is Null", __func__);
12631 return -ENODEV;
12632 }
12633
12634 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012635
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012636 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012637 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012639 "%s: HDD context is Null", __func__);
12640 return -ENODEV;
12641 }
12642
12643 /* The return 0 is intentional when isLogpInProgress and
12644 * isLoadUnloadInProgress. We did observe a crash due to a return of
12645 * failure in sched_scan_stop , especially for a case where the unload
12646 * of the happens at the same time. The function __cfg80211_stop_sched_scan
12647 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
12648 * success. If it returns a failure , then its next invocation due to the
12649 * clean up of the second interface will have the dev pointer corresponding
12650 * to the first one leading to a crash.
12651 */
12652 if (pHddCtx->isLogpInProgress)
12653 {
12654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12655 "%s: LOGP in Progress. Ignore!!!", __func__);
12656 return ret;
12657 }
12658
Mihir Shete18156292014-03-11 15:38:30 +053012659 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012660 {
12661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12662 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
12663 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012664 }
12665
12666 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12667 if (NULL == hHal)
12668 {
12669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12670 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012671 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012672 }
12673
12674 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12675 if (NULL == pPnoRequest)
12676 {
12677 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12678 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012679 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012680 }
12681
12682 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
12683 pPnoRequest->enable = 0; /* Disable PNO */
12684 pPnoRequest->ucNetworksCount = 0;
12685
12686 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
12687 pAdapter->sessionId,
12688 NULL, pAdapter);
12689 if (eHAL_STATUS_SUCCESS != status)
12690 {
12691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12692 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012693 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012694 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012695 }
c_hpothu37f21312014-04-09 21:49:54 +053012696 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012697
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012698error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012699 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012700 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012701 vos_mem_free(pPnoRequest);
12702
12703 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012704 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012705}
12706
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012707/*
12708 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
12709 * NL interface to disable PNO
12710 */
12711static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
12712 struct net_device *dev)
12713{
12714 int ret;
12715
12716 vos_ssr_protect(__func__);
12717 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
12718 vos_ssr_unprotect(__func__);
12719
12720 return ret;
12721}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012722#endif /*FEATURE_WLAN_SCAN_PNO*/
12723
12724
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012725#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012726#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012727static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
12728 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012729 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
12730#else
12731static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
12732 u8 *peer, u8 action_code, u8 dialog_token,
12733 u16 status_code, const u8 *buf, size_t len)
12734#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012735{
12736
12737 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12738 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012739 u8 peerMac[6];
12740 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012741 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080012742 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070012743 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012744#if !(TDLS_MGMT_VERSION2)
12745 u32 peer_capability = 0;
12746#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012747 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012748
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012749 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12750 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
12751 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012752 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012753 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012755 "Invalid arguments");
12756 return -EINVAL;
12757 }
12758
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012759 if (pHddCtx->isLogpInProgress)
12760 {
12761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12762 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012763 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012764 return -EBUSY;
12765 }
12766
Hoonki Lee27511902013-03-14 18:19:06 -070012767 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012768 {
Hoonki Lee27511902013-03-14 18:19:06 -070012769 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
12770 "%s: TDLS mode is disabled OR not enabled in FW."
12771 MAC_ADDRESS_STR " action %d declined.",
12772 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012773 return -ENOTSUPP;
12774 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012775
Hoonki Lee27511902013-03-14 18:19:06 -070012776 /* other than teardown frame, other mgmt frames are not sent if disabled */
12777 if (SIR_MAC_TDLS_TEARDOWN != action_code)
12778 {
12779 /* if tdls_mode is disabled to respond to peer's request */
12780 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
12781 {
12782 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
12783 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012784 " TDLS mode is disabled. action %d declined.",
12785 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070012786
12787 return -ENOTSUPP;
12788 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053012789
12790 if (vos_max_concurrent_connections_reached())
12791 {
12792 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12793 return -EINVAL;
12794 }
Hoonki Lee27511902013-03-14 18:19:06 -070012795 }
12796
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012797 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
12798 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012799 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012800 {
12801 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012802 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012803 " TDLS setup is ongoing. action %d declined.",
12804 __func__, MAC_ADDR_ARRAY(peer), action_code);
12805 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012806 }
12807 }
12808
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012809 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
12810 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080012811 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012812 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12813 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080012814 {
12815 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
12816 we return error code at 'add_station()'. Hence we have this
12817 check again in addtion to add_station().
12818 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012819 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080012820 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12822 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012823 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
12824 __func__, MAC_ADDR_ARRAY(peer), action_code,
12825 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012826 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080012827 }
12828 else
12829 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012830 /* maximum reached. tweak to send error code to peer and return
12831 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080012832 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12834 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012835 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
12836 __func__, MAC_ADDR_ARRAY(peer), status_code,
12837 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012838 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012839 /* fall through to send setup resp with failure status
12840 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080012841 }
12842 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012843 else
12844 {
12845 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012846 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012847 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012848 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012850 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
12851 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012852 return -EPERM;
12853 }
12854 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012855 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012856 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012857
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012858#ifdef WLAN_FEATURE_TDLS_DEBUG
12859 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053012860 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012861 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
12862 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012863#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012864
Hoonki Leea34dd892013-02-05 22:56:02 -080012865 /*Except teardown responder will not be used so just make 0*/
12866 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012867 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080012868 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012869
12870 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012871 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012872
12873 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
12874 responder = pTdlsPeer->is_responder;
12875 else
Hoonki Leea34dd892013-02-05 22:56:02 -080012876 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053012878 "%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 -070012879 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
12880 dialog_token, status_code, len);
12881 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080012882 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012883 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012884
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012885 /* For explicit trigger of DIS_REQ come out of BMPS for
12886 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070012887 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012888 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
12889 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070012890 {
12891 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12892 {
12893 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012894 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070012895 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12896 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012897 if (SIR_MAC_TDLS_DIS_REQ != action_code)
12898 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070012899 }
12900
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012901 /* make sure doesn't call send_mgmt() while it is pending */
12902 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
12903 {
12904 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012905 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012906 __func__, MAC_ADDR_ARRAY(peer), action_code);
12907 return -EBUSY;
12908 }
12909
12910 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012911 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
12912
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012913 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053012914 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012915
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012916 if (VOS_STATUS_SUCCESS != status)
12917 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12919 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012920 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -070012921 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012922 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012923 }
12924
Hoonki Leed37cbb32013-04-20 00:31:14 -070012925 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
12926 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
12927
12928 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012929 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070012930 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012931 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070012932 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012933 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080012934
12935 if (pHddCtx->isLogpInProgress)
12936 {
12937 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12938 "%s: LOGP in Progress. Ignore!!!", __func__);
12939 return -EAGAIN;
12940 }
12941
Hoonki Leed37cbb32013-04-20 00:31:14 -070012942 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012943 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012944 }
12945
Gopichand Nakkala05922802013-03-14 12:23:19 -070012946 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070012947 {
12948 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012949 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070012950 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012951
Hoonki Leea34dd892013-02-05 22:56:02 -080012952 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
12953 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012954 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080012955 }
12956 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
12957 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012958 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080012959 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012960
12961 return 0;
12962}
12963
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012964static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012965 u8 *peer, enum nl80211_tdls_operation oper)
12966{
12967 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12968 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012969 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012970 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012971
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012972 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12973 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
12974 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012975 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012976 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012977 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070012978 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012979 return -EINVAL;
12980 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012981
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012982 status = wlan_hdd_validate_context(pHddCtx);
12983
12984 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012985 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012986 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12987 "%s: HDD context is not valid", __func__);
12988 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012989 }
12990
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012991
12992 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012993 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012994 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012995 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070012996 "TDLS Disabled in INI OR not enabled in FW. "
12997 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012998 return -ENOTSUPP;
12999 }
13000
13001 switch (oper) {
13002 case NL80211_TDLS_ENABLE_LINK:
13003 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013004 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013005 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013006 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013007
Sunil Dutt41de4e22013-11-14 18:09:02 +053013008 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13009
13010 if ( NULL == pTdlsPeer ) {
13011 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13012 " (oper %d) not exsting. ignored",
13013 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13014 return -EINVAL;
13015 }
13016
13017 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13018 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13019 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13020 "NL80211_TDLS_ENABLE_LINK");
13021
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070013022 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
13023 {
13024 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
13025 MAC_ADDRESS_STR " failed",
13026 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
13027 return -EINVAL;
13028 }
13029
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013030 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013031 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013032 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053013033
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013034 if (0 != wlan_hdd_tdls_get_link_establish_params(
13035 pAdapter, peer,&tdlsLinkEstablishParams)) {
13036 return -EINVAL;
13037 }
13038 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013039
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013040 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
13041 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
13042 /* Send TDLS peer UAPSD capabilities to the firmware and
13043 * register with the TL on after the response for this operation
13044 * is received .
13045 */
13046 ret = wait_for_completion_interruptible_timeout(
13047 &pAdapter->tdls_link_establish_req_comp,
13048 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
13049 if (ret <= 0)
13050 {
13051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13052 "%s: Link Establish Request Faled Status %ld",
13053 __func__, ret);
13054 return -EINVAL;
13055 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013056 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013057 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +053013058 /* Mark TDLS client Authenticated .*/
13059 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
13060 pTdlsPeer->staId,
13061 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013062 if (VOS_STATUS_SUCCESS == status)
13063 {
Hoonki Lee14621352013-04-16 17:51:19 -070013064 if (pTdlsPeer->is_responder == 0)
13065 {
13066 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
13067
13068 wlan_hdd_tdls_timer_restart(pAdapter,
13069 &pTdlsPeer->initiatorWaitTimeoutTimer,
13070 WAIT_TIME_TDLS_INITIATOR);
13071 /* suspend initiator TX until it receives direct packet from the
13072 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
13073 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13074 &staId, NULL);
13075 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013076 wlan_hdd_tdls_increment_peer_count(pAdapter);
13077 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013078 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013079
13080 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013081 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
13082 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013083 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013084 int ac;
13085 uint8 ucAc[4] = { WLANTL_AC_VO,
13086 WLANTL_AC_VI,
13087 WLANTL_AC_BK,
13088 WLANTL_AC_BE };
13089 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
13090 for(ac=0; ac < 4; ac++)
13091 {
13092 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13093 pTdlsPeer->staId, ucAc[ac],
13094 tlTid[ac], tlTid[ac], 0, 0,
13095 WLANTL_BI_DIR );
13096 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013097 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013098 }
13099
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013100 }
13101 break;
13102 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080013103 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053013104 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13105
13106 if ( NULL == pTdlsPeer ) {
13107 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13108 " (oper %d) not exsting. ignored",
13109 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13110 return -EINVAL;
13111 }
13112
13113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13114 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13115 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13116 "NL80211_TDLS_DISABLE_LINK");
13117
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013118 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080013119 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013120 long status;
13121
13122 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
13123
Lee Hoonkic1262f22013-01-24 21:59:00 -080013124 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
13125 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013126
13127 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
13128 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
13129 if (status <= 0)
13130 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013131 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013132 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13133 "%s: Del station failed status %ld",
13134 __func__, status);
13135 return -EPERM;
13136 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013137 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -080013138 }
13139 else
13140 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13142 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080013143 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013144 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013145 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013146 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013147 {
13148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13149 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
13150 __func__, MAC_ADDR_ARRAY(peer));
13151
13152 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13153 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13154
13155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13156 " %s TDLS External control and Implicit Trigger not enabled ",
13157 __func__);
13158 return -ENOTSUPP;
13159 }
13160
Sunil Dutt41de4e22013-11-14 18:09:02 +053013161
13162 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13163
13164 if ( NULL == pTdlsPeer ) {
13165 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
13166 " peer not exsting",
13167 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013168 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013169 }
13170 else {
13171 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
13172 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
13173 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013174
13175 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
13176 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013177 break;
13178 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013179 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013180 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013181 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13183 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
13184 __func__, MAC_ADDR_ARRAY(peer));
13185
13186 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13187 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13188
13189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13190 " %s TDLS External control and Implicit Trigger not enabled ",
13191 __func__);
13192 return -ENOTSUPP;
13193 }
13194
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013195 /* To cater the requirement of establishing the TDLS link
13196 * irrespective of the data traffic , get an entry of TDLS peer.
13197 */
13198 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
13199 if (pTdlsPeer == NULL) {
13200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13201 "%s: peer " MAC_ADDRESS_STR " not existing",
13202 __func__, MAC_ADDR_ARRAY(peer));
13203 return -EINVAL;
13204 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013205
13206 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
13207
13208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13209 " %s TDLS Add Force Peer Failed",
13210 __func__);
13211 return -EINVAL;
13212 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013213 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013214 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013215 case NL80211_TDLS_DISCOVERY_REQ:
13216 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13218 "%s: We don't support in-driver setup/teardown/discovery "
13219 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013220 return -ENOTSUPP;
13221 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13223 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013224 return -ENOTSUPP;
13225 }
13226 return 0;
13227}
Chilam NG571c65a2013-01-19 12:27:36 +053013228
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013229static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
13230 u8 *peer, enum nl80211_tdls_operation oper)
13231{
13232 int ret;
13233
13234 vos_ssr_protect(__func__);
13235 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
13236 vos_ssr_unprotect(__func__);
13237
13238 return ret;
13239}
13240
Chilam NG571c65a2013-01-19 12:27:36 +053013241int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
13242 struct net_device *dev, u8 *peer)
13243{
Arif Hussaina7c8e412013-11-20 11:06:42 -080013244 hddLog(VOS_TRACE_LEVEL_INFO,
13245 "tdls send discover req: "MAC_ADDRESS_STR,
13246 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053013247
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013248#if TDLS_MGMT_VERSION2
13249 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13250 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
13251#else
Chilam NG571c65a2013-01-19 12:27:36 +053013252 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13253 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013254#endif
Chilam NG571c65a2013-01-19 12:27:36 +053013255}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013256#endif
13257
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013258#ifdef WLAN_FEATURE_GTK_OFFLOAD
13259/*
13260 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
13261 * Callback rountine called upon receiving response for
13262 * get offload info
13263 */
13264void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
13265 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
13266{
13267
13268 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013269 tANI_U8 tempReplayCounter[8];
13270 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013271
13272 ENTER();
13273
13274 if (NULL == pAdapter)
13275 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013277 "%s: HDD adapter is Null", __func__);
13278 return ;
13279 }
13280
13281 if (NULL == pGtkOffloadGetInfoRsp)
13282 {
13283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13284 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
13285 return ;
13286 }
13287
13288 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
13289 {
13290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13291 "%s: wlan Failed to get replay counter value",
13292 __func__);
13293 return ;
13294 }
13295
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013296 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13297 /* Update replay counter */
13298 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
13299 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13300
13301 {
13302 /* changing from little to big endian since supplicant
13303 * works on big endian format
13304 */
13305 int i;
13306 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13307
13308 for (i = 0; i < 8; i++)
13309 {
13310 tempReplayCounter[7-i] = (tANI_U8)p[i];
13311 }
13312 }
13313
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013314 /* Update replay counter to NL */
13315 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013316 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013317}
13318
13319/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013320 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013321 * This function is used to offload GTK rekeying job to the firmware.
13322 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013323int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013324 struct cfg80211_gtk_rekey_data *data)
13325{
13326 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13327 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13328 hdd_station_ctx_t *pHddStaCtx;
13329 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013330 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013331 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013332 eHalStatus status = eHAL_STATUS_FAILURE;
13333
13334 ENTER();
13335
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013336
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013337 if (NULL == pAdapter)
13338 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013340 "%s: HDD adapter is Null", __func__);
13341 return -ENODEV;
13342 }
13343
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013344 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13345 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
13346 pAdapter->sessionId, pAdapter->device_mode));
13347
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013348 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013349
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013350 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013351 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13353 "%s: HDD context is not valid", __func__);
13354 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013355 }
13356
13357 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13358 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13359 if (NULL == hHal)
13360 {
13361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13362 "%s: HAL context is Null!!!", __func__);
13363 return -EAGAIN;
13364 }
13365
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013366 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
13367 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
13368 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
13369 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013370 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013371 {
13372 /* changing from big to little endian since driver
13373 * works on little endian format
13374 */
13375 tANI_U8 *p =
13376 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
13377 int i;
13378
13379 for (i = 0; i < 8; i++)
13380 {
13381 p[7-i] = data->replay_ctr[i];
13382 }
13383 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013384
13385 if (TRUE == pHddCtx->hdd_wlan_suspended)
13386 {
13387 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013388 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
13389 sizeof (tSirGtkOffloadParams));
13390 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013391 pAdapter->sessionId);
13392
13393 if (eHAL_STATUS_SUCCESS != status)
13394 {
13395 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13396 "%s: sme_SetGTKOffload failed, returned %d",
13397 __func__, status);
13398 return status;
13399 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13401 "%s: sme_SetGTKOffload successfull", __func__);
13402 }
13403 else
13404 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13406 "%s: wlan not suspended GTKOffload request is stored",
13407 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013408 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013409
13410 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013411}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013412
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013413int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
13414 struct cfg80211_gtk_rekey_data *data)
13415{
13416 int ret;
13417
13418 vos_ssr_protect(__func__);
13419 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
13420 vos_ssr_unprotect(__func__);
13421
13422 return ret;
13423}
13424#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013425/*
13426 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
13427 * This function is used to set access control policy
13428 */
13429static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
13430 struct net_device *dev, const struct cfg80211_acl_data *params)
13431{
13432 int i;
13433 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13434 hdd_hostapd_state_t *pHostapdState;
13435 tsap_Config_t *pConfig;
13436 v_CONTEXT_t pVosContext = NULL;
13437 hdd_context_t *pHddCtx;
13438 int status;
13439
13440 ENTER();
13441
13442 if (NULL == pAdapter)
13443 {
13444 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13445 "%s: HDD adapter is Null", __func__);
13446 return -ENODEV;
13447 }
13448
13449 if (NULL == params)
13450 {
13451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13452 "%s: params is Null", __func__);
13453 return -EINVAL;
13454 }
13455
13456 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13457 status = wlan_hdd_validate_context(pHddCtx);
13458
13459 if (0 != status)
13460 {
13461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13462 "%s: HDD context is not valid", __func__);
13463 return status;
13464 }
13465
13466 pVosContext = pHddCtx->pvosContext;
13467 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13468
13469 if (NULL == pHostapdState)
13470 {
13471 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13472 "%s: pHostapdState is Null", __func__);
13473 return -EINVAL;
13474 }
13475
13476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
13477 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
13478
13479 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
13480 {
13481 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
13482
13483 /* default value */
13484 pConfig->num_accept_mac = 0;
13485 pConfig->num_deny_mac = 0;
13486
13487 /**
13488 * access control policy
13489 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
13490 * listed in hostapd.deny file.
13491 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
13492 * listed in hostapd.accept file.
13493 */
13494 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
13495 {
13496 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
13497 }
13498 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
13499 {
13500 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
13501 }
13502 else
13503 {
13504 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13505 "%s:Acl Policy : %d is not supported",
13506 __func__, params->acl_policy);
13507 return -ENOTSUPP;
13508 }
13509
13510 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
13511 {
13512 pConfig->num_accept_mac = params->n_acl_entries;
13513 for (i = 0; i < params->n_acl_entries; i++)
13514 {
13515 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13516 "** Add ACL MAC entry %i in WhiletList :"
13517 MAC_ADDRESS_STR, i,
13518 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
13519
13520 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
13521 sizeof(qcmacaddr));
13522 }
13523 }
13524 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
13525 {
13526 pConfig->num_deny_mac = params->n_acl_entries;
13527 for (i = 0; i < params->n_acl_entries; i++)
13528 {
13529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13530 "** Add ACL MAC entry %i in BlackList :"
13531 MAC_ADDRESS_STR, i,
13532 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
13533
13534 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
13535 sizeof(qcmacaddr));
13536 }
13537 }
13538
13539 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
13540 {
13541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13542 "%s: SAP Set Mac Acl fail", __func__);
13543 return -EINVAL;
13544 }
13545 }
13546 else
13547 {
13548 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013549 "%s: Invalid device_mode = %s (%d)",
13550 __func__, hdd_device_modetoString(pAdapter->device_mode),
13551 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013552 return -EINVAL;
13553 }
13554
13555 return 0;
13556}
13557
Leo Chang9056f462013-08-01 19:21:11 -070013558#ifdef WLAN_NL80211_TESTMODE
13559#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070013560void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070013561(
13562 void *pAdapter,
13563 void *indCont
13564)
13565{
Leo Changd9df8aa2013-09-26 13:32:26 -070013566 tSirLPHBInd *lphbInd;
13567 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053013568 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070013569
13570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070013571 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070013572
c_hpothu73f35e62014-04-18 13:40:08 +053013573 if (pAdapter == NULL)
13574 {
13575 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13576 "%s: pAdapter is NULL\n",__func__);
13577 return;
13578 }
13579
Leo Chang9056f462013-08-01 19:21:11 -070013580 if (NULL == indCont)
13581 {
13582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070013583 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070013584 return;
13585 }
13586
c_hpothu73f35e62014-04-18 13:40:08 +053013587 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070013588 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070013589 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053013590 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070013591 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070013592 GFP_ATOMIC);
13593 if (!skb)
13594 {
13595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13596 "LPHB timeout, NL buffer alloc fail");
13597 return;
13598 }
13599
Leo Changac3ba772013-10-07 09:47:04 -070013600 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070013601 {
13602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13603 "WLAN_HDD_TM_ATTR_CMD put fail");
13604 goto nla_put_failure;
13605 }
Leo Changac3ba772013-10-07 09:47:04 -070013606 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070013607 {
13608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13609 "WLAN_HDD_TM_ATTR_TYPE put fail");
13610 goto nla_put_failure;
13611 }
Leo Changac3ba772013-10-07 09:47:04 -070013612 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070013613 sizeof(tSirLPHBInd), lphbInd))
13614 {
13615 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13616 "WLAN_HDD_TM_ATTR_DATA put fail");
13617 goto nla_put_failure;
13618 }
Leo Chang9056f462013-08-01 19:21:11 -070013619 cfg80211_testmode_event(skb, GFP_ATOMIC);
13620 return;
13621
13622nla_put_failure:
13623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13624 "NLA Put fail");
13625 kfree_skb(skb);
13626
13627 return;
13628}
13629#endif /* FEATURE_WLAN_LPHB */
13630
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013631static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070013632{
13633 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
13634 int err = 0;
13635#ifdef FEATURE_WLAN_LPHB
13636 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070013637 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -070013638#endif /* FEATURE_WLAN_LPHB */
13639
13640 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
13641 if (err)
13642 {
13643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13644 "%s Testmode INV ATTR", __func__);
13645 return err;
13646 }
13647
13648 if (!tb[WLAN_HDD_TM_ATTR_CMD])
13649 {
13650 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13651 "%s Testmode INV CMD", __func__);
13652 return -EINVAL;
13653 }
13654
13655 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
13656 {
13657#ifdef FEATURE_WLAN_LPHB
13658 /* Low Power Heartbeat configuration request */
13659 case WLAN_HDD_TM_CMD_WLAN_HB:
13660 {
13661 int buf_len;
13662 void *buf;
13663 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080013664 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070013665
13666 if (!tb[WLAN_HDD_TM_ATTR_DATA])
13667 {
13668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13669 "%s Testmode INV DATA", __func__);
13670 return -EINVAL;
13671 }
13672
13673 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
13674 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080013675
13676 hb_params_temp =(tSirLPHBReq *)buf;
13677 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
13678 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
13679 return -EINVAL;
13680
Leo Chang9056f462013-08-01 19:21:11 -070013681 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
13682 if (NULL == hb_params)
13683 {
13684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13685 "%s Request Buffer Alloc Fail", __func__);
13686 return -EINVAL;
13687 }
13688
13689 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070013690 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
13691 hb_params,
13692 wlan_hdd_cfg80211_lphb_ind_handler);
13693 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070013694 {
Leo Changd9df8aa2013-09-26 13:32:26 -070013695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13696 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070013697 vos_mem_free(hb_params);
13698 }
Leo Chang9056f462013-08-01 19:21:11 -070013699 return 0;
13700 }
13701#endif /* FEATURE_WLAN_LPHB */
13702 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013703 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13704 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070013705 return -EOPNOTSUPP;
13706 }
13707
13708 return err;
13709}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013710
13711static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
13712{
13713 int ret;
13714
13715 vos_ssr_protect(__func__);
13716 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
13717 vos_ssr_unprotect(__func__);
13718
13719 return ret;
13720}
Leo Chang9056f462013-08-01 19:21:11 -070013721#endif /* CONFIG_NL80211_TESTMODE */
13722
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013723static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013724 struct net_device *dev,
13725 int idx, struct survey_info *survey)
13726{
13727 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13728 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053013729 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013730 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053013731 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013732 v_S7_t snr,rssi;
13733 int status, i, j, filled = 0;
13734
13735 ENTER();
13736
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013737 if (NULL == pAdapter)
13738 {
13739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13740 "%s: HDD adapter is Null", __func__);
13741 return -ENODEV;
13742 }
13743
13744 if (NULL == wiphy)
13745 {
13746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13747 "%s: wiphy is Null", __func__);
13748 return -ENODEV;
13749 }
13750
13751 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13752 status = wlan_hdd_validate_context(pHddCtx);
13753
13754 if (0 != status)
13755 {
13756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13757 "%s: HDD context is not valid", __func__);
13758 return status;
13759 }
13760
Mihir Sheted9072e02013-08-21 17:02:29 +053013761 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13762
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013763 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053013764 0 != pAdapter->survey_idx ||
13765 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013766 {
13767 /* The survey dump ops when implemented completely is expected to
13768 * return a survey of all channels and the ops is called by the
13769 * kernel with incremental values of the argument 'idx' till it
13770 * returns -ENONET. But we can only support the survey for the
13771 * operating channel for now. survey_idx is used to track
13772 * that the ops is called only once and then return -ENONET for
13773 * the next iteration
13774 */
13775 pAdapter->survey_idx = 0;
13776 return -ENONET;
13777 }
13778
13779 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13780
13781 wlan_hdd_get_snr(pAdapter, &snr);
13782 wlan_hdd_get_rssi(pAdapter, &rssi);
13783
13784 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
13785 hdd_wlan_get_freq(channel, &freq);
13786
13787
13788 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
13789 {
13790 if (NULL == wiphy->bands[i])
13791 {
13792 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
13793 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
13794 continue;
13795 }
13796
13797 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
13798 {
13799 struct ieee80211_supported_band *band = wiphy->bands[i];
13800
13801 if (band->channels[j].center_freq == (v_U16_t)freq)
13802 {
13803 survey->channel = &band->channels[j];
13804 /* The Rx BDs contain SNR values in dB for the received frames
13805 * while the supplicant expects noise. So we calculate and
13806 * return the value of noise (dBm)
13807 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
13808 */
13809 survey->noise = rssi - snr;
13810 survey->filled = SURVEY_INFO_NOISE_DBM;
13811 filled = 1;
13812 }
13813 }
13814 }
13815
13816 if (filled)
13817 pAdapter->survey_idx = 1;
13818 else
13819 {
13820 pAdapter->survey_idx = 0;
13821 return -ENONET;
13822 }
13823
13824 return 0;
13825}
13826
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013827static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
13828 struct net_device *dev,
13829 int idx, struct survey_info *survey)
13830{
13831 int ret;
13832
13833 vos_ssr_protect(__func__);
13834 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
13835 vos_ssr_unprotect(__func__);
13836
13837 return ret;
13838}
13839
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013840/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013841 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013842 * this is called when cfg80211 driver resume
13843 * driver updates latest sched_scan scan result(if any) to cfg80211 database
13844 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013845int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013846{
13847 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13848 hdd_adapter_t *pAdapter;
13849 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13850 VOS_STATUS status = VOS_STATUS_SUCCESS;
13851
13852 ENTER();
13853
13854 if ( NULL == pHddCtx )
13855 {
13856 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13857 "%s: HddCtx validation failed", __func__);
13858 return 0;
13859 }
13860
13861 if (pHddCtx->isLogpInProgress)
13862 {
13863 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13864 "%s: LOGP in Progress. Ignore!!!", __func__);
13865 return 0;
13866 }
13867
Mihir Shete18156292014-03-11 15:38:30 +053013868 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013869 {
13870 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13871 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13872 return 0;
13873 }
13874
13875 spin_lock(&pHddCtx->schedScan_lock);
13876 pHddCtx->isWiphySuspended = FALSE;
13877 if (TRUE != pHddCtx->isSchedScanUpdatePending)
13878 {
13879 spin_unlock(&pHddCtx->schedScan_lock);
13880 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13881 "%s: Return resume is not due to PNO indication", __func__);
13882 return 0;
13883 }
13884 // Reset flag to avoid updatating cfg80211 data old results again
13885 pHddCtx->isSchedScanUpdatePending = FALSE;
13886 spin_unlock(&pHddCtx->schedScan_lock);
13887
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013888
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013889 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13890
13891 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13892 {
13893 pAdapter = pAdapterNode->pAdapter;
13894 if ( (NULL != pAdapter) &&
13895 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
13896 {
13897 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013898 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13900 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013901 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013902 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013903 {
13904 /* Acquire wakelock to handle the case where APP's tries to
13905 * suspend immediately after updating the scan results. Whis
13906 * results in app's is in suspended state and not able to
13907 * process the connect request to AP
13908 */
13909 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013910 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013911 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013912
13913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13914 "%s : cfg80211 scan result database updated", __func__);
13915
13916 return 0;
13917
13918 }
13919 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13920 pAdapterNode = pNext;
13921 }
13922
13923 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13924 "%s: Failed to find Adapter", __func__);
13925 return 0;
13926}
13927
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013928int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
13929{
13930 int ret;
13931
13932 vos_ssr_protect(__func__);
13933 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
13934 vos_ssr_unprotect(__func__);
13935
13936 return ret;
13937}
13938
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013939/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013940 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013941 * this is called when cfg80211 driver suspends
13942 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013943int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013944 struct cfg80211_wowlan *wow)
13945{
13946 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13947
13948 ENTER();
13949 if (NULL == pHddCtx)
13950 {
13951 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13952 "%s: HddCtx validation failed", __func__);
13953 return 0;
13954 }
13955
13956 pHddCtx->isWiphySuspended = TRUE;
13957
13958 EXIT();
13959
13960 return 0;
13961}
13962
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013963int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
13964 struct cfg80211_wowlan *wow)
13965{
13966 int ret;
13967
13968 vos_ssr_protect(__func__);
13969 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
13970 vos_ssr_unprotect(__func__);
13971
13972 return ret;
13973}
Jeff Johnson295189b2012-06-20 16:38:30 -070013974/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013975static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070013976{
13977 .add_virtual_intf = wlan_hdd_add_virtual_intf,
13978 .del_virtual_intf = wlan_hdd_del_virtual_intf,
13979 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
13980 .change_station = wlan_hdd_change_station,
13981#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
13982 .add_beacon = wlan_hdd_cfg80211_add_beacon,
13983 .del_beacon = wlan_hdd_cfg80211_del_beacon,
13984 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013985#else
13986 .start_ap = wlan_hdd_cfg80211_start_ap,
13987 .change_beacon = wlan_hdd_cfg80211_change_beacon,
13988 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070013989#endif
13990 .change_bss = wlan_hdd_cfg80211_change_bss,
13991 .add_key = wlan_hdd_cfg80211_add_key,
13992 .get_key = wlan_hdd_cfg80211_get_key,
13993 .del_key = wlan_hdd_cfg80211_del_key,
13994 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013995#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070013996 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013997#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013998 .scan = wlan_hdd_cfg80211_scan,
13999 .connect = wlan_hdd_cfg80211_connect,
14000 .disconnect = wlan_hdd_cfg80211_disconnect,
14001 .join_ibss = wlan_hdd_cfg80211_join_ibss,
14002 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
14003 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
14004 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
14005 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070014006 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
14007 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053014008 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070014009#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14010 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
14011 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
14012 .set_txq_params = wlan_hdd_set_txq_params,
14013#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014014 .get_station = wlan_hdd_cfg80211_get_station,
14015 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
14016 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014017 .add_station = wlan_hdd_cfg80211_add_station,
14018#ifdef FEATURE_WLAN_LFR
14019 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
14020 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
14021 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
14022#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014023#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
14024 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
14025#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014026#ifdef FEATURE_WLAN_TDLS
14027 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
14028 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
14029#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014030#ifdef WLAN_FEATURE_GTK_OFFLOAD
14031 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
14032#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014033#ifdef FEATURE_WLAN_SCAN_PNO
14034 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
14035 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
14036#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014037 .resume = wlan_hdd_cfg80211_resume_wlan,
14038 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014039 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070014040#ifdef WLAN_NL80211_TESTMODE
14041 .testmode_cmd = wlan_hdd_cfg80211_testmode,
14042#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014043 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070014044};
14045