blob: 39f70e8dead786fd74431666e050ab513853b330 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#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"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098
99#define g_mode_rates_size (12)
100#define a_mode_rates_size (8)
101#define FREQ_BASE_80211G (2407)
102#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700103#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530104#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700105#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800106 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700107
108#define HDD2GHZCHAN(freq, chan, flag) { \
109 .band = IEEE80211_BAND_2GHZ, \
110 .center_freq = (freq), \
111 .hw_value = (chan),\
112 .flags = (flag), \
113 .max_antenna_gain = 0 ,\
114 .max_power = 30, \
115}
116
117#define HDD5GHZCHAN(freq, chan, flag) { \
118 .band = IEEE80211_BAND_5GHZ, \
119 .center_freq = (freq), \
120 .hw_value = (chan),\
121 .flags = (flag), \
122 .max_antenna_gain = 0 ,\
123 .max_power = 30, \
124}
125
126#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
127{\
128 .bitrate = rate, \
129 .hw_value = rate_id, \
130 .flags = flag, \
131}
132
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530133#ifdef WLAN_FEATURE_VOWIFI_11R
134#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
135#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
136#endif
137
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530138#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530139#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530140
Sunil Duttc69bccb2014-05-26 21:30:20 +0530141#ifdef WLAN_FEATURE_LINK_LAYER_STATS
142/*
143 * Used to allocate the size of 4096 for the link layer stats.
144 * The size of 4096 is considered assuming that all data per
145 * respective event fit with in the limit.Please take a call
146 * on the limit based on the data requirements on link layer
147 * statistics.
148 */
149#define LL_STATS_EVENT_BUF_SIZE 4096
150#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530151#ifdef WLAN_FEATURE_EXTSCAN
152/*
153 * Used to allocate the size of 4096 for the EXTScan NL data.
154 * The size of 4096 is considered assuming that all data per
155 * respective event fit with in the limit.Please take a call
156 * on the limit based on the data requirements.
157 */
158
159#define EXTSCAN_EVENT_BUF_SIZE 4096
160#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
161#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530162
Atul Mittal115287b2014-07-08 13:26:33 +0530163/*EXT TDLS*/
164/*
165 * Used to allocate the size of 4096 for the TDLS.
166 * The size of 4096 is considered assuming that all data per
167 * respective event fit with in the limit.Please take a call
168 * on the limit based on the data requirements on link layer
169 * statistics.
170 */
171#define EXTTDLS_EVENT_BUF_SIZE 4096
172
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530173static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700174{
175 WLAN_CIPHER_SUITE_WEP40,
176 WLAN_CIPHER_SUITE_WEP104,
177 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800178#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700179#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
180 WLAN_CIPHER_SUITE_KRK,
181 WLAN_CIPHER_SUITE_CCMP,
182#else
183 WLAN_CIPHER_SUITE_CCMP,
184#endif
185#ifdef FEATURE_WLAN_WAPI
186 WLAN_CIPHER_SUITE_SMS4,
187#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700188#ifdef WLAN_FEATURE_11W
189 WLAN_CIPHER_SUITE_AES_CMAC,
190#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700191};
192
193static inline int is_broadcast_ether_addr(const u8 *addr)
194{
195 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
196 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
197}
198
199static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530200{
Jeff Johnson295189b2012-06-20 16:38:30 -0700201 HDD2GHZCHAN(2412, 1, 0) ,
202 HDD2GHZCHAN(2417, 2, 0) ,
203 HDD2GHZCHAN(2422, 3, 0) ,
204 HDD2GHZCHAN(2427, 4, 0) ,
205 HDD2GHZCHAN(2432, 5, 0) ,
206 HDD2GHZCHAN(2437, 6, 0) ,
207 HDD2GHZCHAN(2442, 7, 0) ,
208 HDD2GHZCHAN(2447, 8, 0) ,
209 HDD2GHZCHAN(2452, 9, 0) ,
210 HDD2GHZCHAN(2457, 10, 0) ,
211 HDD2GHZCHAN(2462, 11, 0) ,
212 HDD2GHZCHAN(2467, 12, 0) ,
213 HDD2GHZCHAN(2472, 13, 0) ,
214 HDD2GHZCHAN(2484, 14, 0) ,
215};
216
Jeff Johnson295189b2012-06-20 16:38:30 -0700217static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
218{
219 HDD2GHZCHAN(2412, 1, 0) ,
220 HDD2GHZCHAN(2437, 6, 0) ,
221 HDD2GHZCHAN(2462, 11, 0) ,
222};
Jeff Johnson295189b2012-06-20 16:38:30 -0700223
224static struct ieee80211_channel hdd_channels_5_GHZ[] =
225{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700226 HDD5GHZCHAN(4920, 240, 0) ,
227 HDD5GHZCHAN(4940, 244, 0) ,
228 HDD5GHZCHAN(4960, 248, 0) ,
229 HDD5GHZCHAN(4980, 252, 0) ,
230 HDD5GHZCHAN(5040, 208, 0) ,
231 HDD5GHZCHAN(5060, 212, 0) ,
232 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700233 HDD5GHZCHAN(5180, 36, 0) ,
234 HDD5GHZCHAN(5200, 40, 0) ,
235 HDD5GHZCHAN(5220, 44, 0) ,
236 HDD5GHZCHAN(5240, 48, 0) ,
237 HDD5GHZCHAN(5260, 52, 0) ,
238 HDD5GHZCHAN(5280, 56, 0) ,
239 HDD5GHZCHAN(5300, 60, 0) ,
240 HDD5GHZCHAN(5320, 64, 0) ,
241 HDD5GHZCHAN(5500,100, 0) ,
242 HDD5GHZCHAN(5520,104, 0) ,
243 HDD5GHZCHAN(5540,108, 0) ,
244 HDD5GHZCHAN(5560,112, 0) ,
245 HDD5GHZCHAN(5580,116, 0) ,
246 HDD5GHZCHAN(5600,120, 0) ,
247 HDD5GHZCHAN(5620,124, 0) ,
248 HDD5GHZCHAN(5640,128, 0) ,
249 HDD5GHZCHAN(5660,132, 0) ,
250 HDD5GHZCHAN(5680,136, 0) ,
251 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800252#ifdef FEATURE_WLAN_CH144
253 HDD5GHZCHAN(5720,144, 0) ,
254#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700255 HDD5GHZCHAN(5745,149, 0) ,
256 HDD5GHZCHAN(5765,153, 0) ,
257 HDD5GHZCHAN(5785,157, 0) ,
258 HDD5GHZCHAN(5805,161, 0) ,
259 HDD5GHZCHAN(5825,165, 0) ,
260};
261
262static struct ieee80211_rate g_mode_rates[] =
263{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530264 HDD_G_MODE_RATETAB(10, 0x1, 0),
265 HDD_G_MODE_RATETAB(20, 0x2, 0),
266 HDD_G_MODE_RATETAB(55, 0x4, 0),
267 HDD_G_MODE_RATETAB(110, 0x8, 0),
268 HDD_G_MODE_RATETAB(60, 0x10, 0),
269 HDD_G_MODE_RATETAB(90, 0x20, 0),
270 HDD_G_MODE_RATETAB(120, 0x40, 0),
271 HDD_G_MODE_RATETAB(180, 0x80, 0),
272 HDD_G_MODE_RATETAB(240, 0x100, 0),
273 HDD_G_MODE_RATETAB(360, 0x200, 0),
274 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700275 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530276};
Jeff Johnson295189b2012-06-20 16:38:30 -0700277
278static struct ieee80211_rate a_mode_rates[] =
279{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530280 HDD_G_MODE_RATETAB(60, 0x10, 0),
281 HDD_G_MODE_RATETAB(90, 0x20, 0),
282 HDD_G_MODE_RATETAB(120, 0x40, 0),
283 HDD_G_MODE_RATETAB(180, 0x80, 0),
284 HDD_G_MODE_RATETAB(240, 0x100, 0),
285 HDD_G_MODE_RATETAB(360, 0x200, 0),
286 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700287 HDD_G_MODE_RATETAB(540, 0x800, 0),
288};
289
290static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
291{
292 .channels = hdd_channels_2_4_GHZ,
293 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
294 .band = IEEE80211_BAND_2GHZ,
295 .bitrates = g_mode_rates,
296 .n_bitrates = g_mode_rates_size,
297 .ht_cap.ht_supported = 1,
298 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
299 | IEEE80211_HT_CAP_GRN_FLD
300 | IEEE80211_HT_CAP_DSSSCCK40
301 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
302 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
303 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
304 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
305 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
306 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
307};
308
Jeff Johnson295189b2012-06-20 16:38:30 -0700309static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
310{
311 .channels = hdd_social_channels_2_4_GHZ,
312 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
313 .band = IEEE80211_BAND_2GHZ,
314 .bitrates = g_mode_rates,
315 .n_bitrates = g_mode_rates_size,
316 .ht_cap.ht_supported = 1,
317 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
318 | IEEE80211_HT_CAP_GRN_FLD
319 | IEEE80211_HT_CAP_DSSSCCK40
320 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
321 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
322 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
323 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
324 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
325 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
326};
Jeff Johnson295189b2012-06-20 16:38:30 -0700327
328static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
329{
330 .channels = hdd_channels_5_GHZ,
331 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
332 .band = IEEE80211_BAND_5GHZ,
333 .bitrates = a_mode_rates,
334 .n_bitrates = a_mode_rates_size,
335 .ht_cap.ht_supported = 1,
336 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
337 | IEEE80211_HT_CAP_GRN_FLD
338 | IEEE80211_HT_CAP_DSSSCCK40
339 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
340 | IEEE80211_HT_CAP_SGI_40
341 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
342 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
343 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
344 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
345 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
346 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
347};
348
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530349/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700350 TX/RX direction for each kind of interface */
351static const struct ieee80211_txrx_stypes
352wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
353 [NL80211_IFTYPE_STATION] = {
354 .tx = 0xffff,
355 .rx = BIT(SIR_MAC_MGMT_ACTION) |
356 BIT(SIR_MAC_MGMT_PROBE_REQ),
357 },
358 [NL80211_IFTYPE_AP] = {
359 .tx = 0xffff,
360 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
361 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
362 BIT(SIR_MAC_MGMT_PROBE_REQ) |
363 BIT(SIR_MAC_MGMT_DISASSOC) |
364 BIT(SIR_MAC_MGMT_AUTH) |
365 BIT(SIR_MAC_MGMT_DEAUTH) |
366 BIT(SIR_MAC_MGMT_ACTION),
367 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700368 [NL80211_IFTYPE_ADHOC] = {
369 .tx = 0xffff,
370 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
371 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
372 BIT(SIR_MAC_MGMT_PROBE_REQ) |
373 BIT(SIR_MAC_MGMT_DISASSOC) |
374 BIT(SIR_MAC_MGMT_AUTH) |
375 BIT(SIR_MAC_MGMT_DEAUTH) |
376 BIT(SIR_MAC_MGMT_ACTION),
377 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700378 [NL80211_IFTYPE_P2P_CLIENT] = {
379 .tx = 0xffff,
380 .rx = BIT(SIR_MAC_MGMT_ACTION) |
381 BIT(SIR_MAC_MGMT_PROBE_REQ),
382 },
383 [NL80211_IFTYPE_P2P_GO] = {
384 /* This is also same as for SoftAP */
385 .tx = 0xffff,
386 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
387 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
388 BIT(SIR_MAC_MGMT_PROBE_REQ) |
389 BIT(SIR_MAC_MGMT_DISASSOC) |
390 BIT(SIR_MAC_MGMT_AUTH) |
391 BIT(SIR_MAC_MGMT_DEAUTH) |
392 BIT(SIR_MAC_MGMT_ACTION),
393 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700394};
395
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800396#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800397static const struct ieee80211_iface_limit
398wlan_hdd_iface_limit[] = {
399 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800400 /* max = 3 ; Our driver create two interfaces during driver init
401 * wlan0 and p2p0 interfaces. p2p0 is considered as station
402 * interface until a group is formed. In JB architecture, once the
403 * group is formed, interface type of p2p0 is changed to P2P GO or
404 * Client.
405 * When supplicant remove the group, it first issue a set interface
406 * cmd to change the mode back to Station. In JB this works fine as
407 * we advertize two station type interface during driver init.
408 * Some vendors create separate interface for P2P GO/Client,
409 * after group formation(Third one). But while group remove
410 * supplicant first tries to change the mode(3rd interface) to STATION
411 * But as we advertized only two sta type interfaces nl80211 was
412 * returning error for the third one which was leading to failure in
413 * delete interface. Ideally while removing the group, supplicant
414 * should not try to change the 3rd interface mode to Station type.
415 * Till we get a fix in wpa_supplicant, we advertize max STA
416 * interface type to 3
417 */
418 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800419 .types = BIT(NL80211_IFTYPE_STATION),
420 },
421 {
422 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700423 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800424 },
425 {
426 .max = 1,
427 .types = BIT(NL80211_IFTYPE_P2P_GO) |
428 BIT(NL80211_IFTYPE_P2P_CLIENT),
429 },
430};
431
432/* By default, only single channel concurrency is allowed */
433static struct ieee80211_iface_combination
434wlan_hdd_iface_combination = {
435 .limits = wlan_hdd_iface_limit,
436 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800437 /*
438 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
439 * and p2p0 interfaces during driver init
440 * Some vendors create separate interface for P2P operations.
441 * wlan0: STA interface
442 * p2p0: P2P Device interface, action frames goes
443 * through this interface.
444 * p2p-xx: P2P interface, After GO negotiation this interface is
445 * created for p2p operations(GO/CLIENT interface).
446 */
447 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800448 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
449 .beacon_int_infra_match = false,
450};
451#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800452
Jeff Johnson295189b2012-06-20 16:38:30 -0700453static struct cfg80211_ops wlan_hdd_cfg80211_ops;
454
455/* Data rate 100KBPS based on IE Index */
456struct index_data_rate_type
457{
458 v_U8_t beacon_rate_index;
459 v_U16_t supported_rate[4];
460};
461
462/* 11B, 11G Rate table include Basic rate and Extended rate
463 The IDX field is the rate index
464 The HI field is the rate when RSSI is strong or being ignored
465 (in this case we report actual rate)
466 The MID field is the rate when RSSI is moderate
467 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
468 The LO field is the rate when RSSI is low
469 (in this case we don't report rates, actual current rate used)
470 */
471static const struct
472{
473 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700474 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700475} supported_data_rate[] =
476{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700477/* IDX HI HM LM LO (RSSI-based index */
478 {2, { 10, 10, 10, 0}},
479 {4, { 20, 20, 10, 0}},
480 {11, { 55, 20, 10, 0}},
481 {12, { 60, 55, 20, 0}},
482 {18, { 90, 55, 20, 0}},
483 {22, {110, 55, 20, 0}},
484 {24, {120, 90, 60, 0}},
485 {36, {180, 120, 60, 0}},
486 {44, {220, 180, 60, 0}},
487 {48, {240, 180, 90, 0}},
488 {66, {330, 180, 90, 0}},
489 {72, {360, 240, 90, 0}},
490 {96, {480, 240, 120, 0}},
491 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700492};
493
494/* MCS Based rate table */
495static struct index_data_rate_type supported_mcs_rate[] =
496{
497/* MCS L20 L40 S20 S40 */
498 {0, {65, 135, 72, 150}},
499 {1, {130, 270, 144, 300}},
500 {2, {195, 405, 217, 450}},
501 {3, {260, 540, 289, 600}},
502 {4, {390, 810, 433, 900}},
503 {5, {520, 1080, 578, 1200}},
504 {6, {585, 1215, 650, 1350}},
505 {7, {650, 1350, 722, 1500}}
506};
507
Leo Chang6f8870f2013-03-26 18:11:36 -0700508#ifdef WLAN_FEATURE_11AC
509
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530510#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700511
512struct index_vht_data_rate_type
513{
514 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530515 v_U16_t supported_VHT80_rate[2];
516 v_U16_t supported_VHT40_rate[2];
517 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700518};
519
520typedef enum
521{
522 DATA_RATE_11AC_MAX_MCS_7,
523 DATA_RATE_11AC_MAX_MCS_8,
524 DATA_RATE_11AC_MAX_MCS_9,
525 DATA_RATE_11AC_MAX_MCS_NA
526} eDataRate11ACMaxMcs;
527
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530528/* SSID broadcast type */
529typedef enum eSSIDBcastType
530{
531 eBCAST_UNKNOWN = 0,
532 eBCAST_NORMAL = 1,
533 eBCAST_HIDDEN = 2,
534} tSSIDBcastType;
535
Leo Chang6f8870f2013-03-26 18:11:36 -0700536/* MCS Based VHT rate table */
537static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
538{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530539/* MCS L80 S80 L40 S40 L20 S40*/
540 {0, {293, 325}, {135, 150}, {65, 72}},
541 {1, {585, 650}, {270, 300}, {130, 144}},
542 {2, {878, 975}, {405, 450}, {195, 217}},
543 {3, {1170, 1300}, {540, 600}, {260, 289}},
544 {4, {1755, 1950}, {810, 900}, {390, 433}},
545 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
546 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
547 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
548 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
549 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700550};
551#endif /* WLAN_FEATURE_11AC */
552
c_hpothu79aab322014-07-14 21:11:01 +0530553/*array index points to MCS and array value points respective rssi*/
554static int rssiMcsTbl[][10] =
555{
556/*MCS 0 1 2 3 4 5 6 7 8 9*/
557 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
558 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
559 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
560};
561
Jeff Johnson295189b2012-06-20 16:38:30 -0700562extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530563#ifdef FEATURE_WLAN_SCAN_PNO
564static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
565#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700566
Leo Chang9056f462013-08-01 19:21:11 -0700567#ifdef WLAN_NL80211_TESTMODE
568enum wlan_hdd_tm_attr
569{
570 WLAN_HDD_TM_ATTR_INVALID = 0,
571 WLAN_HDD_TM_ATTR_CMD = 1,
572 WLAN_HDD_TM_ATTR_DATA = 2,
573 WLAN_HDD_TM_ATTR_TYPE = 3,
574 /* keep last */
575 WLAN_HDD_TM_ATTR_AFTER_LAST,
576 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
577};
578
579enum wlan_hdd_tm_cmd
580{
581 WLAN_HDD_TM_CMD_WLAN_HB = 1,
582};
583
584#define WLAN_HDD_TM_DATA_MAX_LEN 5000
585
586static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
587{
588 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
589 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
590 .len = WLAN_HDD_TM_DATA_MAX_LEN },
591};
592#endif /* WLAN_NL80211_TESTMODE */
593
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800594#ifdef FEATURE_WLAN_CH_AVOID
595/*
596 * FUNCTION: wlan_hdd_send_avoid_freq_event
597 * This is called when wlan driver needs to send vendor specific
598 * avoid frequency range event to userspace
599 */
600int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
601 tHddAvoidFreqList *pAvoidFreqList)
602{
603 struct sk_buff *vendor_event;
604
605 ENTER();
606
607 if (!pHddCtx)
608 {
609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
610 "%s: HDD context is null", __func__);
611 return -1;
612 }
613
614 if (!pAvoidFreqList)
615 {
616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
617 "%s: pAvoidFreqList is null", __func__);
618 return -1;
619 }
620
621 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530622#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
623 NULL,
624#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800625 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530626 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800627 GFP_KERNEL);
628 if (!vendor_event)
629 {
630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
631 "%s: cfg80211_vendor_event_alloc failed", __func__);
632 return -1;
633 }
634
635 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
636 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
637
638 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
639
640 EXIT();
641 return 0;
642}
643#endif /* FEATURE_WLAN_CH_AVOID */
644
Srinivas Dasari030bad32015-02-18 23:23:54 +0530645/*
646 * FUNCTION: __wlan_hdd_cfg80211_nan_request
647 * This is called when wlan driver needs to send vendor specific
648 * nan request event.
649 */
650static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
651 struct wireless_dev *wdev,
652 const void *data, int data_len)
653{
654 tNanRequestReq nan_req;
655 VOS_STATUS status;
656 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530657 struct net_device *dev = wdev->netdev;
658 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
659 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530660 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
661
662 if (0 == data_len)
663 {
664 hddLog(VOS_TRACE_LEVEL_ERROR,
665 FL("NAN - Invalid Request, length = 0"));
666 return ret_val;
667 }
668
669 if (NULL == data)
670 {
671 hddLog(VOS_TRACE_LEVEL_ERROR,
672 FL("NAN - Invalid Request, data is NULL"));
673 return ret_val;
674 }
675
676 status = wlan_hdd_validate_context(pHddCtx);
677 if (0 != status)
678 {
679 hddLog(VOS_TRACE_LEVEL_ERROR,
680 FL("HDD context is not valid"));
681 return -EINVAL;
682 }
683
684 hddLog(LOG1, FL("Received NAN command"));
685 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
686 (tANI_U8 *)data, data_len);
687
688 /* check the NAN Capability */
689 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
690 {
691 hddLog(VOS_TRACE_LEVEL_ERROR,
692 FL("NAN is not supported by Firmware"));
693 return -EINVAL;
694 }
695
696 nan_req.request_data_len = data_len;
697 nan_req.request_data = data;
698
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530699 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530700 if (VOS_STATUS_SUCCESS == status)
701 {
702 ret_val = 0;
703 }
704 return ret_val;
705}
706
707/*
708 * FUNCTION: wlan_hdd_cfg80211_nan_request
709 * Wrapper to protect the nan vendor command from ssr
710 */
711static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
712 struct wireless_dev *wdev,
713 const void *data, int data_len)
714{
715 int ret;
716
717 vos_ssr_protect(__func__);
718 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
719 vos_ssr_unprotect(__func__);
720
721 return ret;
722}
723
724/*
725 * FUNCTION: wlan_hdd_cfg80211_nan_callback
726 * This is a callback function and it gets called
727 * when we need to report nan response event to
728 * upper layers.
729 */
730static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
731{
732 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
733 struct sk_buff *vendor_event;
734 int status;
735 tSirNanEvent *data;
736
737 ENTER();
738 if (NULL == msg)
739 {
740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
741 FL(" msg received here is null"));
742 return;
743 }
744 data = msg;
745
746 status = wlan_hdd_validate_context(pHddCtx);
747
748 if (0 != status)
749 {
750 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
751 FL("HDD context is not valid"));
752 return;
753 }
754
755 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530756#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
757 NULL,
758#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530759 data->event_data_len +
760 NLMSG_HDRLEN,
761 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
762 GFP_KERNEL);
763
764 if (!vendor_event)
765 {
766 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
767 FL("cfg80211_vendor_event_alloc failed"));
768 return;
769 }
770 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
771 data->event_data_len, data->event_data))
772 {
773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
774 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
775 kfree_skb(vendor_event);
776 return;
777 }
778 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
779 EXIT();
780}
781
782/*
783 * FUNCTION: wlan_hdd_cfg80211_nan_init
784 * This function is called to register the callback to sme layer
785 */
786inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
787{
788 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
789}
790
791
Sunil Duttc69bccb2014-05-26 21:30:20 +0530792#ifdef WLAN_FEATURE_LINK_LAYER_STATS
793
794static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
795 struct sk_buff *vendor_event)
796{
797 if (nla_put_u8(vendor_event,
798 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
799 stats->rate.preamble) ||
800 nla_put_u8(vendor_event,
801 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
802 stats->rate.nss) ||
803 nla_put_u8(vendor_event,
804 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
805 stats->rate.bw) ||
806 nla_put_u8(vendor_event,
807 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
808 stats->rate.rateMcsIdx) ||
809 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
810 stats->rate.bitrate ) ||
811 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
812 stats->txMpdu ) ||
813 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
814 stats->rxMpdu ) ||
815 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
816 stats->mpduLost ) ||
817 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
818 stats->retries) ||
819 nla_put_u32(vendor_event,
820 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
821 stats->retriesShort ) ||
822 nla_put_u32(vendor_event,
823 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
824 stats->retriesLong))
825 {
826 hddLog(VOS_TRACE_LEVEL_ERROR,
827 FL("QCA_WLAN_VENDOR_ATTR put fail"));
828 return FALSE;
829 }
830 return TRUE;
831}
832
833static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
834 struct sk_buff *vendor_event)
835{
836 u32 i = 0;
837 struct nlattr *rateInfo;
838 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
839 stats->type) ||
840 nla_put(vendor_event,
841 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
842 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
843 nla_put_u32(vendor_event,
844 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
845 stats->capabilities) ||
846 nla_put_u32(vendor_event,
847 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
848 stats->numRate))
849 {
850 hddLog(VOS_TRACE_LEVEL_ERROR,
851 FL("QCA_WLAN_VENDOR_ATTR put fail"));
852 goto error;
853 }
854
855 rateInfo = nla_nest_start(vendor_event,
856 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530857 if(!rateInfo)
858 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530859 for (i = 0; i < stats->numRate; i++)
860 {
861 struct nlattr *rates;
862 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
863 stats->rateStats +
864 (i * sizeof(tSirWifiRateStat)));
865 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530866 if(!rates)
867 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530868
869 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
870 {
871 hddLog(VOS_TRACE_LEVEL_ERROR,
872 FL("QCA_WLAN_VENDOR_ATTR put fail"));
873 return FALSE;
874 }
875 nla_nest_end(vendor_event, rates);
876 }
877 nla_nest_end(vendor_event, rateInfo);
878
879 return TRUE;
880error:
881 return FALSE;
882}
883
884static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
885 struct sk_buff *vendor_event)
886{
887 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
888 stats->ac ) ||
889 nla_put_u32(vendor_event,
890 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
891 stats->txMpdu ) ||
892 nla_put_u32(vendor_event,
893 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
894 stats->rxMpdu ) ||
895 nla_put_u32(vendor_event,
896 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
897 stats->txMcast ) ||
898 nla_put_u32(vendor_event,
899 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
900 stats->rxMcast ) ||
901 nla_put_u32(vendor_event,
902 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
903 stats->rxAmpdu ) ||
904 nla_put_u32(vendor_event,
905 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
906 stats->txAmpdu ) ||
907 nla_put_u32(vendor_event,
908 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
909 stats->mpduLost )||
910 nla_put_u32(vendor_event,
911 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
912 stats->retries ) ||
913 nla_put_u32(vendor_event,
914 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
915 stats->retriesShort ) ||
916 nla_put_u32(vendor_event,
917 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
918 stats->retriesLong ) ||
919 nla_put_u32(vendor_event,
920 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
921 stats->contentionTimeMin ) ||
922 nla_put_u32(vendor_event,
923 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
924 stats->contentionTimeMax ) ||
925 nla_put_u32(vendor_event,
926 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
927 stats->contentionTimeAvg ) ||
928 nla_put_u32(vendor_event,
929 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
930 stats->contentionNumSamples ))
931 {
932 hddLog(VOS_TRACE_LEVEL_ERROR,
933 FL("QCA_WLAN_VENDOR_ATTR put fail") );
934 return FALSE;
935 }
936 return TRUE;
937}
938
939static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
940 struct sk_buff *vendor_event)
941{
Dino Myclec8f3f332014-07-21 16:48:27 +0530942 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530943 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
944 nla_put(vendor_event,
945 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
946 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
947 nla_put_u32(vendor_event,
948 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
949 stats->state ) ||
950 nla_put_u32(vendor_event,
951 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
952 stats->roaming ) ||
953 nla_put_u32(vendor_event,
954 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
955 stats->capabilities ) ||
956 nla_put(vendor_event,
957 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
958 strlen(stats->ssid), stats->ssid) ||
959 nla_put(vendor_event,
960 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
961 WNI_CFG_BSSID_LEN, stats->bssid) ||
962 nla_put(vendor_event,
963 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
964 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
965 nla_put(vendor_event,
966 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
967 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
968 )
969 {
970 hddLog(VOS_TRACE_LEVEL_ERROR,
971 FL("QCA_WLAN_VENDOR_ATTR put fail") );
972 return FALSE;
973 }
974 return TRUE;
975}
976
Dino Mycle3b9536d2014-07-09 22:05:24 +0530977static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
978 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530979 struct sk_buff *vendor_event)
980{
981 int i = 0;
982 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530983 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
984 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530985 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530986
Sunil Duttc69bccb2014-05-26 21:30:20 +0530987 if (FALSE == put_wifi_interface_info(
988 &pWifiIfaceStat->info,
989 vendor_event))
990 {
991 hddLog(VOS_TRACE_LEVEL_ERROR,
992 FL("QCA_WLAN_VENDOR_ATTR put fail") );
993 return FALSE;
994
995 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530996 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
997 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
998 if (NULL == pWifiIfaceStatTL)
999 {
1000 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1001 return FALSE;
1002 }
1003
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301004 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1005 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1006 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1007 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1008
1009 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1010 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1011 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1012 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301013
1014 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1015 {
1016 if (VOS_STATUS_SUCCESS ==
1017 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1018 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1019 {
1020 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1021 * obtained from TL structure
1022 */
1023
1024 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1025 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301026 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1027
Srinivas Dasari98947432014-11-07 19:41:24 +05301028 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1029 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1030 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1031 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1032 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1033 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1034 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1035 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301036
Srinivas Dasari98947432014-11-07 19:41:24 +05301037 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1038 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1039 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1040 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1041 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1042 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1043 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1044 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301045
Srinivas Dasari98947432014-11-07 19:41:24 +05301046 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1047 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1048 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1049 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1050 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1051 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1052 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1053 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301054 }
1055 else
1056 {
1057 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1058 }
1059
Dino Mycle3b9536d2014-07-09 22:05:24 +05301060 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1061 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1062 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1063 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1064 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1065 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1066 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1067 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1068 }
1069 else
1070 {
1071 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1072 }
1073
1074
Sunil Duttc69bccb2014-05-26 21:30:20 +05301075
1076 if (nla_put_u32(vendor_event,
1077 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1078 pWifiIfaceStat->beaconRx) ||
1079 nla_put_u32(vendor_event,
1080 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1081 pWifiIfaceStat->mgmtRx) ||
1082 nla_put_u32(vendor_event,
1083 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1084 pWifiIfaceStat->mgmtActionRx) ||
1085 nla_put_u32(vendor_event,
1086 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1087 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301088 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301089 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1090 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301091 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301092 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1093 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301094 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301095 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1096 pWifiIfaceStat->rssiAck))
1097 {
1098 hddLog(VOS_TRACE_LEVEL_ERROR,
1099 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301100 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301101 return FALSE;
1102 }
1103
1104 wmmInfo = nla_nest_start(vendor_event,
1105 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301106 if(!wmmInfo)
1107 {
1108 vos_mem_free(pWifiIfaceStatTL);
1109 return FALSE;
1110 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301111 for (i = 0; i < WIFI_AC_MAX; i++)
1112 {
1113 struct nlattr *wmmStats;
1114 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301115 if(!wmmStats)
1116 {
1117 vos_mem_free(pWifiIfaceStatTL);
1118 return FALSE;
1119 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301120 if (FALSE == put_wifi_wmm_ac_stat(
1121 &pWifiIfaceStat->AccessclassStats[i],
1122 vendor_event))
1123 {
1124 hddLog(VOS_TRACE_LEVEL_ERROR,
1125 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301126 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301127 return FALSE;
1128 }
1129
1130 nla_nest_end(vendor_event, wmmStats);
1131 }
1132 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301133 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301134 return TRUE;
1135}
1136
1137static tSirWifiInterfaceMode
1138 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1139{
1140 switch (deviceMode)
1141 {
1142 case WLAN_HDD_INFRA_STATION:
1143 return WIFI_INTERFACE_STA;
1144 case WLAN_HDD_SOFTAP:
1145 return WIFI_INTERFACE_SOFTAP;
1146 case WLAN_HDD_P2P_CLIENT:
1147 return WIFI_INTERFACE_P2P_CLIENT;
1148 case WLAN_HDD_P2P_GO:
1149 return WIFI_INTERFACE_P2P_GO;
1150 case WLAN_HDD_IBSS:
1151 return WIFI_INTERFACE_IBSS;
1152 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301153 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301154 }
1155}
1156
1157static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1158 tpSirWifiInterfaceInfo pInfo)
1159{
1160 v_U8_t *staMac = NULL;
1161 hdd_station_ctx_t *pHddStaCtx;
1162 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1163 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1164
1165 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1166
1167 vos_mem_copy(pInfo->macAddr,
1168 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1169
1170 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1171 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1172 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1173 {
1174 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1175 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1176 {
1177 pInfo->state = WIFI_DISCONNECTED;
1178 }
1179 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1180 {
1181 hddLog(VOS_TRACE_LEVEL_ERROR,
1182 "%s: Session ID %d, Connection is in progress", __func__,
1183 pAdapter->sessionId);
1184 pInfo->state = WIFI_ASSOCIATING;
1185 }
1186 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1187 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1188 {
1189 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1190 hddLog(VOS_TRACE_LEVEL_ERROR,
1191 "%s: client " MAC_ADDRESS_STR
1192 " is in the middle of WPS/EAPOL exchange.", __func__,
1193 MAC_ADDR_ARRAY(staMac));
1194 pInfo->state = WIFI_AUTHENTICATING;
1195 }
1196 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1197 {
1198 pInfo->state = WIFI_ASSOCIATED;
1199 vos_mem_copy(pInfo->bssid,
1200 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1201 vos_mem_copy(pInfo->ssid,
1202 pHddStaCtx->conn_info.SSID.SSID.ssId,
1203 pHddStaCtx->conn_info.SSID.SSID.length);
1204 //NULL Terminate the string.
1205 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1206 }
1207 }
1208 vos_mem_copy(pInfo->countryStr,
1209 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1210
1211 vos_mem_copy(pInfo->apCountryStr,
1212 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1213
1214 return TRUE;
1215}
1216
1217/*
1218 * hdd_link_layer_process_peer_stats () - This function is called after
1219 * receiving Link Layer Peer statistics from FW.This function converts
1220 * the firmware data to the NL data and sends the same to the kernel/upper
1221 * layers.
1222 */
1223static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1224 v_VOID_t *pData)
1225{
1226 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1227 tpSirWifiRateStat pWifiRateStat;
1228 tpSirWifiPeerStat pWifiPeerStat;
1229 tpSirWifiPeerInfo pWifiPeerInfo;
1230 struct nlattr *peerInfo;
1231 struct sk_buff *vendor_event;
1232 int status, i;
1233
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301234 ENTER();
1235
Sunil Duttc69bccb2014-05-26 21:30:20 +05301236 status = wlan_hdd_validate_context(pHddCtx);
1237 if (0 != status)
1238 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301239 return;
1240 }
1241
1242 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1243
1244 hddLog(VOS_TRACE_LEVEL_INFO,
1245 "LL_STATS_PEER_ALL : numPeers %u",
1246 pWifiPeerStat->numPeers);
1247 {
1248 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1249 {
1250 pWifiPeerInfo = (tpSirWifiPeerInfo)
1251 ((uint8 *)pWifiPeerStat->peerInfo +
1252 ( i * sizeof(tSirWifiPeerInfo)));
1253
Dasari Srinivas1be0c4e2014-10-19 13:03:41 +05301254 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) {
1255 pWifiPeerInfo->type = WIFI_PEER_AP;
1256 }
1257 if (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) {
1258 pWifiPeerInfo->type = WIFI_PEER_P2P_GO;
1259 }
1260
Sunil Duttc69bccb2014-05-26 21:30:20 +05301261 hddLog(VOS_TRACE_LEVEL_INFO,
1262 " %d) LL_STATS Channel Stats "
1263 " Peer Type %u "
1264 " peerMacAddress %pM "
1265 " capabilities 0x%x "
1266 " numRate %u ",
1267 i,
1268 pWifiPeerInfo->type,
1269 pWifiPeerInfo->peerMacAddress,
1270 pWifiPeerInfo->capabilities,
1271 pWifiPeerInfo->numRate);
1272 {
1273 int j;
1274 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1275 {
1276 pWifiRateStat = (tpSirWifiRateStat)
1277 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1278 ( j * sizeof(tSirWifiRateStat)));
1279
1280 hddLog(VOS_TRACE_LEVEL_INFO,
1281 " peer Rate Stats "
1282 " preamble %u "
1283 " nss %u "
1284 " bw %u "
1285 " rateMcsIdx %u "
1286 " reserved %u "
1287 " bitrate %u "
1288 " txMpdu %u "
1289 " rxMpdu %u "
1290 " mpduLost %u "
1291 " retries %u "
1292 " retriesShort %u "
1293 " retriesLong %u",
1294 pWifiRateStat->rate.preamble,
1295 pWifiRateStat->rate.nss,
1296 pWifiRateStat->rate.bw,
1297 pWifiRateStat->rate.rateMcsIdx,
1298 pWifiRateStat->rate.reserved,
1299 pWifiRateStat->rate.bitrate,
1300 pWifiRateStat->txMpdu,
1301 pWifiRateStat->rxMpdu,
1302 pWifiRateStat->mpduLost,
1303 pWifiRateStat->retries,
1304 pWifiRateStat->retriesShort,
1305 pWifiRateStat->retriesLong);
1306 }
1307 }
1308 }
1309 }
1310
1311 /*
1312 * Allocate a size of 4096 for the peer stats comprising
1313 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1314 * sizeof (tSirWifiRateStat).Each field is put with an
1315 * NL attribute.The size of 4096 is considered assuming
1316 * that number of rates shall not exceed beyond 50 with
1317 * the sizeof (tSirWifiRateStat) being 32.
1318 */
1319 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05301320#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
1321 NULL,
1322#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301323 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1324 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1325 GFP_KERNEL);
1326 if (!vendor_event)
1327 {
1328 hddLog(VOS_TRACE_LEVEL_ERROR,
1329 "%s: cfg80211_vendor_event_alloc failed",
1330 __func__);
1331 return;
1332 }
1333 if (nla_put_u32(vendor_event,
1334 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1335 pWifiPeerStat->numPeers))
1336 {
1337 hddLog(VOS_TRACE_LEVEL_ERROR,
1338 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1339 kfree_skb(vendor_event);
1340 return;
1341 }
1342
1343 peerInfo = nla_nest_start(vendor_event,
1344 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301345 if(!peerInfo)
1346 {
1347 hddLog(VOS_TRACE_LEVEL_ERROR,
1348 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1349 __func__);
1350 kfree_skb(vendor_event);
1351 return;
1352 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301353
1354 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1355 pWifiPeerStat->peerInfo);
1356
1357 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1358 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301359 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301360 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301361
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301362 if(!peers)
1363 {
1364 hddLog(VOS_TRACE_LEVEL_ERROR,
1365 "%s: peer stats put fail",
1366 __func__);
1367 kfree_skb(vendor_event);
1368 return;
1369 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301370 if (FALSE == put_wifi_peer_info(
1371 pWifiPeerInfo, vendor_event))
1372 {
1373 hddLog(VOS_TRACE_LEVEL_ERROR,
1374 "%s: put_wifi_peer_info put fail", __func__);
1375 kfree_skb(vendor_event);
1376 return;
1377 }
1378
1379 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1380 pWifiPeerStat->peerInfo +
1381 (i * sizeof(tSirWifiPeerInfo)) +
1382 (numRate * sizeof (tSirWifiRateStat)));
1383 nla_nest_end(vendor_event, peers);
1384 }
1385 nla_nest_end(vendor_event, peerInfo);
1386 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301387
1388 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301389}
1390
1391/*
1392 * hdd_link_layer_process_iface_stats () - This function is called after
1393 * receiving Link Layer Interface statistics from FW.This function converts
1394 * the firmware data to the NL data and sends the same to the kernel/upper
1395 * layers.
1396 */
1397static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1398 v_VOID_t *pData)
1399{
1400 tpSirWifiIfaceStat pWifiIfaceStat;
1401 struct sk_buff *vendor_event;
1402 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1403 int status;
1404
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301405 ENTER();
1406
Sunil Duttc69bccb2014-05-26 21:30:20 +05301407 status = wlan_hdd_validate_context(pHddCtx);
1408 if (0 != status)
1409 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301410 return;
1411 }
1412 /*
1413 * Allocate a size of 4096 for the interface stats comprising
1414 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1415 * assuming that all these fit with in the limit.Please take
1416 * a call on the limit based on the data requirements on
1417 * interface statistics.
1418 */
1419 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05301420#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
1421 NULL,
1422#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301423 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1424 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1425 GFP_KERNEL);
1426 if (!vendor_event)
1427 {
1428 hddLog(VOS_TRACE_LEVEL_ERROR,
1429 FL("cfg80211_vendor_event_alloc failed") );
1430 return;
1431 }
1432
1433 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1434
Dino Mycle3b9536d2014-07-09 22:05:24 +05301435
1436 if (FALSE == hdd_get_interface_info( pAdapter,
1437 &pWifiIfaceStat->info))
1438 {
1439 hddLog(VOS_TRACE_LEVEL_ERROR,
1440 FL("hdd_get_interface_info get fail") );
1441 kfree_skb(vendor_event);
1442 return;
1443 }
1444
1445 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1446 vendor_event))
1447 {
1448 hddLog(VOS_TRACE_LEVEL_ERROR,
1449 FL("put_wifi_iface_stats fail") );
1450 kfree_skb(vendor_event);
1451 return;
1452 }
1453
Sunil Duttc69bccb2014-05-26 21:30:20 +05301454 hddLog(VOS_TRACE_LEVEL_INFO,
1455 "WMI_LINK_STATS_IFACE Data");
1456
1457 hddLog(VOS_TRACE_LEVEL_INFO,
1458 "LL_STATS_IFACE: "
1459 " Mode %u "
1460 " MAC %pM "
1461 " State %u "
1462 " Roaming %u "
1463 " capabilities 0x%x "
1464 " SSID %s "
1465 " BSSID %pM",
1466 pWifiIfaceStat->info.mode,
1467 pWifiIfaceStat->info.macAddr,
1468 pWifiIfaceStat->info.state,
1469 pWifiIfaceStat->info.roaming,
1470 pWifiIfaceStat->info.capabilities,
1471 pWifiIfaceStat->info.ssid,
1472 pWifiIfaceStat->info.bssid);
1473
1474 hddLog(VOS_TRACE_LEVEL_INFO,
1475 " AP country str: %c%c%c",
1476 pWifiIfaceStat->info.apCountryStr[0],
1477 pWifiIfaceStat->info.apCountryStr[1],
1478 pWifiIfaceStat->info.apCountryStr[2]);
1479
1480
1481 hddLog(VOS_TRACE_LEVEL_INFO,
1482 " Country Str Association: %c%c%c",
1483 pWifiIfaceStat->info.countryStr[0],
1484 pWifiIfaceStat->info.countryStr[1],
1485 pWifiIfaceStat->info.countryStr[2]);
1486
1487 hddLog(VOS_TRACE_LEVEL_INFO,
1488 " beaconRx %u "
1489 " mgmtRx %u "
1490 " mgmtActionRx %u "
1491 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301492 " rssiMgmt %d "
1493 " rssiData %d "
1494 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301495 pWifiIfaceStat->beaconRx,
1496 pWifiIfaceStat->mgmtRx,
1497 pWifiIfaceStat->mgmtActionRx,
1498 pWifiIfaceStat->mgmtActionTx,
1499 pWifiIfaceStat->rssiMgmt,
1500 pWifiIfaceStat->rssiData,
1501 pWifiIfaceStat->rssiAck );
1502
1503
1504 {
1505 int i;
1506 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1507 {
1508 hddLog(VOS_TRACE_LEVEL_INFO,
1509
1510 " %d) LL_STATS IFACE: "
1511 " ac: %u txMpdu: %u "
1512 " rxMpdu: %u txMcast: %u "
1513 " rxMcast: %u rxAmpdu: %u "
1514 " txAmpdu: %u mpduLost: %u "
1515 " retries: %u retriesShort: %u "
1516 " retriesLong: %u contentionTimeMin: %u "
1517 " contentionTimeMax: %u contentionTimeAvg: %u "
1518 " contentionNumSamples: %u",
1519 i,
1520 pWifiIfaceStat->AccessclassStats[i].ac,
1521 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1522 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1523 pWifiIfaceStat->AccessclassStats[i].txMcast,
1524 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1525 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1526 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1527 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1528 pWifiIfaceStat->AccessclassStats[i].retries,
1529 pWifiIfaceStat->
1530 AccessclassStats[i].retriesShort,
1531 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1532 pWifiIfaceStat->
1533 AccessclassStats[i].contentionTimeMin,
1534 pWifiIfaceStat->
1535 AccessclassStats[i].contentionTimeMax,
1536 pWifiIfaceStat->
1537 AccessclassStats[i].contentionTimeAvg,
1538 pWifiIfaceStat->
1539 AccessclassStats[i].contentionNumSamples);
1540
1541 }
1542 }
1543
Sunil Duttc69bccb2014-05-26 21:30:20 +05301544 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301545
1546 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301547}
1548
1549/*
1550 * hdd_link_layer_process_radio_stats () - This function is called after
1551 * receiving Link Layer Radio statistics from FW.This function converts
1552 * the firmware data to the NL data and sends the same to the kernel/upper
1553 * layers.
1554 */
1555static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1556 v_VOID_t *pData)
1557{
1558 int status, i;
1559 tpSirWifiRadioStat pWifiRadioStat;
1560 tpSirWifiChannelStats pWifiChannelStats;
1561 struct sk_buff *vendor_event;
1562 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1563 struct nlattr *chList;
1564
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301565 ENTER();
1566
Sunil Duttc69bccb2014-05-26 21:30:20 +05301567 status = wlan_hdd_validate_context(pHddCtx);
1568 if (0 != status)
1569 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301570 return;
1571 }
1572 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1573
1574 hddLog(VOS_TRACE_LEVEL_INFO,
1575 "LL_STATS_RADIO"
1576 " radio is %d onTime is %u "
1577 " txTime is %u rxTime is %u "
1578 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301579 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301580 " onTimePnoScan is %u onTimeHs20 is %u "
1581 " numChannels is %u",
1582 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1583 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1584 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301585 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301586 pWifiRadioStat->onTimeRoamScan,
1587 pWifiRadioStat->onTimePnoScan,
1588 pWifiRadioStat->onTimeHs20,
1589 pWifiRadioStat->numChannels);
1590 /*
1591 * Allocate a size of 4096 for the Radio stats comprising
1592 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1593 * (tSirWifiChannelStats).Each channel data is put with an
1594 * NL attribute.The size of 4096 is considered assuming that
1595 * number of channels shall not exceed beyond 60 with the
1596 * sizeof (tSirWifiChannelStats) being 24 bytes.
1597 */
1598
1599 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05301600#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
1601 NULL,
1602#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301603 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1604 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1605 GFP_KERNEL);
1606
1607 if (!vendor_event)
1608 {
1609 hddLog(VOS_TRACE_LEVEL_ERROR,
1610 FL("cfg80211_vendor_event_alloc failed") );
1611 return;
1612 }
1613
1614 if (nla_put_u32(vendor_event,
1615 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1616 pWifiRadioStat->radio) ||
1617 nla_put_u32(vendor_event,
1618 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1619 pWifiRadioStat->onTime) ||
1620 nla_put_u32(vendor_event,
1621 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1622 pWifiRadioStat->txTime) ||
1623 nla_put_u32(vendor_event,
1624 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1625 pWifiRadioStat->rxTime) ||
1626 nla_put_u32(vendor_event,
1627 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1628 pWifiRadioStat->onTimeScan) ||
1629 nla_put_u32(vendor_event,
1630 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1631 pWifiRadioStat->onTimeNbd) ||
1632 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301633 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1634 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301635 nla_put_u32(vendor_event,
1636 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1637 pWifiRadioStat->onTimeRoamScan) ||
1638 nla_put_u32(vendor_event,
1639 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1640 pWifiRadioStat->onTimePnoScan) ||
1641 nla_put_u32(vendor_event,
1642 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1643 pWifiRadioStat->onTimeHs20) ||
1644 nla_put_u32(vendor_event,
1645 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1646 pWifiRadioStat->numChannels))
1647 {
1648 hddLog(VOS_TRACE_LEVEL_ERROR,
1649 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1650 kfree_skb(vendor_event);
1651 return ;
1652 }
1653
1654 chList = nla_nest_start(vendor_event,
1655 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301656 if(!chList)
1657 {
1658 hddLog(VOS_TRACE_LEVEL_ERROR,
1659 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1660 __func__);
1661 kfree_skb(vendor_event);
1662 return;
1663 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301664 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1665 {
1666 struct nlattr *chInfo;
1667
1668 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1669 pWifiRadioStat->channels +
1670 (i * sizeof(tSirWifiChannelStats)));
1671
1672 hddLog(VOS_TRACE_LEVEL_INFO,
1673 " %d) Channel Info"
1674 " width is %u "
1675 " CenterFreq %u "
1676 " CenterFreq0 %u "
1677 " CenterFreq1 %u "
1678 " onTime %u "
1679 " ccaBusyTime %u",
1680 i,
1681 pWifiChannelStats->channel.width,
1682 pWifiChannelStats->channel.centerFreq,
1683 pWifiChannelStats->channel.centerFreq0,
1684 pWifiChannelStats->channel.centerFreq1,
1685 pWifiChannelStats->onTime,
1686 pWifiChannelStats->ccaBusyTime);
1687
1688
1689 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301690 if(!chInfo)
1691 {
1692 hddLog(VOS_TRACE_LEVEL_ERROR,
1693 "%s: failed to put chInfo",
1694 __func__);
1695 kfree_skb(vendor_event);
1696 return;
1697 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301698
1699 if (nla_put_u32(vendor_event,
1700 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1701 pWifiChannelStats->channel.width) ||
1702 nla_put_u32(vendor_event,
1703 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1704 pWifiChannelStats->channel.centerFreq) ||
1705 nla_put_u32(vendor_event,
1706 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1707 pWifiChannelStats->channel.centerFreq0) ||
1708 nla_put_u32(vendor_event,
1709 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1710 pWifiChannelStats->channel.centerFreq1) ||
1711 nla_put_u32(vendor_event,
1712 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1713 pWifiChannelStats->onTime) ||
1714 nla_put_u32(vendor_event,
1715 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1716 pWifiChannelStats->ccaBusyTime))
1717 {
1718 hddLog(VOS_TRACE_LEVEL_ERROR,
1719 FL("cfg80211_vendor_event_alloc failed") );
1720 kfree_skb(vendor_event);
1721 return ;
1722 }
1723 nla_nest_end(vendor_event, chInfo);
1724 }
1725 nla_nest_end(vendor_event, chList);
1726
1727 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301728
1729 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301730 return;
1731}
1732
1733/*
1734 * hdd_link_layer_stats_ind_callback () - This function is called after
1735 * receiving Link Layer indications from FW.This callback converts the firmware
1736 * data to the NL data and send the same to the kernel/upper layers.
1737 */
1738static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1739 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301740 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301741{
Dino Mycled3d50022014-07-07 12:58:25 +05301742 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1743 hdd_adapter_t *pAdapter = NULL;
1744 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301745 int status;
1746
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301747 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301748
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301749 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301750 if (0 != status)
1751 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301752 return;
1753 }
1754
Dino Mycled3d50022014-07-07 12:58:25 +05301755 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1756 if (NULL == pAdapter)
1757 {
1758 hddLog(VOS_TRACE_LEVEL_ERROR,
1759 FL(" MAC address %pM does not exist with host"),
1760 macAddr);
1761 return;
1762 }
1763
Sunil Duttc69bccb2014-05-26 21:30:20 +05301764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301765 "%s: Interface: %s LLStats indType: %d", __func__,
1766 pAdapter->dev->name, indType);
1767
Sunil Duttc69bccb2014-05-26 21:30:20 +05301768 switch (indType)
1769 {
1770 case SIR_HAL_LL_STATS_RESULTS_RSP:
1771 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301772 hddLog(VOS_TRACE_LEVEL_INFO,
1773 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1774 hddLog(VOS_TRACE_LEVEL_INFO,
1775 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1776 linkLayerStatsResults->paramId);
1777 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301778 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1779 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301780 hddLog(VOS_TRACE_LEVEL_INFO,
1781 "LL_STATS RESULTS RESPONSE respId = %u",
1782 linkLayerStatsResults->respId);
1783 hddLog(VOS_TRACE_LEVEL_INFO,
1784 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1785 linkLayerStatsResults->moreResultToFollow);
1786 hddLog(VOS_TRACE_LEVEL_INFO,
1787 "LL_STATS RESULTS RESPONSE result = %p",
1788 linkLayerStatsResults->result);
1789 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1790 {
1791 hdd_link_layer_process_radio_stats(pAdapter,
1792 (v_VOID_t *)linkLayerStatsResults->result);
1793 }
1794 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1795 {
1796 hdd_link_layer_process_iface_stats(pAdapter,
1797 (v_VOID_t *)linkLayerStatsResults->result);
1798 }
1799 else if ( linkLayerStatsResults->paramId &
1800 WMI_LINK_STATS_ALL_PEER )
1801 {
1802 hdd_link_layer_process_peer_stats(pAdapter,
1803 (v_VOID_t *)linkLayerStatsResults->result);
1804 } /* WMI_LINK_STATS_ALL_PEER */
1805 else
1806 {
1807 hddLog(VOS_TRACE_LEVEL_ERROR,
1808 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1809 }
1810
1811 break;
1812 }
1813 default:
1814 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1815 break;
1816 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301817
1818 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301819 return;
1820}
1821
1822const struct
1823nla_policy
1824qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1825{
1826 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1827 { .type = NLA_U32 },
1828 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1829 { .type = NLA_U32 },
1830};
1831
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301832static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1833 struct wireless_dev *wdev,
1834 const void *data,
1835 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301836{
1837 int status;
1838 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301839 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301840 struct net_device *dev = wdev->netdev;
1841 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1842 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Srinivas Dasari98947432014-11-07 19:41:24 +05301843 hdd_station_ctx_t *pHddStaCtx;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301844
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301845 ENTER();
1846
Sunil Duttc69bccb2014-05-26 21:30:20 +05301847 status = wlan_hdd_validate_context(pHddCtx);
1848 if (0 != status)
1849 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301850 return -EINVAL;
1851 }
1852
1853 if (NULL == pAdapter)
1854 {
1855 hddLog(VOS_TRACE_LEVEL_ERROR,
1856 FL("HDD adapter is Null"));
1857 return -ENODEV;
1858 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301859 /* check the LLStats Capability */
1860 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1861 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1862 {
1863 hddLog(VOS_TRACE_LEVEL_ERROR,
1864 FL("Link Layer Statistics not supported by Firmware"));
1865 return -EINVAL;
1866 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301867
1868 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1869 (struct nlattr *)data,
1870 data_len, qca_wlan_vendor_ll_set_policy))
1871 {
1872 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1873 return -EINVAL;
1874 }
1875 if (!tb_vendor
1876 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1877 {
1878 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1879 return -EINVAL;
1880 }
1881 if (!tb_vendor[
1882 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1883 {
1884 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1885 return -EINVAL;
1886 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301887 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301888 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301889
Dino Mycledf0a5d92014-07-04 09:41:55 +05301890 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301891 nla_get_u32(
1892 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1893
Dino Mycledf0a5d92014-07-04 09:41:55 +05301894 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301895 nla_get_u32(
1896 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1897
Dino Mycled3d50022014-07-07 12:58:25 +05301898 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1899 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301900
1901
1902 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301903 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301904 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301905 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301906 hddLog(VOS_TRACE_LEVEL_INFO,
1907 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301908 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301909 hddLog(VOS_TRACE_LEVEL_INFO,
1910 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301911 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301912
1913 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1914 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301915 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301916 {
1917 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1918 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301919 return -EINVAL;
1920
1921 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301922
1923 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1924 if (VOS_STATUS_SUCCESS !=
1925 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1926 pHddStaCtx->conn_info.staId[0], WIFI_STATS_IFACE))
1927 {
1928 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1929 "WLANTL_ClearInterfaceStats Failed", __func__);
1930 return -EINVAL;
1931 }
1932
Sunil Duttc69bccb2014-05-26 21:30:20 +05301933 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301934 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301935 {
1936 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1937 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301938 return -EINVAL;
1939 }
1940
1941 pAdapter->isLinkLayerStatsSet = 1;
1942
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301943 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301944 return 0;
1945}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301946static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1947 struct wireless_dev *wdev,
1948 const void *data,
1949 int data_len)
1950{
1951 int ret = 0;
1952
1953 vos_ssr_protect(__func__);
1954 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1955 vos_ssr_unprotect(__func__);
1956
1957 return ret;
1958}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301959
1960const struct
1961nla_policy
1962qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1963{
1964 /* Unsigned 32bit value provided by the caller issuing the GET stats
1965 * command. When reporting
1966 * the stats results, the driver uses the same value to indicate
1967 * which GET request the results
1968 * correspond to.
1969 */
1970 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1971
1972 /* Unsigned 32bit value . bit mask to identify what statistics are
1973 requested for retrieval */
1974 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1975};
1976
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301977static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1978 struct wireless_dev *wdev,
1979 const void *data,
1980 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301981{
1982 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1983 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301984 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301985 struct net_device *dev = wdev->netdev;
1986 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1987 int status;
1988
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301989 ENTER();
1990
Sunil Duttc69bccb2014-05-26 21:30:20 +05301991 status = wlan_hdd_validate_context(pHddCtx);
1992 if (0 != status)
1993 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301994 return -EINVAL ;
1995 }
1996
1997 if (NULL == pAdapter)
1998 {
1999 hddLog(VOS_TRACE_LEVEL_FATAL,
2000 "%s: HDD adapter is Null", __func__);
2001 return -ENODEV;
2002 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302003 /* check the LLStats Capability */
2004 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2005 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2006 {
2007 hddLog(VOS_TRACE_LEVEL_ERROR,
2008 FL("Link Layer Statistics not supported by Firmware"));
2009 return -EINVAL;
2010 }
2011
Sunil Duttc69bccb2014-05-26 21:30:20 +05302012
2013 if (!pAdapter->isLinkLayerStatsSet)
2014 {
2015 hddLog(VOS_TRACE_LEVEL_FATAL,
2016 "%s: isLinkLayerStatsSet : %d",
2017 __func__, pAdapter->isLinkLayerStatsSet);
2018 return -EINVAL;
2019 }
2020
2021 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2022 (struct nlattr *)data,
2023 data_len, qca_wlan_vendor_ll_get_policy))
2024 {
2025 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2026 return -EINVAL;
2027 }
2028
2029 if (!tb_vendor
2030 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2031 {
2032 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2033 return -EINVAL;
2034 }
2035
2036 if (!tb_vendor
2037 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2038 {
2039 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2040 return -EINVAL;
2041 }
2042
Sunil Duttc69bccb2014-05-26 21:30:20 +05302043
Dino Mycledf0a5d92014-07-04 09:41:55 +05302044 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302045 nla_get_u32( tb_vendor[
2046 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302047 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302048 nla_get_u32( tb_vendor[
2049 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2050
Dino Mycled3d50022014-07-07 12:58:25 +05302051 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2052 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302053
2054 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302055 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302056 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302057 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302058 hddLog(VOS_TRACE_LEVEL_INFO,
2059 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302060 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302061
2062 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302063 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302064 {
2065 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2066 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302067 return -EINVAL;
2068 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302069
2070 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302071 return 0;
2072}
2073
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302074static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2075 struct wireless_dev *wdev,
2076 const void *data,
2077 int data_len)
2078{
2079 int ret = 0;
2080
2081 vos_ssr_protect(__func__);
2082 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
2083 vos_ssr_unprotect(__func__);
2084
2085 return ret;
2086}
2087
Sunil Duttc69bccb2014-05-26 21:30:20 +05302088const struct
2089nla_policy
2090qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2091{
2092 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2093 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2094 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2095 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2096};
2097
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302098static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2099 struct wireless_dev *wdev,
2100 const void *data,
2101 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302102{
2103 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2104 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302105 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302106 struct net_device *dev = wdev->netdev;
2107 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2108 u32 statsClearReqMask;
2109 u8 stopReq;
2110 int status;
2111
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302112 ENTER();
2113
Sunil Duttc69bccb2014-05-26 21:30:20 +05302114 status = wlan_hdd_validate_context(pHddCtx);
2115 if (0 != status)
2116 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302117 return -EINVAL;
2118 }
2119
2120 if (NULL == pAdapter)
2121 {
2122 hddLog(VOS_TRACE_LEVEL_FATAL,
2123 "%s: HDD adapter is Null", __func__);
2124 return -ENODEV;
2125 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302126 /* check the LLStats Capability */
2127 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2128 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2129 {
2130 hddLog(VOS_TRACE_LEVEL_ERROR,
2131 FL("Enable LLStats Capability"));
2132 return -EINVAL;
2133 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302134
2135 if (!pAdapter->isLinkLayerStatsSet)
2136 {
2137 hddLog(VOS_TRACE_LEVEL_FATAL,
2138 "%s: isLinkLayerStatsSet : %d",
2139 __func__, pAdapter->isLinkLayerStatsSet);
2140 return -EINVAL;
2141 }
2142
2143 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2144 (struct nlattr *)data,
2145 data_len, qca_wlan_vendor_ll_clr_policy))
2146 {
2147 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2148 return -EINVAL;
2149 }
2150
2151 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2152
2153 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2154 {
2155 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2156 return -EINVAL;
2157
2158 }
2159
Sunil Duttc69bccb2014-05-26 21:30:20 +05302160
Dino Mycledf0a5d92014-07-04 09:41:55 +05302161 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302162 nla_get_u32(
2163 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2164
Dino Mycledf0a5d92014-07-04 09:41:55 +05302165 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302166 nla_get_u8(
2167 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2168
2169 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302170 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302171
Dino Mycled3d50022014-07-07 12:58:25 +05302172 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2173 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302174
2175 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302176 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302177 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302178 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302179 hddLog(VOS_TRACE_LEVEL_INFO,
2180 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302181 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302182 hddLog(VOS_TRACE_LEVEL_INFO,
2183 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302184 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302185
2186 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302187 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302188 {
2189 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302190 hdd_station_ctx_t *pHddStaCtx;
2191
2192 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2193 if (VOS_STATUS_SUCCESS !=
2194 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2195 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2196 {
2197 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2198 "WLANTL_ClearInterfaceStats Failed", __func__);
2199 return -EINVAL;
2200 }
2201 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2202 (statsClearReqMask & WIFI_STATS_IFACE)) {
2203 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2204 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2205 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2206 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2207 }
2208
Sunil Duttc69bccb2014-05-26 21:30:20 +05302209 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2210 2 * sizeof(u32) +
2211 NLMSG_HDRLEN);
2212
2213 if (temp_skbuff != NULL)
2214 {
2215
2216 if (nla_put_u32(temp_skbuff,
2217 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2218 statsClearReqMask) ||
2219 nla_put_u32(temp_skbuff,
2220 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2221 stopReq))
2222 {
2223 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2224 kfree_skb(temp_skbuff);
2225 return -EINVAL;
2226 }
2227 /* If the ask is to stop the stats collection as part of clear
2228 * (stopReq = 1) , ensure that no further requests of get
2229 * go to the firmware by having isLinkLayerStatsSet set to 0.
2230 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302231 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302232 * case the firmware is just asked to clear the statistics.
2233 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302234 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302235 pAdapter->isLinkLayerStatsSet = 0;
2236 return cfg80211_vendor_cmd_reply(temp_skbuff);
2237 }
2238 return -ENOMEM;
2239 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302240
2241 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302242 return -EINVAL;
2243}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302244static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2245 struct wireless_dev *wdev,
2246 const void *data,
2247 int data_len)
2248{
2249 int ret = 0;
2250
2251 vos_ssr_protect(__func__);
2252 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2253 vos_ssr_unprotect(__func__);
2254
2255 return ret;
2256
2257
2258}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302259#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2260
Dino Mycle6fb96c12014-06-10 11:52:40 +05302261#ifdef WLAN_FEATURE_EXTSCAN
2262static const struct nla_policy
2263wlan_hdd_extscan_config_policy
2264 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2265{
2266 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2267 { .type = NLA_U32 },
2268 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2269 { .type = NLA_U32 },
2270 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2271 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2272 { .type = NLA_U32 },
2273 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2274 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2275
2276 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2277 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2278 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2279 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2280 { .type = NLA_U8 },
2281 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2282 { .type = NLA_U32 },
2283 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2284 { .type = NLA_U32 },
2285 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2286 { .type = NLA_U32 },
2287 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
2288 { .type = NLA_U8 },
2289 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2290 { .type = NLA_U8 },
2291 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2292 { .type = NLA_U8 },
2293
2294 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2295 { .type = NLA_U32 },
2296 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2297 { .type = NLA_UNSPEC },
2298 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2299 { .type = NLA_S32 },
2300 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2301 { .type = NLA_S32 },
2302 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2303 { .type = NLA_U32 },
2304 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2305 { .type = NLA_U32 },
2306 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2307 { .type = NLA_U32 },
2308 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2309 = { .type = NLA_U32 },
2310 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2311 { .type = NLA_U32 },
2312 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2313 NLA_U32 },
2314};
2315
2316static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
2317{
2318 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2319 struct sk_buff *skb = NULL;
2320 tpSirEXTScanCapabilitiesEvent pData =
2321 (tpSirEXTScanCapabilitiesEvent) pMsg;
2322
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302323 ENTER();
2324
2325 if (wlan_hdd_validate_context(pHddCtx))
2326 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302327 return;
2328 }
2329
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302330 if (!pMsg)
2331 {
2332 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2333 return;
2334 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302335 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302336#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2337 NULL,
2338#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302339 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2340 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
2341 GFP_KERNEL);
2342
2343 if (!skb) {
2344 hddLog(VOS_TRACE_LEVEL_ERROR,
2345 FL("cfg80211_vendor_event_alloc failed"));
2346 return;
2347 }
2348
2349 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2350 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
2351 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
2352 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
2353 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
2354 pData->maxRssiSampleSize);
2355 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
2356 pData->maxScanReportingThreshold);
2357 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
2358 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
2359 pData->maxSignificantWifiChangeAPs);
2360 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
2361 pData->maxBsidHistoryEntries);
2362
2363 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2364 pData->requestId) ||
2365 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
2366 nla_put_u32(skb,
2367 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
2368 pData->scanCacheSize) ||
2369 nla_put_u32(skb,
2370 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
2371 pData->scanBuckets) ||
2372 nla_put_u32(skb,
2373 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
2374 pData->maxApPerScan) ||
2375 nla_put_u32(skb,
2376 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
2377 pData->maxRssiSampleSize) ||
2378 nla_put_u32(skb,
2379 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
2380 pData->maxScanReportingThreshold) ||
2381 nla_put_u32(skb,
2382 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
2383 pData->maxHotlistAPs) ||
2384 nla_put_u32(skb,
2385 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
2386 pData->maxSignificantWifiChangeAPs) ||
2387 nla_put_u32(skb,
2388 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2389 pData->maxBsidHistoryEntries)) {
2390 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2391 goto nla_put_failure;
2392 }
2393
2394 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302395 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302396 return;
2397
2398nla_put_failure:
2399 kfree_skb(skb);
2400 return;
2401}
2402
2403
2404static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2405{
2406 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2407 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2408 struct sk_buff *skb = NULL;
2409 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2410
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302411 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302412
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302413 if (wlan_hdd_validate_context(pHddCtx)){
2414 return;
2415 }
2416 if (!pMsg)
2417 {
2418 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302419 return;
2420 }
2421
2422 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302423#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2424 NULL,
2425#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302426 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2427 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2428 GFP_KERNEL);
2429
2430 if (!skb) {
2431 hddLog(VOS_TRACE_LEVEL_ERROR,
2432 FL("cfg80211_vendor_event_alloc failed"));
2433 return;
2434 }
2435 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2436 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2437 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2438
2439 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2440 pData->requestId) ||
2441 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2442 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2443 goto nla_put_failure;
2444 }
2445
2446 /*
2447 * Store the Request ID for comparing with the requestID obtained
2448 * in other requests.HDD shall return a failure is the extscan_stop
2449 * request is issued with a different requestId as that of the
2450 * extscan_start request. Also, This requestId shall be used while
2451 * indicating the full scan results to the upper layers.
2452 * The requestId is stored with the assumption that the firmware
2453 * shall return the ext scan start request's requestId in ext scan
2454 * start response.
2455 */
2456 if (pData->status == 0)
2457 pMac->sme.extScanStartReqId = pData->requestId;
2458
2459
2460 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302461 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302462 return;
2463
2464nla_put_failure:
2465 kfree_skb(skb);
2466 return;
2467}
2468
2469
2470static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2471{
2472 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2473 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2474 struct sk_buff *skb = NULL;
2475
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302476 ENTER();
2477
2478 if (wlan_hdd_validate_context(pHddCtx)){
2479 return;
2480 }
2481 if (!pMsg)
2482 {
2483 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302484 return;
2485 }
2486
2487 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302488#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2489 NULL,
2490#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302491 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2492 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2493 GFP_KERNEL);
2494
2495 if (!skb) {
2496 hddLog(VOS_TRACE_LEVEL_ERROR,
2497 FL("cfg80211_vendor_event_alloc failed"));
2498 return;
2499 }
2500 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2501 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2502
2503 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2504 pData->requestId) ||
2505 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2506 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2507 goto nla_put_failure;
2508 }
2509
2510 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302511 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302512 return;
2513
2514nla_put_failure:
2515 kfree_skb(skb);
2516 return;
2517}
2518
2519
2520static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2521 void *pMsg)
2522{
2523 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2524 struct sk_buff *skb = NULL;
2525 tpSirEXTScanSetBssidHotListRspParams pData =
2526 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2527
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302528 ENTER();
2529
2530 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302531 return;
2532 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302533 if (!pMsg)
2534 {
2535 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2536 return;
2537 }
2538
Dino Mycle6fb96c12014-06-10 11:52:40 +05302539 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302540#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2541 NULL,
2542#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302543 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2544 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2545 GFP_KERNEL);
2546
2547 if (!skb) {
2548 hddLog(VOS_TRACE_LEVEL_ERROR,
2549 FL("cfg80211_vendor_event_alloc failed"));
2550 return;
2551 }
2552 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2553 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2554 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2555
2556 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2557 pData->requestId) ||
2558 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2559 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2560 goto nla_put_failure;
2561 }
2562
2563 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302564 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302565 return;
2566
2567nla_put_failure:
2568 kfree_skb(skb);
2569 return;
2570}
2571
2572static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2573 void *pMsg)
2574{
2575 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2576 struct sk_buff *skb = NULL;
2577 tpSirEXTScanResetBssidHotlistRspParams pData =
2578 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2579
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302580 ENTER();
2581
2582 if (wlan_hdd_validate_context(pHddCtx)) {
2583 return;
2584 }
2585 if (!pMsg)
2586 {
2587 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302588 return;
2589 }
2590
2591 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302592#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2593 NULL,
2594#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302595 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2596 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2597 GFP_KERNEL);
2598
2599 if (!skb) {
2600 hddLog(VOS_TRACE_LEVEL_ERROR,
2601 FL("cfg80211_vendor_event_alloc failed"));
2602 return;
2603 }
2604 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2605 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2606
2607 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2608 pData->requestId) ||
2609 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2610 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2611 goto nla_put_failure;
2612 }
2613
2614 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302615 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302616 return;
2617
2618nla_put_failure:
2619 kfree_skb(skb);
2620 return;
2621}
2622
2623
2624static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2625 void *pMsg)
2626{
2627 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2628 struct sk_buff *skb = NULL;
2629 tpSirEXTScanSetSignificantChangeRspParams pData =
2630 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2631
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302632 ENTER();
2633
2634 if (wlan_hdd_validate_context(pHddCtx)) {
2635 return;
2636 }
2637 if (!pMsg)
2638 {
2639 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302640 return;
2641 }
2642
2643 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302644#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2645 NULL,
2646#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302647 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2648 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2649 GFP_KERNEL);
2650
2651 if (!skb) {
2652 hddLog(VOS_TRACE_LEVEL_ERROR,
2653 FL("cfg80211_vendor_event_alloc failed"));
2654 return;
2655 }
2656 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2657 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2658 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2659
2660 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2661 pData->requestId) ||
2662 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2663 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2664 goto nla_put_failure;
2665 }
2666
2667 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302668 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302669 return;
2670
2671nla_put_failure:
2672 kfree_skb(skb);
2673 return;
2674}
2675
2676
2677static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2678 void *pMsg)
2679{
2680 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2681 struct sk_buff *skb = NULL;
2682 tpSirEXTScanResetSignificantChangeRspParams pData =
2683 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2684
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302685 ENTER();
2686
2687 if (wlan_hdd_validate_context(pHddCtx)) {
2688 return;
2689 }
2690 if (!pMsg)
2691 {
2692 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302693 return;
2694 }
2695
2696 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302697#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2698 NULL,
2699#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302700 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2701 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2702 GFP_KERNEL);
2703
2704 if (!skb) {
2705 hddLog(VOS_TRACE_LEVEL_ERROR,
2706 FL("cfg80211_vendor_event_alloc failed"));
2707 return;
2708 }
2709 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2710 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2711 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2712
2713 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2714 pData->requestId) ||
2715 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2716 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2717 goto nla_put_failure;
2718 }
2719
2720 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302721 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302722 return;
2723
2724nla_put_failure:
2725 kfree_skb(skb);
2726 return;
2727}
2728
2729static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2730 void *pMsg)
2731{
2732 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2733 struct sk_buff *skb = NULL;
2734 tANI_U32 i = 0, j, resultsPerEvent;
2735 tANI_S32 totalResults;
2736 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2737 tpSirWifiScanResult pSirWifiScanResult;
2738
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302739 ENTER();
2740
2741 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302742 return;
2743 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302744 if (!pMsg)
2745 {
2746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2747 return;
2748 }
2749
Dino Mycle6fb96c12014-06-10 11:52:40 +05302750 totalResults = pData->numOfAps;
2751 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2752 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2753 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2754
2755 do{
2756 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2757 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2758 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2759
2760 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302761#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2762 NULL,
2763#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302764 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2765 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2766 GFP_KERNEL);
2767
2768 if (!skb) {
2769 hddLog(VOS_TRACE_LEVEL_ERROR,
2770 FL("cfg80211_vendor_event_alloc failed"));
2771 return;
2772 }
2773
2774 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2775
2776 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2777 pData->requestId) ||
2778 nla_put_u32(skb,
2779 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2780 resultsPerEvent)) {
2781 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2782 goto fail;
2783 }
2784 if (nla_put_u8(skb,
2785 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2786 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2787 {
2788 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2789 goto fail;
2790 }
2791
2792 if (resultsPerEvent) {
2793 struct nlattr *aps;
2794
2795 aps = nla_nest_start(skb,
2796 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2797 if (!aps)
2798 {
2799 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2800 goto fail;
2801 }
2802
2803 for (j = 0; j < resultsPerEvent; j++, i++) {
2804 struct nlattr *ap;
2805 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2806 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2807
2808 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2809 "Ssid (%s)"
2810 "Bssid: %pM "
2811 "Channel (%u)"
2812 "Rssi (%d)"
2813 "RTT (%u)"
2814 "RTT_SD (%u)",
2815 i,
2816 pSirWifiScanResult->ts,
2817 pSirWifiScanResult->ssid,
2818 pSirWifiScanResult->bssid,
2819 pSirWifiScanResult->channel,
2820 pSirWifiScanResult->rssi,
2821 pSirWifiScanResult->rtt,
2822 pSirWifiScanResult->rtt_sd);
2823
2824 ap = nla_nest_start(skb, j + 1);
2825 if (!ap)
2826 {
2827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2828 goto fail;
2829 }
2830
2831 if (nla_put_u64(skb,
2832 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2833 pSirWifiScanResult->ts) )
2834 {
2835 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2836 goto fail;
2837 }
2838 if (nla_put(skb,
2839 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2840 sizeof(pSirWifiScanResult->ssid),
2841 pSirWifiScanResult->ssid) )
2842 {
2843 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2844 goto fail;
2845 }
2846 if (nla_put(skb,
2847 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2848 sizeof(pSirWifiScanResult->bssid),
2849 pSirWifiScanResult->bssid) )
2850 {
2851 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2852 goto fail;
2853 }
2854 if (nla_put_u32(skb,
2855 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2856 pSirWifiScanResult->channel) )
2857 {
2858 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2859 goto fail;
2860 }
Dasari Srinivas90747d72014-10-08 12:16:15 +05302861 if (nla_put_s32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302862 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2863 pSirWifiScanResult->rssi) )
2864 {
2865 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2866 goto fail;
2867 }
2868 if (nla_put_u32(skb,
2869 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2870 pSirWifiScanResult->rtt) )
2871 {
2872 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2873 goto fail;
2874 }
2875 if (nla_put_u32(skb,
2876 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2877 pSirWifiScanResult->rtt_sd))
2878 {
2879 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2880 goto fail;
2881 }
2882
2883 nla_nest_end(skb, ap);
2884 }
2885 nla_nest_end(skb, aps);
2886
2887 }
2888 cfg80211_vendor_event(skb, GFP_KERNEL);
2889 } while (totalResults > 0);
2890
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302891 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302892 return;
2893fail:
2894 kfree_skb(skb);
2895 return;
2896}
2897
2898static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2899 void *pMsg)
2900{
2901 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2902 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2903 struct sk_buff *skb = NULL;
2904 tANI_U32 i;
2905
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302906 ENTER();
2907
2908 if (wlan_hdd_validate_context(pHddCtx)) {
2909 return;
2910 }
2911 if (!pMsg)
2912 {
2913 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302914 return;
2915 }
2916
2917 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302918#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2919 NULL,
2920#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302921 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2922 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2923 GFP_KERNEL);
2924
2925 if (!skb) {
2926 hddLog(VOS_TRACE_LEVEL_ERROR,
2927 FL("cfg80211_vendor_event_alloc failed"));
2928 return;
2929 }
2930 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2931 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2932 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2933 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2934
2935 for (i = 0; i < pData->numOfAps; i++) {
2936 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2937 "Ssid (%s) "
2938 "Bssid (" MAC_ADDRESS_STR ") "
2939 "Channel (%u) "
2940 "Rssi (%d) "
2941 "RTT (%u) "
2942 "RTT_SD (%u) ",
2943 i,
2944 pData->ap[i].ts,
2945 pData->ap[i].ssid,
2946 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2947 pData->ap[i].channel,
2948 pData->ap[i].rssi,
2949 pData->ap[i].rtt,
2950 pData->ap[i].rtt_sd);
2951 }
2952
2953 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2954 pData->requestId) ||
2955 nla_put_u32(skb,
2956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2957 pData->numOfAps)) {
2958 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2959 goto fail;
2960 }
2961 if (pData->numOfAps) {
2962 struct nlattr *aps;
2963
2964 aps = nla_nest_start(skb,
2965 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2966 if (!aps)
2967 goto fail;
2968
2969 for (i = 0; i < pData->numOfAps; i++) {
2970 struct nlattr *ap;
2971
2972 ap = nla_nest_start(skb, i + 1);
2973 if (!ap)
2974 goto fail;
2975
2976 if (nla_put_u64(skb,
2977 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2978 pData->ap[i].ts) ||
2979 nla_put(skb,
2980 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2981 sizeof(pData->ap[i].ssid),
2982 pData->ap[i].ssid) ||
2983 nla_put(skb,
2984 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2985 sizeof(pData->ap[i].bssid),
2986 pData->ap[i].bssid) ||
2987 nla_put_u32(skb,
2988 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2989 pData->ap[i].channel) ||
2990 nla_put_s32(skb,
2991 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2992 pData->ap[i].rssi) ||
2993 nla_put_u32(skb,
2994 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2995 pData->ap[i].rtt) ||
2996 nla_put_u32(skb,
2997 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2998 pData->ap[i].rtt_sd))
2999 goto fail;
3000
3001 nla_nest_end(skb, ap);
3002 }
3003 nla_nest_end(skb, aps);
3004
3005 if (nla_put_u8(skb,
3006 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3007 pData->moreData))
3008 goto fail;
3009 }
3010
3011 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303012 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303013 return;
3014
3015fail:
3016 kfree_skb(skb);
3017 return;
3018
3019}
3020static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
3021 void *pMsg)
3022{
3023 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3024 struct sk_buff *skb = NULL;
3025 tANI_U32 i, j;
3026 tpSirWifiSignificantChangeEvent pData =
3027 (tpSirWifiSignificantChangeEvent) pMsg;
3028
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303029 ENTER();
3030
3031 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303032 return;
3033 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303034 if (!pMsg)
3035 {
3036 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3037 return;
3038 }
3039
Dino Mycle6fb96c12014-06-10 11:52:40 +05303040 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303041#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3042 NULL,
3043#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303044 EXTSCAN_EVENT_BUF_SIZE,
3045 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
3046 GFP_KERNEL);
3047
3048 if (!skb) {
3049 hddLog(VOS_TRACE_LEVEL_ERROR,
3050 FL("cfg80211_vendor_event_alloc failed"));
3051 return;
3052 }
3053 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3054 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3055 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
3056 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
3057 pData->numSigRssiBss);
3058 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
3059
3060 for (i = 0; i < pData->numSigRssiBss; i++) {
3061 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
3062 " num RSSI %u ",
3063 i, pData->sigRssiResult[i].bssid,
3064 pData->sigRssiResult[i].channel,
3065 pData->sigRssiResult[i].numRssi);
3066
3067 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
3068
3069 hddLog(VOS_TRACE_LEVEL_INFO,
3070 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05303071 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303072
3073 }
3074 }
3075
3076
3077 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3078 pData->requestId) ||
3079 nla_put_u32(skb,
3080 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3081 pData->numSigRssiBss)) {
3082 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3083 goto fail;
3084 }
3085
3086 if (pData->numSigRssiBss) {
3087 struct nlattr *aps;
3088 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3089 if (!aps)
3090 goto fail;
3091 for (i = 0; i < pData->numSigRssiBss; i++) {
3092 struct nlattr *ap;
3093
3094 ap = nla_nest_start(skb, i);
3095 if (!ap)
3096 goto fail;
3097 if (nla_put(skb,
3098 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
3099 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
3100 nla_put_u32(skb,
3101 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
3102 pData->sigRssiResult[i].channel) ||
3103 nla_put_u32(skb,
3104 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
3105 pData->sigRssiResult[i].numRssi) ||
3106 nla_put(skb,
3107 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
3108 sizeof(s32) * pData->sigRssiResult[i].numRssi,
3109 pData->sigRssiResult[i].rssi))
3110 goto fail;
3111 nla_nest_end(skb, ap);
3112 }
3113 nla_nest_end(skb, aps);
3114 if (nla_put_u8(skb,
3115 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3116 pData->moreData))
3117 goto fail;
3118 }
3119 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303120 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303121 return;
3122fail:
3123 kfree_skb(skb);
3124 return;
3125}
3126
3127static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3128 void *pMsg)
3129{
3130 struct sk_buff *skb;
3131 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3132 tpSirWifiFullScanResultEvent pData =
3133 (tpSirWifiFullScanResultEvent) (pMsg);
3134
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303135 ENTER();
3136
3137 if (wlan_hdd_validate_context(pHddCtx)) {
3138 return;
3139 }
3140 if (!pMsg)
3141 {
3142 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303143 return;
3144 }
3145
3146 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303147#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3148 NULL,
3149#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303150 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3151 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3152 GFP_KERNEL);
3153
3154 if (!skb) {
3155 hddLog(VOS_TRACE_LEVEL_ERROR,
3156 FL("cfg80211_vendor_event_alloc failed"));
3157 return;
3158 }
3159
3160 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3161 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3162 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3163 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3164 "Ssid (%s)"
3165 "Bssid (" MAC_ADDRESS_STR ")"
3166 "Channel (%u)"
3167 "Rssi (%d)"
3168 "RTT (%u)"
3169 "RTT_SD (%u)"),
3170 pData->ap.ts,
3171 pData->ap.ssid,
3172 MAC_ADDR_ARRAY(pData->ap.bssid),
3173 pData->ap.channel,
3174 pData->ap.rssi,
3175 pData->ap.rtt,
3176 pData->ap.rtt_sd);
3177 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3178 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3179 pData->requestId) ||
3180 nla_put_u64(skb,
3181 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3182 pData->ap.ts) ||
3183 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3184 sizeof(pData->ap.ssid),
3185 pData->ap.ssid) ||
3186 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3187 WNI_CFG_BSSID_LEN,
3188 pData->ap.bssid) ||
3189 nla_put_u32(skb,
3190 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3191 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303192 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303193 pData->ap.rssi) ||
3194 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3195 pData->ap.rtt) ||
3196 nla_put_u32(skb,
3197 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3198 pData->ap.rtt_sd) ||
3199 nla_put_u16(skb,
3200 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3201 pData->ap.beaconPeriod) ||
3202 nla_put_u16(skb,
3203 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3204 pData->ap.capability) ||
3205 nla_put_u32(skb,
3206 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3207 pData->ieLength))
3208 {
3209 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3210 goto nla_put_failure;
3211 }
3212 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3213 pData->ieLength,
3214 pData->ie))
3215 {
3216 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3217 goto nla_put_failure;
3218 }
3219
3220 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303221 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303222 return;
3223
3224nla_put_failure:
3225 kfree_skb(skb);
3226 return;
3227}
3228
3229static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3230 void *pMsg)
3231{
3232 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3233 struct sk_buff *skb = NULL;
3234 tpSirEXTScanResultsAvailableIndParams pData =
3235 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3236
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303237 ENTER();
3238
3239 if (wlan_hdd_validate_context(pHddCtx)){
3240 return;
3241 }
3242 if (!pMsg)
3243 {
3244 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303245 return;
3246 }
3247
3248 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303249#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3250 NULL,
3251#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303252 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3253 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3254 GFP_KERNEL);
3255
3256 if (!skb) {
3257 hddLog(VOS_TRACE_LEVEL_ERROR,
3258 FL("cfg80211_vendor_event_alloc failed"));
3259 return;
3260 }
3261
3262 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3263 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3264 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3265 pData->numResultsAvailable);
3266 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3267 pData->requestId) ||
3268 nla_put_u32(skb,
3269 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3270 pData->numResultsAvailable)) {
3271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3272 goto nla_put_failure;
3273 }
3274
3275 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303276 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303277 return;
3278
3279nla_put_failure:
3280 kfree_skb(skb);
3281 return;
3282}
3283
3284static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3285{
3286 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3287 struct sk_buff *skb = NULL;
3288 tpSirEXTScanProgressIndParams pData =
3289 (tpSirEXTScanProgressIndParams) pMsg;
3290
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303291 ENTER();
3292
3293 if (wlan_hdd_validate_context(pHddCtx)){
3294 return;
3295 }
3296 if (!pMsg)
3297 {
3298 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303299 return;
3300 }
3301
3302 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303303#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3304 NULL,
3305#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303306 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3307 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3308 GFP_KERNEL);
3309
3310 if (!skb) {
3311 hddLog(VOS_TRACE_LEVEL_ERROR,
3312 FL("cfg80211_vendor_event_alloc failed"));
3313 return;
3314 }
3315 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3316 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3317 pData->extScanEventType);
3318 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3319 pData->status);
3320
3321 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3322 pData->extScanEventType) ||
3323 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303324 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3325 pData->requestId) ||
3326 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303327 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3328 pData->status)) {
3329 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3330 goto nla_put_failure;
3331 }
3332
3333 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303334 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303335 return;
3336
3337nla_put_failure:
3338 kfree_skb(skb);
3339 return;
3340}
3341
3342void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3343 void *pMsg)
3344{
3345 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3346
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303347 ENTER();
3348
Dino Mycle6fb96c12014-06-10 11:52:40 +05303349 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303350 return;
3351 }
3352
3353 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3354
3355
3356 switch(evType) {
3357 case SIR_HAL_EXTSCAN_START_RSP:
3358 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3359 break;
3360
3361 case SIR_HAL_EXTSCAN_STOP_RSP:
3362 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3363 break;
3364 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3365 /* There is no need to send this response to upper layer
3366 Just log the message */
3367 hddLog(VOS_TRACE_LEVEL_INFO,
3368 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3369 break;
3370 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3371 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3372 break;
3373
3374 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3375 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3376 break;
3377
3378 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
3379 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
3380 break;
3381
3382 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
3383 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
3384 break;
3385 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
3386 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
3387 break;
3388 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3389 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3390 break;
3391 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3392 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3393 break;
3394 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3395 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3396 break;
3397 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3398 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3399 break;
3400 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
3401 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
3402 break;
3403 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3404 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3405 break;
3406 default:
3407 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3408 break;
3409 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303410 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303411}
3412
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303413static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3414 struct wireless_dev *wdev,
3415 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303416{
Dino Myclee8843b32014-07-04 14:21:45 +05303417 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303418 struct net_device *dev = wdev->netdev;
3419 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3420 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3421 struct nlattr
3422 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3423 eHalStatus status;
3424
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303425 ENTER();
3426
Dino Mycle6fb96c12014-06-10 11:52:40 +05303427 status = wlan_hdd_validate_context(pHddCtx);
3428 if (0 != status)
3429 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303430 return -EINVAL;
3431 }
Dino Myclee8843b32014-07-04 14:21:45 +05303432 /* check the EXTScan Capability */
3433 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3434 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3435 {
3436 hddLog(VOS_TRACE_LEVEL_ERROR,
3437 FL("EXTScan not enabled/supported by Firmware"));
3438 return -EINVAL;
3439 }
3440
Dino Mycle6fb96c12014-06-10 11:52:40 +05303441 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3442 data, dataLen,
3443 wlan_hdd_extscan_config_policy)) {
3444 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3445 return -EINVAL;
3446 }
3447
3448 /* Parse and fetch request Id */
3449 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3450 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3451 return -EINVAL;
3452 }
3453
Dino Mycle6fb96c12014-06-10 11:52:40 +05303454
Dino Myclee8843b32014-07-04 14:21:45 +05303455 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303456 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303457 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303458
Dino Myclee8843b32014-07-04 14:21:45 +05303459 reqMsg.sessionId = pAdapter->sessionId;
3460 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303461
Dino Myclee8843b32014-07-04 14:21:45 +05303462 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303463 if (!HAL_STATUS_SUCCESS(status)) {
3464 hddLog(VOS_TRACE_LEVEL_ERROR,
3465 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303466 return -EINVAL;
3467 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303468 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303469 return 0;
3470}
3471
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303472static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3473 struct wireless_dev *wdev,
3474 const void *data, int dataLen)
3475{
3476 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303477
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303478 vos_ssr_protect(__func__);
3479 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3480 vos_ssr_unprotect(__func__);
3481
3482 return ret;
3483}
3484
3485static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3486 struct wireless_dev *wdev,
3487 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303488{
Dino Myclee8843b32014-07-04 14:21:45 +05303489 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303490 struct net_device *dev = wdev->netdev;
3491 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3492 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3493 struct nlattr
3494 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3495 eHalStatus status;
3496
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303497 ENTER();
3498
Dino Mycle6fb96c12014-06-10 11:52:40 +05303499 status = wlan_hdd_validate_context(pHddCtx);
3500 if (0 != status)
3501 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303502 return -EINVAL;
3503 }
Dino Myclee8843b32014-07-04 14:21:45 +05303504 /* check the EXTScan Capability */
3505 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3506 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3507 {
3508 hddLog(VOS_TRACE_LEVEL_ERROR,
3509 FL("EXTScan not enabled/supported by Firmware"));
3510 return -EINVAL;
3511 }
3512
Dino Mycle6fb96c12014-06-10 11:52:40 +05303513 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3514 data, dataLen,
3515 wlan_hdd_extscan_config_policy)) {
3516 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3517 return -EINVAL;
3518 }
3519 /* Parse and fetch request Id */
3520 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3521 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3522 return -EINVAL;
3523 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303524
Dino Myclee8843b32014-07-04 14:21:45 +05303525 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303526 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3527
Dino Myclee8843b32014-07-04 14:21:45 +05303528 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303529
Dino Myclee8843b32014-07-04 14:21:45 +05303530 reqMsg.sessionId = pAdapter->sessionId;
3531 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303532
3533 /* Parse and fetch flush parameter */
3534 if (!tb
3535 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3536 {
3537 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3538 goto failed;
3539 }
Dino Myclee8843b32014-07-04 14:21:45 +05303540 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303541 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3542
Dino Myclee8843b32014-07-04 14:21:45 +05303543 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303544
Dino Myclee8843b32014-07-04 14:21:45 +05303545 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303546 if (!HAL_STATUS_SUCCESS(status)) {
3547 hddLog(VOS_TRACE_LEVEL_ERROR,
3548 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303549 return -EINVAL;
3550 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303551 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303552 return 0;
3553
3554failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303555 return -EINVAL;
3556}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303557static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3558 struct wireless_dev *wdev,
3559 const void *data, int dataLen)
3560{
3561 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303562
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303563 vos_ssr_protect(__func__);
3564 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3565 vos_ssr_unprotect(__func__);
3566
3567 return ret;
3568}
3569
3570static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303571 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303572 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303573{
3574 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3575 struct net_device *dev = wdev->netdev;
3576 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3577 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3578 struct nlattr
3579 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3580 struct nlattr
3581 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3582 struct nlattr *apTh;
3583 eHalStatus status;
3584 tANI_U8 i = 0;
3585 int rem;
3586
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303587 ENTER();
3588
Dino Mycle6fb96c12014-06-10 11:52:40 +05303589 status = wlan_hdd_validate_context(pHddCtx);
3590 if (0 != status)
3591 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303592 return -EINVAL;
3593 }
Dino Myclee8843b32014-07-04 14:21:45 +05303594 /* check the EXTScan Capability */
3595 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3596 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3597 {
3598 hddLog(VOS_TRACE_LEVEL_ERROR,
3599 FL("EXTScan not enabled/supported by Firmware"));
3600 return -EINVAL;
3601 }
3602
Dino Mycle6fb96c12014-06-10 11:52:40 +05303603 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3604 data, dataLen,
3605 wlan_hdd_extscan_config_policy)) {
3606 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3607 return -EINVAL;
3608 }
3609
3610 /* Parse and fetch request Id */
3611 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3612 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3613 return -EINVAL;
3614 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303615 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3616 vos_mem_malloc(sizeof(*pReqMsg));
3617 if (!pReqMsg) {
3618 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3619 return -ENOMEM;
3620 }
3621
Dino Myclee8843b32014-07-04 14:21:45 +05303622
Dino Mycle6fb96c12014-06-10 11:52:40 +05303623 pReqMsg->requestId = nla_get_u32(
3624 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3625 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3626
3627 /* Parse and fetch number of APs */
3628 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3629 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3630 goto fail;
3631 }
3632
3633 pReqMsg->sessionId = pAdapter->sessionId;
3634 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3635
3636 pReqMsg->numAp = nla_get_u32(
3637 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3638 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3639
3640 nla_for_each_nested(apTh,
3641 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3642 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3643 nla_data(apTh), nla_len(apTh),
3644 NULL)) {
3645 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3646 goto fail;
3647 }
3648
3649 /* Parse and fetch MAC address */
3650 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3651 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3652 goto fail;
3653 }
3654 memcpy(pReqMsg->ap[i].bssid, nla_data(
3655 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3656 sizeof(tSirMacAddr));
3657 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3658
3659 /* Parse and fetch low RSSI */
3660 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3661 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3662 goto fail;
3663 }
3664 pReqMsg->ap[i].low = nla_get_s32(
3665 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3666 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3667
3668 /* Parse and fetch high RSSI */
3669 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3670 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3671 goto fail;
3672 }
3673 pReqMsg->ap[i].high = nla_get_s32(
3674 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3675 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3676 pReqMsg->ap[i].high);
3677
3678 /* Parse and fetch channel */
3679 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3680 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3681 goto fail;
3682 }
3683 pReqMsg->ap[i].channel = nla_get_u32(
3684 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3685 hddLog(VOS_TRACE_LEVEL_INFO,
3686 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3687 i++;
3688 }
3689 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3690 if (!HAL_STATUS_SUCCESS(status)) {
3691 hddLog(VOS_TRACE_LEVEL_ERROR,
3692 FL("sme_SetBssHotlist failed(err=%d)"), status);
3693 vos_mem_free(pReqMsg);
3694 return -EINVAL;
3695 }
3696
Dino Myclee8843b32014-07-04 14:21:45 +05303697 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303698 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303699 return 0;
3700
3701fail:
3702 vos_mem_free(pReqMsg);
3703 return -EINVAL;
3704}
3705
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303706static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3707 struct wireless_dev *wdev,
3708 const void *data, int dataLen)
3709{
3710 int ret = 0;
3711
3712 vos_ssr_protect(__func__);
3713 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3714 dataLen);
3715 vos_ssr_unprotect(__func__);
3716
3717 return ret;
3718}
3719
3720static int __wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303721 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303722 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303723{
3724 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3725 struct net_device *dev = wdev->netdev;
3726 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3727 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3728 struct nlattr
3729 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3730 struct nlattr
3731 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3732 struct nlattr *apTh;
3733 eHalStatus status;
3734 int i = 0;
3735 int rem;
3736
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303737 ENTER();
3738
Dino Mycle6fb96c12014-06-10 11:52:40 +05303739 status = wlan_hdd_validate_context(pHddCtx);
3740 if (0 != status)
3741 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303742 return -EINVAL;
3743 }
Dino Myclee8843b32014-07-04 14:21:45 +05303744 /* check the EXTScan Capability */
3745 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3746 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3747 {
3748 hddLog(VOS_TRACE_LEVEL_ERROR,
3749 FL("EXTScan not enabled/supported by Firmware"));
3750 return -EINVAL;
3751 }
3752
Dino Mycle6fb96c12014-06-10 11:52:40 +05303753 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3754 data, dataLen,
3755 wlan_hdd_extscan_config_policy)) {
3756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3757 return -EINVAL;
3758 }
3759
3760 /* Parse and fetch request Id */
3761 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3762 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3763 return -EINVAL;
3764 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303765 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303766 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303767 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3769 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303770 }
3771
Dino Myclee8843b32014-07-04 14:21:45 +05303772
3773
Dino Mycle6fb96c12014-06-10 11:52:40 +05303774 pReqMsg->requestId = nla_get_u32(
3775 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3776 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3777
3778 /* Parse and fetch RSSI sample size */
3779 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3780 {
3781 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3782 goto fail;
3783 }
3784 pReqMsg->rssiSampleSize = nla_get_u32(
3785 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3786 hddLog(VOS_TRACE_LEVEL_INFO,
3787 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3788
3789 /* Parse and fetch lost AP sample size */
3790 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3791 {
3792 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3793 goto fail;
3794 }
3795 pReqMsg->lostApSampleSize = nla_get_u32(
3796 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3797 hddLog(VOS_TRACE_LEVEL_INFO,
3798 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3799 /* Parse and fetch minimum Breaching */
3800 if (!tb
3801 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3802 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3803 goto fail;
3804 }
3805 pReqMsg->minBreaching = nla_get_u32(
3806 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3807 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3808
3809 /* Parse and fetch number of APs */
3810 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3812 goto fail;
3813 }
3814 pReqMsg->numAp = nla_get_u32(
3815 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3816 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3817
3818 pReqMsg->sessionId = pAdapter->sessionId;
3819 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3820
3821 nla_for_each_nested(apTh,
3822 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3823 if(nla_parse(tb2,
3824 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3825 nla_data(apTh), nla_len(apTh),
3826 NULL)) {
3827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3828 goto fail;
3829 }
3830
3831 /* Parse and fetch MAC address */
3832 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3833 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3834 goto fail;
3835 }
3836 memcpy(pReqMsg->ap[i].bssid, nla_data(
3837 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3838 sizeof(tSirMacAddr));
3839
3840 /* Parse and fetch low RSSI */
3841 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3842 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3843 goto fail;
3844 }
3845 pReqMsg->ap[i].low = nla_get_s32(
3846 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3847 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3848
3849 /* Parse and fetch high RSSI */
3850 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3851 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3852 goto fail;
3853 }
3854 pReqMsg->ap[i].high = nla_get_s32(
3855 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3856 hddLog(VOS_TRACE_LEVEL_INFO,
3857 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3858
3859 /* Parse and fetch channel */
3860 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3861 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3862 goto fail;
3863 }
3864 pReqMsg->ap[i].channel = nla_get_u32(
3865 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3866 hddLog(VOS_TRACE_LEVEL_INFO,
3867 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3868 i++;
3869 }
3870
3871 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3872 if (!HAL_STATUS_SUCCESS(status)) {
3873 hddLog(VOS_TRACE_LEVEL_ERROR,
3874 FL("sme_SetSignificantChange failed(err=%d)"), status);
3875 vos_mem_free(pReqMsg);
3876 return -EINVAL;
3877 }
Dino Myclee8843b32014-07-04 14:21:45 +05303878 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303879 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303880 return 0;
3881
3882fail:
3883 vos_mem_free(pReqMsg);
3884 return -EINVAL;
3885}
3886
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303887static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3888 struct wireless_dev *wdev,
3889 const void *data, int dataLen)
3890{
3891 int ret = 0;
3892
3893 vos_ssr_protect(__func__);
3894 ret = __wlan_hdd_cfg80211_extscan_set_significant_change(wiphy, wdev, data,
3895 dataLen);
3896 vos_ssr_unprotect(__func__);
3897
3898 return ret;
3899}
3900
3901static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303902 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303903 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303904{
3905 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3906 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3907 tANI_U8 numChannels = 0;
3908 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3909 tANI_U32 requestId;
3910 tWifiBand wifiBand;
3911 eHalStatus status;
3912 struct sk_buff *replySkb;
3913 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303914 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303915
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303916 ENTER();
3917
Dino Mycle6fb96c12014-06-10 11:52:40 +05303918 status = wlan_hdd_validate_context(pHddCtx);
3919 if (0 != status)
3920 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303921 return -EINVAL;
3922 }
Dino Myclee8843b32014-07-04 14:21:45 +05303923
Dino Mycle6fb96c12014-06-10 11:52:40 +05303924 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3925 data, dataLen,
3926 wlan_hdd_extscan_config_policy)) {
3927 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3928 return -EINVAL;
3929 }
3930
3931 /* Parse and fetch request Id */
3932 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3933 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3934 return -EINVAL;
3935 }
3936 requestId = nla_get_u32(
3937 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3938 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3939
3940 /* Parse and fetch wifi band */
3941 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3942 {
3943 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3944 return -EINVAL;
3945 }
3946 wifiBand = nla_get_u32(
3947 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3948 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3949
3950 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3951 wifiBand, ChannelList,
3952 &numChannels);
3953 if (eHAL_STATUS_SUCCESS != status) {
3954 hddLog(VOS_TRACE_LEVEL_ERROR,
3955 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3956 return -EINVAL;
3957 }
3958 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3959 for (i = 0; i < numChannels; i++)
3960 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3961
3962 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3963 sizeof(u32) * numChannels +
3964 NLMSG_HDRLEN);
3965
3966 if (!replySkb) {
3967 hddLog(VOS_TRACE_LEVEL_ERROR,
3968 FL("valid channels: buffer alloc fail"));
3969 return -EINVAL;
3970 }
3971 if (nla_put_u32(replySkb,
3972 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3973 numChannels) ||
3974 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3975 sizeof(u32) * numChannels, ChannelList)) {
3976
3977 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3978 kfree_skb(replySkb);
3979 return -EINVAL;
3980 }
3981
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303982 ret = cfg80211_vendor_cmd_reply(replySkb);
3983
3984 EXIT();
3985 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303986}
3987
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303988static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3989 struct wireless_dev *wdev,
3990 const void *data, int dataLen)
3991{
3992 int ret = 0;
3993
3994 vos_ssr_protect(__func__);
3995 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
3996 dataLen);
3997 vos_ssr_unprotect(__func__);
3998
3999 return ret;
4000}
4001
4002static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304003 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304004 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304005{
Dino Myclee8843b32014-07-04 14:21:45 +05304006 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304007 struct net_device *dev = wdev->netdev;
4008 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4009 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4010 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4011 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4012 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4013 struct nlattr *buckets;
4014 struct nlattr *channels;
4015 int rem1;
4016 int rem2;
4017 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304018 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304019
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304020 ENTER();
4021
Dino Mycle6fb96c12014-06-10 11:52:40 +05304022 status = wlan_hdd_validate_context(pHddCtx);
4023 if (0 != status)
4024 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304025 return -EINVAL;
4026 }
Dino Myclee8843b32014-07-04 14:21:45 +05304027 /* check the EXTScan Capability */
4028 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4029 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4030 {
4031 hddLog(VOS_TRACE_LEVEL_ERROR,
4032 FL("EXTScan not enabled/supported by Firmware"));
4033 return -EINVAL;
4034 }
4035
Dino Mycle6fb96c12014-06-10 11:52:40 +05304036 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4037 data, dataLen,
4038 wlan_hdd_extscan_config_policy)) {
4039 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4040 return -EINVAL;
4041 }
4042
4043 /* Parse and fetch request Id */
4044 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4045 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4046 return -EINVAL;
4047 }
4048
Dino Myclee8843b32014-07-04 14:21:45 +05304049 pReqMsg = (tpSirEXTScanStartReqParams)
4050 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304051 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304052 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4053 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304054 }
4055
4056 pReqMsg->requestId = nla_get_u32(
4057 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4058 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4059
4060 pReqMsg->sessionId = pAdapter->sessionId;
4061 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4062
4063 /* Parse and fetch base period */
4064 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
4065 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4066 goto fail;
4067 }
4068 pReqMsg->basePeriod = nla_get_u32(
4069 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
4070 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4071 pReqMsg->basePeriod);
4072
4073 /* Parse and fetch max AP per scan */
4074 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
4075 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4076 goto fail;
4077 }
4078 pReqMsg->maxAPperScan = nla_get_u32(
4079 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
4080 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4081 pReqMsg->maxAPperScan);
4082
4083 /* Parse and fetch report threshold */
4084 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
4085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4086 goto fail;
4087 }
4088 pReqMsg->reportThreshold = nla_get_u8(
4089 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
4090 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
4091 pReqMsg->reportThreshold);
4092
4093 /* Parse and fetch number of buckets */
4094 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
4095 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4096 goto fail;
4097 }
4098 pReqMsg->numBuckets = nla_get_u8(
4099 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
4100 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4101 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4102 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4103 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4104 }
4105 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4106 pReqMsg->numBuckets);
4107 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4108 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4109 goto fail;
4110 }
4111
4112 nla_for_each_nested(buckets,
4113 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4114 if(nla_parse(bucket,
4115 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4116 nla_data(buckets), nla_len(buckets), NULL)) { //policy
4117 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4118 goto fail;
4119 }
4120
4121 /* Parse and fetch bucket spec */
4122 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4123 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
4124 goto fail;
4125 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304126
4127 pReqMsg->buckets[index].bucket = nla_get_u8(
4128 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4129
4130 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
4131 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304132
4133 /* Parse and fetch wifi band */
4134 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4135 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4136 goto fail;
4137 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304138 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304139 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4140 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304141 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304142
4143 /* Parse and fetch period */
4144 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4145 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
4146 goto fail;
4147 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304148 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304149 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4150 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304151 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304152
4153 /* Parse and fetch report events */
4154 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4155 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
4156 goto fail;
4157 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304158 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304159 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4160 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304161 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304162
4163 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304164 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
4165 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304166 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
4167 goto fail;
4168 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304169 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304170 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4171 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304172 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304173
4174 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4175 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
4176 goto fail;
4177 }
4178
4179 j = 0;
4180 nla_for_each_nested(channels,
4181 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4182 if(nla_parse(channel,
4183 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4184 nla_data(channels), nla_len(channels),
4185 NULL)) { //wlan_hdd_extscan_config_policy here
4186 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4187 goto fail;
4188 }
4189
4190 /* Parse and fetch channel */
4191 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4192 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4193 goto fail;
4194 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304195 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304196 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4197 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304198 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304199
4200 /* Parse and fetch dwell time */
4201 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4202 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
4203 goto fail;
4204 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304205 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304206 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4207 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304208 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304209
4210 /* Parse and fetch channel spec passive */
4211 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4212 hddLog(VOS_TRACE_LEVEL_ERROR,
4213 FL("attr channel spec passive failed"));
4214 goto fail;
4215 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304216 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304217 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4218 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304219 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304220 j++;
4221 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304222 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304223 }
4224 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4225 if (!HAL_STATUS_SUCCESS(status)) {
4226 hddLog(VOS_TRACE_LEVEL_ERROR,
4227 FL("sme_EXTScanStart failed(err=%d)"), status);
4228 vos_mem_free(pReqMsg);
4229 return -EINVAL;
4230 }
4231
Dino Myclee8843b32014-07-04 14:21:45 +05304232 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304233 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304234 return 0;
4235
4236fail:
4237 vos_mem_free(pReqMsg);
4238 return -EINVAL;
4239}
4240
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304241static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4242 struct wireless_dev *wdev,
4243 const void *data, int dataLen)
4244{
4245 int ret = 0;
4246
4247 vos_ssr_protect(__func__);
4248 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4249 vos_ssr_unprotect(__func__);
4250
4251 return ret;
4252}
4253
4254static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304255 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304256 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304257{
Dino Myclee8843b32014-07-04 14:21:45 +05304258 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304259 struct net_device *dev = wdev->netdev;
4260 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4261 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4262 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4263 eHalStatus status;
4264
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304265 ENTER();
4266
Dino Mycle6fb96c12014-06-10 11:52:40 +05304267 status = wlan_hdd_validate_context(pHddCtx);
4268 if (0 != status)
4269 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304270 return -EINVAL;
4271 }
Dino Myclee8843b32014-07-04 14:21:45 +05304272 /* check the EXTScan Capability */
4273 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4274 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4275 {
4276 hddLog(VOS_TRACE_LEVEL_ERROR,
4277 FL("EXTScan not enabled/supported by Firmware"));
4278 return -EINVAL;
4279 }
4280
Dino Mycle6fb96c12014-06-10 11:52:40 +05304281 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4282 data, dataLen,
4283 wlan_hdd_extscan_config_policy)) {
4284 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4285 return -EINVAL;
4286 }
4287
4288 /* Parse and fetch request Id */
4289 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4290 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4291 return -EINVAL;
4292 }
4293
Dino Myclee8843b32014-07-04 14:21:45 +05304294 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304295 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304296 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304297
Dino Myclee8843b32014-07-04 14:21:45 +05304298 reqMsg.sessionId = pAdapter->sessionId;
4299 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304300
Dino Myclee8843b32014-07-04 14:21:45 +05304301 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304302 if (!HAL_STATUS_SUCCESS(status)) {
4303 hddLog(VOS_TRACE_LEVEL_ERROR,
4304 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304305 return -EINVAL;
4306 }
4307
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304308 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304309 return 0;
4310}
4311
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304312static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4313 struct wireless_dev *wdev,
4314 const void *data, int dataLen)
4315{
4316 int ret = 0;
4317
4318 vos_ssr_protect(__func__);
4319 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4320 vos_ssr_unprotect(__func__);
4321
4322 return ret;
4323}
4324
4325static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304326 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304327 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304328{
Dino Myclee8843b32014-07-04 14:21:45 +05304329 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304330 struct net_device *dev = wdev->netdev;
4331 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4332 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4333 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4334 eHalStatus status;
4335
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304336 ENTER();
4337
Dino Mycle6fb96c12014-06-10 11:52:40 +05304338 status = wlan_hdd_validate_context(pHddCtx);
4339 if (0 != status)
4340 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304341 return -EINVAL;
4342 }
Dino Myclee8843b32014-07-04 14:21:45 +05304343 /* check the EXTScan Capability */
4344 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4345 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4346 {
4347 hddLog(VOS_TRACE_LEVEL_ERROR,
4348 FL("EXTScan not enabled/supported by Firmware"));
4349 return -EINVAL;
4350 }
4351
Dino Mycle6fb96c12014-06-10 11:52:40 +05304352 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4353 data, dataLen,
4354 wlan_hdd_extscan_config_policy)) {
4355 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4356 return -EINVAL;
4357 }
4358
4359 /* Parse and fetch request Id */
4360 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4361 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4362 return -EINVAL;
4363 }
4364
Dino Myclee8843b32014-07-04 14:21:45 +05304365 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304366 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304367 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304368
Dino Myclee8843b32014-07-04 14:21:45 +05304369 reqMsg.sessionId = pAdapter->sessionId;
4370 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304371
Dino Myclee8843b32014-07-04 14:21:45 +05304372 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304373 if (!HAL_STATUS_SUCCESS(status)) {
4374 hddLog(VOS_TRACE_LEVEL_ERROR,
4375 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304376 return -EINVAL;
4377 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304378 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304379 return 0;
4380}
4381
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304382static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4383 struct wireless_dev *wdev,
4384 const void *data, int dataLen)
4385{
4386 int ret = 0;
4387
4388 vos_ssr_protect(__func__);
4389 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4390 vos_ssr_unprotect(__func__);
4391
4392 return ret;
4393}
4394
4395static int __wlan_hdd_cfg80211_extscan_reset_significant_change(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304396 struct wiphy *wiphy,
4397 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304398 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304399{
Dino Myclee8843b32014-07-04 14:21:45 +05304400 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304401 struct net_device *dev = wdev->netdev;
4402 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4403 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4404 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4405 eHalStatus status;
4406
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304407 ENTER();
4408
Dino Mycle6fb96c12014-06-10 11:52:40 +05304409 status = wlan_hdd_validate_context(pHddCtx);
4410 if (0 != status)
4411 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304412 return -EINVAL;
4413 }
Dino Myclee8843b32014-07-04 14:21:45 +05304414 /* check the EXTScan Capability */
4415 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4416 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4417 {
4418 hddLog(VOS_TRACE_LEVEL_ERROR,
4419 FL("EXTScan not enabled/supported by Firmware"));
4420 return -EINVAL;
4421 }
4422
Dino Mycle6fb96c12014-06-10 11:52:40 +05304423 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4424 data, dataLen,
4425 wlan_hdd_extscan_config_policy)) {
4426 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4427 return -EINVAL;
4428 }
4429
4430 /* Parse and fetch request Id */
4431 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4432 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4433 return -EINVAL;
4434 }
4435
Dino Mycle6fb96c12014-06-10 11:52:40 +05304436
Dino Myclee8843b32014-07-04 14:21:45 +05304437 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304438 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304439 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304440
Dino Myclee8843b32014-07-04 14:21:45 +05304441 reqMsg.sessionId = pAdapter->sessionId;
4442 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304443
Dino Myclee8843b32014-07-04 14:21:45 +05304444 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304445 if (!HAL_STATUS_SUCCESS(status)) {
4446 hddLog(VOS_TRACE_LEVEL_ERROR,
4447 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304448 return -EINVAL;
4449 }
4450
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304451 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304452 return 0;
4453}
4454
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304455static int wlan_hdd_cfg80211_extscan_reset_significant_change(
4456 struct wiphy *wiphy,
4457 struct wireless_dev *wdev,
4458 const void *data, int dataLen)
4459{
4460 int ret = 0;
4461
4462 vos_ssr_protect(__func__);
4463 ret = __wlan_hdd_cfg80211_extscan_reset_significant_change(wiphy,
4464 wdev, data,
4465 dataLen);
4466 vos_ssr_unprotect(__func__);
4467
4468 return ret;
4469}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304470#endif /* WLAN_FEATURE_EXTSCAN */
4471
Atul Mittal115287b2014-07-08 13:26:33 +05304472/*EXT TDLS*/
4473static const struct nla_policy
4474wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4475{
4476 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4477 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4478 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4479 {.type = NLA_S32 },
4480 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4481 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4482
4483};
4484
4485static const struct nla_policy
4486wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4487{
4488 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4489
4490};
4491
4492static const struct nla_policy
4493wlan_hdd_tdls_config_state_change_policy[
4494 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4495{
4496 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4497 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4498 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304499 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4500 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4501 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304502
4503};
4504
4505static const struct nla_policy
4506wlan_hdd_tdls_config_get_status_policy[
4507 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4508{
4509 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4510 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4511 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304512 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4513 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4514 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304515
4516};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304517
4518static const struct nla_policy
4519wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4520{
4521 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4522};
4523
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304524static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304525 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304526 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304527 int data_len)
4528{
4529
4530 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4531 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4532
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304533 ENTER();
4534
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304535 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304536 return -EINVAL;
4537 }
4538 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
4539 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN disabled in ini"));
4540 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304541 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304542 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
4543 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN not supported by FW"));
4544 return -ENOTSUPP;
4545 }
4546
4547 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4548 data, data_len, wlan_hdd_mac_config)) {
4549 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4550 return -EINVAL;
4551 }
4552
4553 /* Parse and fetch mac address */
4554 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4555 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4556 return -EINVAL;
4557 }
4558
4559 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4560 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4561 VOS_MAC_ADDR_LAST_3_BYTES);
4562
Siddharth Bhal76972212014-10-15 16:22:51 +05304563 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4564
4565 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304566 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4567 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304568 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4569 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4570 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4571 {
4572 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4573 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4574 VOS_MAC_ADDRESS_LEN);
4575 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304576 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304577
Siddharth Bhal76972212014-10-15 16:22:51 +05304578 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
4579 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304580 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4581 }
4582
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304583 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304584 return 0;
4585}
4586
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304587static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
4588 struct wireless_dev *wdev,
4589 const void *data,
4590 int data_len)
4591{
4592 int ret = 0;
4593
4594 vos_ssr_protect(__func__);
4595 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
4596 vos_ssr_unprotect(__func__);
4597
4598 return ret;
4599}
4600
4601static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304602 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304603 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304604 int data_len)
4605{
4606 u8 peer[6] = {0};
4607 struct net_device *dev = wdev->netdev;
4608 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4609 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4610 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4611 eHalStatus ret;
4612 tANI_S32 state;
4613 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304614 tANI_S32 global_operating_class = 0;
4615 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304616 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304617 int retVal;
4618
4619 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304620
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304621 if (!pAdapter) {
4622 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4623 return -EINVAL;
4624 }
4625
Atul Mittal115287b2014-07-08 13:26:33 +05304626 ret = wlan_hdd_validate_context(pHddCtx);
4627 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304628 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304629 return -EINVAL;
4630 }
4631 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304632 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304633 return -ENOTSUPP;
4634 }
4635 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4636 data, data_len,
4637 wlan_hdd_tdls_config_get_status_policy)) {
4638 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4639 return -EINVAL;
4640 }
4641
4642 /* Parse and fetch mac address */
4643 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4644 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4645 return -EINVAL;
4646 }
4647
4648 memcpy(peer, nla_data(
4649 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4650 sizeof(peer));
4651 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4652
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05304653 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05304654
Atul Mittal115287b2014-07-08 13:26:33 +05304655 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304656 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304657 NLMSG_HDRLEN);
4658
4659 if (!skb) {
4660 hddLog(VOS_TRACE_LEVEL_ERROR,
4661 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4662 return -EINVAL;
4663 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304664 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05304665 reason,
4666 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304667 global_operating_class,
4668 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304669 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304670 if (nla_put_s32(skb,
4671 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4672 state) ||
4673 nla_put_s32(skb,
4674 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4675 reason) ||
4676 nla_put_s32(skb,
4677 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4678 global_operating_class) ||
4679 nla_put_s32(skb,
4680 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4681 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304682
4683 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4684 goto nla_put_failure;
4685 }
4686
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304687 retVal = cfg80211_vendor_cmd_reply(skb);
4688 EXIT();
4689 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05304690
4691nla_put_failure:
4692 kfree_skb(skb);
4693 return -EINVAL;
4694}
4695
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304696static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4697 struct wireless_dev *wdev,
4698 const void *data,
4699 int data_len)
4700{
4701 int ret = 0;
4702
4703 vos_ssr_protect(__func__);
4704 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
4705 vos_ssr_unprotect(__func__);
4706
4707 return ret;
4708}
4709
Atul Mittal115287b2014-07-08 13:26:33 +05304710static int wlan_hdd_cfg80211_exttdls_callback(tANI_U8* mac,
4711 tANI_S32 state,
4712 tANI_S32 reason,
4713 void *ctx)
4714{
4715 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05304716 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304717 tANI_S32 global_operating_class = 0;
4718 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304719 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05304720
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304721 ENTER();
4722
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304723 if (!pAdapter) {
4724 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4725 return -EINVAL;
4726 }
4727
4728 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05304729 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304730 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304731 return -EINVAL;
4732 }
4733
4734 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304735 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304736 return -ENOTSUPP;
4737 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304738 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
4739#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4740 NULL,
4741#endif
Atul Mittal115287b2014-07-08 13:26:33 +05304742 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4743 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4744 GFP_KERNEL);
4745
4746 if (!skb) {
4747 hddLog(VOS_TRACE_LEVEL_ERROR,
4748 FL("cfg80211_vendor_event_alloc failed"));
4749 return -EINVAL;
4750 }
4751 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304752 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4753 reason,
4754 state,
4755 global_operating_class,
4756 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304757 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4758 MAC_ADDR_ARRAY(mac));
4759
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304760 if (nla_put(skb,
4761 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4762 VOS_MAC_ADDR_SIZE, mac) ||
4763 nla_put_s32(skb,
4764 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4765 state) ||
4766 nla_put_s32(skb,
4767 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4768 reason) ||
4769 nla_put_s32(skb,
4770 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4771 channel) ||
4772 nla_put_s32(skb,
4773 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4774 global_operating_class)
4775 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304776 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4777 goto nla_put_failure;
4778 }
4779
4780 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304781 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05304782 return (0);
4783
4784nla_put_failure:
4785 kfree_skb(skb);
4786 return -EINVAL;
4787}
4788
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304789static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304790 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304791 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304792 int data_len)
4793{
4794 u8 peer[6] = {0};
4795 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304796 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4797 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4798 eHalStatus status;
4799 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304800 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304801 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304802
4803 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304804
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304805 if (!dev) {
4806 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4807 return -EINVAL;
4808 }
4809
4810 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4811 if (!pAdapter) {
4812 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4813 return -EINVAL;
4814 }
4815
Atul Mittal115287b2014-07-08 13:26:33 +05304816 status = wlan_hdd_validate_context(pHddCtx);
4817 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304818 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304819 return -EINVAL;
4820 }
4821 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304822 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304823 return -ENOTSUPP;
4824 }
4825 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4826 data, data_len,
4827 wlan_hdd_tdls_config_enable_policy)) {
4828 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4829 return -EINVAL;
4830 }
4831
4832 /* Parse and fetch mac address */
4833 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4834 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4835 return -EINVAL;
4836 }
4837
4838 memcpy(peer, nla_data(
4839 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4840 sizeof(peer));
4841 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4842
4843 /* Parse and fetch channel */
4844 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4845 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4846 return -EINVAL;
4847 }
4848 pReqMsg.channel = nla_get_s32(
4849 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4850 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4851
4852 /* Parse and fetch global operating class */
4853 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4854 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4855 return -EINVAL;
4856 }
4857 pReqMsg.global_operating_class = nla_get_s32(
4858 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4859 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4860 pReqMsg.global_operating_class);
4861
4862 /* Parse and fetch latency ms */
4863 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4864 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4865 return -EINVAL;
4866 }
4867 pReqMsg.max_latency_ms = nla_get_s32(
4868 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4869 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4870 pReqMsg.max_latency_ms);
4871
4872 /* Parse and fetch required bandwidth kbps */
4873 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4874 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4875 return -EINVAL;
4876 }
4877
4878 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4879 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4880 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4881 pReqMsg.min_bandwidth_kbps);
4882
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304883 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05304884 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05304885 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304886 wlan_hdd_cfg80211_exttdls_callback);
4887
4888 EXIT();
4889 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304890}
4891
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304892static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4893 struct wireless_dev *wdev,
4894 const void *data,
4895 int data_len)
4896{
4897 int ret = 0;
4898
4899 vos_ssr_protect(__func__);
4900 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
4901 vos_ssr_unprotect(__func__);
4902
4903 return ret;
4904}
4905
4906static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304907 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304908 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304909 int data_len)
4910{
4911 u8 peer[6] = {0};
4912 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304913 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4914 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4915 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304916 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304917 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304918
4919 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304920
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304921 if (!dev) {
4922 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4923 return -EINVAL;
4924 }
4925
4926 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4927 if (!pAdapter) {
4928 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
4929 return -EINVAL;
4930 }
4931
Atul Mittal115287b2014-07-08 13:26:33 +05304932 status = wlan_hdd_validate_context(pHddCtx);
4933 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304934 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304935 return -EINVAL;
4936 }
4937 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304939 return -ENOTSUPP;
4940 }
4941 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4942 data, data_len,
4943 wlan_hdd_tdls_config_disable_policy)) {
4944 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4945 return -EINVAL;
4946 }
4947 /* Parse and fetch mac address */
4948 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4949 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4950 return -EINVAL;
4951 }
4952
4953 memcpy(peer, nla_data(
4954 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4955 sizeof(peer));
4956 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4957
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304958 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
4959
4960 EXIT();
4961 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304962}
4963
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304964static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4965 struct wireless_dev *wdev,
4966 const void *data,
4967 int data_len)
4968{
4969 int ret = 0;
4970
4971 vos_ssr_protect(__func__);
4972 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
4973 vos_ssr_unprotect(__func__);
4974
4975 return ret;
4976}
4977
Dasari Srinivas7875a302014-09-26 17:50:57 +05304978static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304979__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05304980 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304981 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05304982{
4983 struct net_device *dev = wdev->netdev;
4984 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4985 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4986 struct sk_buff *skb = NULL;
4987 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304988 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05304989
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304990 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304991
4992 ret = wlan_hdd_validate_context(pHddCtx);
4993 if (0 != ret)
4994 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304995 return ret;
4996 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05304997 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
4998 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
4999 fset |= WIFI_FEATURE_INFRA;
5000 }
5001
5002 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5003 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5004 fset |= WIFI_FEATURE_INFRA_5G;
5005 }
5006
5007#ifdef WLAN_FEATURE_P2P
5008 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5009 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5010 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5011 fset |= WIFI_FEATURE_P2P;
5012 }
5013#endif
5014
5015 /* Soft-AP is supported currently by default */
5016 fset |= WIFI_FEATURE_SOFT_AP;
5017
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305018 /* HOTSPOT is a supplicant feature, enable it by default */
5019 fset |= WIFI_FEATURE_HOTSPOT;
5020
Dasari Srinivas7875a302014-09-26 17:50:57 +05305021#ifdef WLAN_FEATURE_EXTSCAN
5022 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
5023 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
5024 hddLog(LOG1, FL("EXTScan is supported by firmware"));
5025 fset |= WIFI_FEATURE_EXTSCAN;
5026 }
5027#endif
5028
Dasari Srinivas7875a302014-09-26 17:50:57 +05305029 if (sme_IsFeatureSupportedByFW(NAN)) {
5030 hddLog(LOG1, FL("NAN is supported by firmware"));
5031 fset |= WIFI_FEATURE_NAN;
5032 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305033
5034 /* D2D RTT is not supported currently by default */
5035 if (sme_IsFeatureSupportedByFW(RTT)) {
5036 hddLog(LOG1, FL("RTT is supported by firmware"));
5037 fset |= WIFI_FEATURE_D2AP_RTT;
5038 }
5039
5040#ifdef FEATURE_WLAN_BATCH_SCAN
5041 if (fset & WIFI_FEATURE_EXTSCAN) {
5042 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5043 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5044 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5045 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5046 fset |= WIFI_FEATURE_BATCH_SCAN;
5047 }
5048#endif
5049
5050#ifdef FEATURE_WLAN_SCAN_PNO
5051 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5052 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5053 hddLog(LOG1, FL("PNO is supported by firmware"));
5054 fset |= WIFI_FEATURE_PNO;
5055 }
5056#endif
5057
5058 /* STA+STA is supported currently by default */
5059 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5060
5061#ifdef FEATURE_WLAN_TDLS
5062 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5063 sme_IsFeatureSupportedByFW(TDLS)) {
5064 hddLog(LOG1, FL("TDLS is supported by firmware"));
5065 fset |= WIFI_FEATURE_TDLS;
5066 }
5067
5068 /* TDLS_OFFCHANNEL is not supported currently by default */
5069#endif
5070
5071#ifdef WLAN_AP_STA_CONCURRENCY
5072 /* AP+STA concurrency is supported currently by default */
5073 fset |= WIFI_FEATURE_AP_STA;
5074#endif
5075
5076 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5077 NLMSG_HDRLEN);
5078
5079 if (!skb) {
5080 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5081 return -EINVAL;
5082 }
5083 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5084
5085 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5086 hddLog(LOGE, FL("nla put fail"));
5087 goto nla_put_failure;
5088 }
5089
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305090 ret = cfg80211_vendor_cmd_reply(skb);
5091 EXIT();
5092 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305093
5094nla_put_failure:
5095 kfree_skb(skb);
5096 return -EINVAL;
5097}
5098
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305099static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305100wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5101 struct wireless_dev *wdev,
5102 const void *data, int data_len)
5103{
5104 int ret = 0;
5105
5106 vos_ssr_protect(__func__);
5107 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5108 vos_ssr_unprotect(__func__);
5109
5110 return ret;
5111}
5112
5113static int
5114__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305115 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305116 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305117{
5118 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5119 uint8_t i, feature_sets, max_feature_sets;
5120 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5121 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305122 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5123 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305124
5125 ENTER();
5126
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305127 ret = wlan_hdd_validate_context(pHddCtx);
5128 if (0 != ret)
5129 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305130 return ret;
5131 }
5132
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305133 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5134 data, data_len, NULL)) {
5135 hddLog(LOGE, FL("Invalid ATTR"));
5136 return -EINVAL;
5137 }
5138
5139 /* Parse and fetch max feature set */
5140 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5141 hddLog(LOGE, FL("Attr max feature set size failed"));
5142 return -EINVAL;
5143 }
5144 max_feature_sets = nla_get_u32(
5145 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5146 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5147
5148 /* Fill feature combination matrix */
5149 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305150 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5151 WIFI_FEATURE_P2P;
5152
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305153 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5154 WIFI_FEATURE_SOFT_AP;
5155
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305156 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5157 WIFI_FEATURE_SOFT_AP;
5158
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305159 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5160 WIFI_FEATURE_SOFT_AP |
5161 WIFI_FEATURE_P2P;
5162
5163 /* Add more feature combinations here */
5164
5165 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5166 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5167 hddLog(LOG1, "Feature set matrix");
5168 for (i = 0; i < feature_sets; i++)
5169 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5170
5171 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5172 sizeof(u32) * feature_sets +
5173 NLMSG_HDRLEN);
5174
5175 if (reply_skb) {
5176 if (nla_put_u32(reply_skb,
5177 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5178 feature_sets) ||
5179 nla_put(reply_skb,
5180 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5181 sizeof(u32) * feature_sets, feature_set_matrix)) {
5182 hddLog(LOGE, FL("nla put fail"));
5183 kfree_skb(reply_skb);
5184 return -EINVAL;
5185 }
5186
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305187 ret = cfg80211_vendor_cmd_reply(reply_skb);
5188 EXIT();
5189 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305190 }
5191 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5192 return -ENOMEM;
5193
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305194}
5195
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305196static int
5197wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5198 struct wireless_dev *wdev,
5199 const void *data, int data_len)
5200{
5201 int ret = 0;
5202
5203 vos_ssr_protect(__func__);
5204 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5205 data_len);
5206 vos_ssr_unprotect(__func__);
5207
5208 return ret;
5209}
5210
Agarwal Ashish738843c2014-09-25 12:27:56 +05305211static const struct nla_policy
5212wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5213 +1] =
5214{
5215 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5216};
5217
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305218static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305219 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305220 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305221 int data_len)
5222{
5223 struct net_device *dev = wdev->netdev;
5224 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5225 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5226 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5227 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5228 eHalStatus status;
5229 u32 dfsFlag = 0;
5230
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305231 ENTER();
5232
Agarwal Ashish738843c2014-09-25 12:27:56 +05305233 status = wlan_hdd_validate_context(pHddCtx);
5234 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305235 return -EINVAL;
5236 }
5237 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5238 data, data_len,
5239 wlan_hdd_set_no_dfs_flag_config_policy)) {
5240 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5241 return -EINVAL;
5242 }
5243
5244 /* Parse and fetch required bandwidth kbps */
5245 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5246 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5247 return -EINVAL;
5248 }
5249
5250 dfsFlag = nla_get_u32(
5251 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5252 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5253 dfsFlag);
5254
5255 pHddCtx->disable_dfs_flag = dfsFlag;
5256
5257 sme_disable_dfs_channel(hHal, dfsFlag);
5258 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305259
5260 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305261 return 0;
5262}
Atul Mittal115287b2014-07-08 13:26:33 +05305263
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305264static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5265 struct wireless_dev *wdev,
5266 const void *data,
5267 int data_len)
5268{
5269 int ret = 0;
5270
5271 vos_ssr_protect(__func__);
5272 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5273 vos_ssr_unprotect(__func__);
5274
5275 return ret;
5276
5277}
5278
Mukul Sharma2a271632014-10-13 14:59:01 +05305279const struct
5280nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5281{
5282 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5283 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5284};
5285
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305286static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305287 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305288{
5289
5290 u8 bssid[6] = {0};
5291 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5292 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5293 eHalStatus status = eHAL_STATUS_SUCCESS;
5294 v_U32_t isFwrRoamEnabled = FALSE;
5295 int ret;
5296
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305297 ENTER();
5298
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305299 ret = wlan_hdd_validate_context(pHddCtx);
5300 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305301 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305302 }
5303
5304 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5305 data, data_len,
5306 qca_wlan_vendor_attr);
5307 if (ret){
5308 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5309 return -EINVAL;
5310 }
5311
5312 /* Parse and fetch Enable flag */
5313 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5314 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5315 return -EINVAL;
5316 }
5317
5318 isFwrRoamEnabled = nla_get_u32(
5319 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5320
5321 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5322
5323 /* Parse and fetch bssid */
5324 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5325 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5326 return -EINVAL;
5327 }
5328
5329 memcpy(bssid, nla_data(
5330 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5331 sizeof(bssid));
5332 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5333
5334 //Update roaming
5335 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305336 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305337 return status;
5338}
5339
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305340static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5341 struct wireless_dev *wdev, const void *data, int data_len)
5342{
5343 int ret = 0;
5344
5345 vos_ssr_protect(__func__);
5346 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5347 vos_ssr_unprotect(__func__);
5348
5349 return ret;
5350}
5351
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305352/**
5353 * __wlan_hdd_cfg80211_setband() - set band
5354 * @wiphy: Pointer to wireless phy
5355 * @wdev: Pointer to wireless device
5356 * @data: Pointer to data
5357 * @data_len: Data length
5358 *
5359 * Return: 0 on success, negative errno on failure
5360 */
5361static int
5362__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5363 struct wireless_dev *wdev,
5364 const void *data,
5365 int data_len)
5366{
5367 struct net_device *dev = wdev->netdev;
5368 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5369 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5370 int ret;
5371 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
5372 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
5373
5374 ENTER();
5375
5376 ret = wlan_hdd_validate_context(hdd_ctx);
5377 if (0 != ret) {
5378 hddLog(LOGE, FL("HDD context is not valid"));
5379 return ret;
5380 }
5381
5382 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
5383 policy)) {
5384 hddLog(LOGE, FL("Invalid ATTR"));
5385 return -EINVAL;
5386 }
5387
5388 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
5389 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
5390 return -EINVAL;
5391 }
5392
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305393 hdd_ctx->isSetBandByNL = TRUE;
5394 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305395 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305396 hdd_ctx->isSetBandByNL = FALSE;
5397
5398 EXIT();
5399 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305400}
5401
5402/**
5403 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
5404 * @wiphy: wiphy structure pointer
5405 * @wdev: Wireless device structure pointer
5406 * @data: Pointer to the data received
5407 * @data_len: Length of @data
5408 *
5409 * Return: 0 on success; errno on failure
5410 */
5411static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5412 struct wireless_dev *wdev,
5413 const void *data,
5414 int data_len)
5415{
5416 int ret = 0;
5417
5418 vos_ssr_protect(__func__);
5419 ret = __wlan_hdd_cfg80211_setband(wiphy,
5420 wdev, data, data_len);
5421 vos_ssr_unprotect(__func__);
5422
5423 return ret;
5424}
5425
Sunil Duttc69bccb2014-05-26 21:30:20 +05305426const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
5427{
Mukul Sharma2a271632014-10-13 14:59:01 +05305428 {
5429 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5430 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
5431 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5432 WIPHY_VENDOR_CMD_NEED_NETDEV |
5433 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305434 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05305435 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305436
5437 {
5438 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5439 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
5440 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5441 WIPHY_VENDOR_CMD_NEED_NETDEV |
5442 WIPHY_VENDOR_CMD_NEED_RUNNING,
5443 .doit = wlan_hdd_cfg80211_nan_request
5444 },
5445
Sunil Duttc69bccb2014-05-26 21:30:20 +05305446#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5447 {
5448 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5449 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
5450 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5451 WIPHY_VENDOR_CMD_NEED_NETDEV |
5452 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305453 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05305454 },
5455
5456 {
5457 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5458 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
5459 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5460 WIPHY_VENDOR_CMD_NEED_NETDEV |
5461 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305462 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05305463 },
5464
5465 {
5466 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5467 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
5468 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5469 WIPHY_VENDOR_CMD_NEED_NETDEV |
5470 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305471 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05305472 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305473#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305474#ifdef WLAN_FEATURE_EXTSCAN
5475 {
5476 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5477 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
5478 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5479 WIPHY_VENDOR_CMD_NEED_NETDEV |
5480 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305481 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05305482 },
5483 {
5484 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5485 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
5486 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5487 WIPHY_VENDOR_CMD_NEED_NETDEV |
5488 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305489 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05305490 },
5491 {
5492 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5493 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
5494 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5495 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305496 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05305497 },
5498 {
5499 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5500 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
5501 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5502 WIPHY_VENDOR_CMD_NEED_NETDEV |
5503 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305504 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05305505 },
5506 {
5507 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5508 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
5509 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5510 WIPHY_VENDOR_CMD_NEED_NETDEV |
5511 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305512 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05305513 },
5514 {
5515 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5516 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
5517 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5518 WIPHY_VENDOR_CMD_NEED_NETDEV |
5519 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305520 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305521 },
5522 {
5523 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5524 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
5525 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5526 WIPHY_VENDOR_CMD_NEED_NETDEV |
5527 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305528 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305529 },
5530 {
5531 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5532 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
5533 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5534 WIPHY_VENDOR_CMD_NEED_NETDEV |
5535 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305536 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305537 },
5538 {
5539 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5540 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
5541 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5542 WIPHY_VENDOR_CMD_NEED_NETDEV |
5543 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305544 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305545 },
5546#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305547/*EXT TDLS*/
5548 {
5549 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5550 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
5551 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5552 WIPHY_VENDOR_CMD_NEED_NETDEV |
5553 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305554 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05305555 },
5556 {
5557 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5558 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
5559 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5560 WIPHY_VENDOR_CMD_NEED_NETDEV |
5561 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305562 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05305563 },
5564 {
5565 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5566 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
5567 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5568 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305569 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05305570 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05305571 {
5572 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5573 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
5574 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5575 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305576 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05305577 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05305578 {
5579 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5580 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
5581 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5582 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305583 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05305584 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305585 {
5586 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5587 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
5588 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5589 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305590 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305591 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305592 {
5593 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5594 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
5595 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5596 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305597 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305598 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305599 {
5600 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5601 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
5602 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5603 WIPHY_VENDOR_CMD_NEED_NETDEV |
5604 WIPHY_VENDOR_CMD_NEED_RUNNING,
5605 .doit = wlan_hdd_cfg80211_setband
5606 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05305607};
5608
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005609/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05305610static const
5611struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005612{
5613#ifdef FEATURE_WLAN_CH_AVOID
5614 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05305615 .vendor_id = QCA_NL80211_VENDOR_ID,
5616 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005617 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305618#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
5619#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5620 {
5621 /* Index = 1*/
5622 .vendor_id = QCA_NL80211_VENDOR_ID,
5623 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
5624 },
5625 {
5626 /* Index = 2*/
5627 .vendor_id = QCA_NL80211_VENDOR_ID,
5628 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
5629 },
5630 {
5631 /* Index = 3*/
5632 .vendor_id = QCA_NL80211_VENDOR_ID,
5633 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
5634 },
5635 {
5636 /* Index = 4*/
5637 .vendor_id = QCA_NL80211_VENDOR_ID,
5638 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
5639 },
5640 {
5641 /* Index = 5*/
5642 .vendor_id = QCA_NL80211_VENDOR_ID,
5643 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
5644 },
5645 {
5646 /* Index = 6*/
5647 .vendor_id = QCA_NL80211_VENDOR_ID,
5648 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
5649 },
5650#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305651#ifdef WLAN_FEATURE_EXTSCAN
5652 {
5653 .vendor_id = QCA_NL80211_VENDOR_ID,
5654 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
5655 },
5656 {
5657 .vendor_id = QCA_NL80211_VENDOR_ID,
5658 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
5659 },
5660 {
5661 .vendor_id = QCA_NL80211_VENDOR_ID,
5662 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
5663 },
5664 {
5665 .vendor_id = QCA_NL80211_VENDOR_ID,
5666 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
5667 },
5668 {
5669 .vendor_id = QCA_NL80211_VENDOR_ID,
5670 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
5671 },
5672 {
5673 .vendor_id = QCA_NL80211_VENDOR_ID,
5674 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
5675 },
5676 {
5677 .vendor_id = QCA_NL80211_VENDOR_ID,
5678 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
5679 },
5680 {
5681 .vendor_id = QCA_NL80211_VENDOR_ID,
5682 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
5683 },
5684 {
5685 .vendor_id = QCA_NL80211_VENDOR_ID,
5686 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
5687 },
5688 {
5689 .vendor_id = QCA_NL80211_VENDOR_ID,
5690 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
5691 },
5692 {
5693 .vendor_id = QCA_NL80211_VENDOR_ID,
5694 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
5695 },
5696 {
5697 .vendor_id = QCA_NL80211_VENDOR_ID,
5698 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
5699 },
5700 {
5701 .vendor_id = QCA_NL80211_VENDOR_ID,
5702 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
5703 },
5704#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305705/*EXT TDLS*/
5706 {
5707 .vendor_id = QCA_NL80211_VENDOR_ID,
5708 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
5709 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305710
5711 {
5712 .vendor_id = QCA_NL80211_VENDOR_ID,
5713 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
5714 },
5715
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005716};
5717
Jeff Johnson295189b2012-06-20 16:38:30 -07005718/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305719 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305720 * This function is called by hdd_wlan_startup()
5721 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305722 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07005723 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305724struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07005725{
5726 struct wiphy *wiphy;
5727 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305728 /*
5729 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07005730 */
5731 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
5732
5733 if (!wiphy)
5734 {
5735 /* Print error and jump into err label and free the memory */
5736 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
5737 return NULL;
5738 }
5739
Sunil Duttc69bccb2014-05-26 21:30:20 +05305740
Jeff Johnson295189b2012-06-20 16:38:30 -07005741 return wiphy;
5742}
5743
5744/*
5745 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305746 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07005747 * private ioctl to change the band value
5748 */
5749int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
5750{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305751 int i, j;
5752 eNVChannelEnabledType channelEnabledState;
5753
Jeff Johnsone7245742012-09-05 17:12:55 -07005754 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305755
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305756 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005757 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305758
5759 if (NULL == wiphy->bands[i])
5760 {
5761 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5762 __func__, i);
5763 continue;
5764 }
5765
5766 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5767 {
5768 struct ieee80211_supported_band *band = wiphy->bands[i];
5769
5770 channelEnabledState = vos_nv_getChannelEnabledState(
5771 band->channels[j].hw_value);
5772
5773 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
5774 {
Abhishek Singh678227a2014-11-04 10:52:38 +05305775 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305776 continue;
5777 }
5778 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
5779 {
5780 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5781 continue;
5782 }
5783
5784 if (NV_CHANNEL_DISABLE == channelEnabledState ||
5785 NV_CHANNEL_INVALID == channelEnabledState)
5786 {
5787 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5788 }
5789 else if (NV_CHANNEL_DFS == channelEnabledState)
5790 {
5791 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5792 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
5793 }
5794 else
5795 {
5796 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
5797 |IEEE80211_CHAN_RADAR);
5798 }
5799 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005800 }
5801 return 0;
5802}
5803/*
5804 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305805 * This function is called by hdd_wlan_startup()
5806 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005807 * This function is used to initialize and register wiphy structure.
5808 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305809int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005810 struct wiphy *wiphy,
5811 hdd_config_t *pCfg
5812 )
5813{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305814 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305815 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5816
Jeff Johnsone7245742012-09-05 17:12:55 -07005817 ENTER();
5818
Jeff Johnson295189b2012-06-20 16:38:30 -07005819 /* Now bind the underlying wlan device with wiphy */
5820 set_wiphy_dev(wiphy, dev);
5821
5822 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005823
Kiet Lam6c583332013-10-14 05:37:09 +05305824#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005825 /* the flag for the other case would be initialzed in
5826 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005827 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305828#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005829
Amar Singhalfddc28c2013-09-05 13:03:40 -07005830 /* This will disable updating of NL channels from passive to
5831 * active if a beacon is received on passive channel. */
5832 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07005833
Amar Singhalfddc28c2013-09-05 13:03:40 -07005834
Amar Singhala49cbc52013-10-08 18:37:44 -07005835
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005836#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005837 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5838 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5839 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005840 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05305841 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005842#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005843
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005844#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005845 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005846#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005847 || pCfg->isFastRoamIniFeatureEnabled
5848#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005849#ifdef FEATURE_WLAN_ESE
5850 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005851#endif
5852 )
5853 {
5854 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5855 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005856#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005857#ifdef FEATURE_WLAN_TDLS
5858 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5859 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5860#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305861#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305862 if (pCfg->configPNOScanSupport)
5863 {
5864 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5865 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5866 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5867 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5868 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305869#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005870
Abhishek Singh10d85972015-04-17 10:27:23 +05305871#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5872 wiphy->features |= NL80211_FEATURE_HT_IBSS;
5873#endif
5874
Amar Singhalfddc28c2013-09-05 13:03:40 -07005875#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005876 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5877 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005878 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005879 driver need to determine what to do with both
5880 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005881
5882 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005883#else
5884 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005885#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005886
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305887 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5888
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05305889 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005890
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305891 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5892
Jeff Johnson295189b2012-06-20 16:38:30 -07005893 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05305894 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
5895 | BIT(NL80211_IFTYPE_ADHOC)
5896 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5897 | BIT(NL80211_IFTYPE_P2P_GO)
5898 | BIT(NL80211_IFTYPE_AP);
5899
5900 if (VOS_MONITOR_MODE == hdd_get_conparam())
5901 {
5902 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
5903 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005904
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305905 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005906 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305907#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5908 if( pCfg->enableMCC )
5909 {
5910 /* Currently, supports up to two channels */
5911 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005912
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305913 if( !pCfg->allowMCCGODiffBI )
5914 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005915
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305916 }
5917 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5918 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005919#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305920 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005921
Jeff Johnson295189b2012-06-20 16:38:30 -07005922 /* Before registering we need to update the ht capabilitied based
5923 * on ini values*/
5924 if( !pCfg->ShortGI20MhzEnable )
5925 {
5926 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5927 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5928 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5929 }
5930
5931 if( !pCfg->ShortGI40MhzEnable )
5932 {
5933 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5934 }
5935
5936 if( !pCfg->nChannelBondingMode5GHz )
5937 {
5938 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5939 }
5940
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305941 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305942 if (true == hdd_is_5g_supported(pHddCtx))
5943 {
5944 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5945 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305946
5947 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5948 {
5949
5950 if (NULL == wiphy->bands[i])
5951 {
5952 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5953 __func__, i);
5954 continue;
5955 }
5956
5957 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5958 {
5959 struct ieee80211_supported_band *band = wiphy->bands[i];
5960
5961 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5962 {
5963 // Enable social channels for P2P
5964 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5965 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5966 else
5967 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5968 continue;
5969 }
5970 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5971 {
5972 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5973 continue;
5974 }
5975 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005976 }
5977 /*Initialise the supported cipher suite details*/
5978 wiphy->cipher_suites = hdd_cipher_suites;
5979 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5980
5981 /*signal strength in mBm (100*dBm) */
5982 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5983
5984#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305985 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005986#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005987
Sunil Duttc69bccb2014-05-26 21:30:20 +05305988 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
5989 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005990 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
5991 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
5992
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305993 EXIT();
5994 return 0;
5995}
5996
5997/* In this function we are registering wiphy. */
5998int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
5999{
6000 ENTER();
6001 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006002 if (0 > wiphy_register(wiphy))
6003 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306004 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07006005 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
6006 return -EIO;
6007 }
6008
6009 EXIT();
6010 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306011}
Jeff Johnson295189b2012-06-20 16:38:30 -07006012
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306013/* In this function we are updating channel list when,
6014 regulatory domain is FCC and country code is US.
6015 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
6016 As per FCC smart phone is not a indoor device.
6017 GO should not opeate on indoor channels */
6018void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
6019{
6020 int j;
6021 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6022 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
6023 //Default counrtycode from NV at the time of wiphy initialization.
6024 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
6025 &defaultCountryCode[0]))
6026 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006027 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306028 }
6029 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
6030 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306031 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
6032 {
6033 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
6034 return;
6035 }
6036 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
6037 {
6038 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
6039 // Mark UNII -1 band channel as passive
6040 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
6041 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
6042 }
6043 }
6044}
6045
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306046/* This function registers for all frame which supplicant is interested in */
6047void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006048{
Jeff Johnson295189b2012-06-20 16:38:30 -07006049 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6050 /* Register for all P2P action, public action etc frames */
6051 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6052
Jeff Johnsone7245742012-09-05 17:12:55 -07006053 ENTER();
6054
Jeff Johnson295189b2012-06-20 16:38:30 -07006055 /* Right now we are registering these frame when driver is getting
6056 initialized. Once we will move to 2.6.37 kernel, in which we have
6057 frame register ops, we will move this code as a part of that */
6058 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306059 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006060 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6061
6062 /* GAS Initial Response */
6063 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6064 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306065
Jeff Johnson295189b2012-06-20 16:38:30 -07006066 /* GAS Comeback Request */
6067 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6068 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6069
6070 /* GAS Comeback Response */
6071 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6072 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6073
6074 /* P2P Public Action */
6075 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306076 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006077 P2P_PUBLIC_ACTION_FRAME_SIZE );
6078
6079 /* P2P Action */
6080 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6081 (v_U8_t*)P2P_ACTION_FRAME,
6082 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07006083
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05306084 /* WNM BSS Transition Request frame */
6085 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6086 (v_U8_t*)WNM_BSS_ACTION_FRAME,
6087 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006088
6089 /* WNM-Notification */
6090 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6091 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6092 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006093}
6094
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306095void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006096{
Jeff Johnson295189b2012-06-20 16:38:30 -07006097 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6098 /* Register for all P2P action, public action etc frames */
6099 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6100
Jeff Johnsone7245742012-09-05 17:12:55 -07006101 ENTER();
6102
Jeff Johnson295189b2012-06-20 16:38:30 -07006103 /* Right now we are registering these frame when driver is getting
6104 initialized. Once we will move to 2.6.37 kernel, in which we have
6105 frame register ops, we will move this code as a part of that */
6106 /* GAS Initial Request */
6107
6108 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6109 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6110
6111 /* GAS Initial Response */
6112 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6113 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306114
Jeff Johnson295189b2012-06-20 16:38:30 -07006115 /* GAS Comeback Request */
6116 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6117 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6118
6119 /* GAS Comeback Response */
6120 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6121 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6122
6123 /* P2P Public Action */
6124 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306125 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006126 P2P_PUBLIC_ACTION_FRAME_SIZE );
6127
6128 /* P2P Action */
6129 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6130 (v_U8_t*)P2P_ACTION_FRAME,
6131 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006132 /* WNM-Notification */
6133 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6134 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6135 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006136}
6137
6138#ifdef FEATURE_WLAN_WAPI
6139void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
6140 const u8 *mac_addr, u8 *key , int key_Len)
6141{
6142 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6143 tCsrRoamSetKey setKey;
6144 v_BOOL_t isConnected = TRUE;
6145 int status = 0;
6146 v_U32_t roamId= 0xFF;
6147 tANI_U8 *pKeyPtr = NULL;
6148 int n = 0;
6149
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306150 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6151 __func__, hdd_device_modetoString(pAdapter->device_mode),
6152 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006153
Gopichand Nakkalae7480202013-02-11 15:24:22 +05306154 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006155 setKey.keyId = key_index; // Store Key ID
6156 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
6157 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
6158 setKey.paeRole = 0 ; // the PAE role
6159 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
6160 {
6161 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
6162 }
6163 else
6164 {
6165 isConnected = hdd_connIsConnected(pHddStaCtx);
6166 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
6167 }
6168 setKey.keyLength = key_Len;
6169 pKeyPtr = setKey.Key;
6170 memcpy( pKeyPtr, key, key_Len);
6171
Arif Hussain6d2a3322013-11-17 19:50:10 -08006172 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07006173 __func__, key_Len);
6174 for (n = 0 ; n < key_Len; n++)
6175 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
6176 __func__,n,setKey.Key[n]);
6177
6178 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
6179 if ( isConnected )
6180 {
6181 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
6182 pAdapter->sessionId, &setKey, &roamId );
6183 }
6184 if ( status != 0 )
6185 {
6186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6187 "[%4d] sme_RoamSetKey returned ERROR status= %d",
6188 __LINE__, status );
6189 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
6190 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05306191 /* Need to clear any trace of key value in the memory.
6192 * Thus zero out the memory even though it is local
6193 * variable.
6194 */
6195 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006196}
6197#endif /* FEATURE_WLAN_WAPI*/
6198
6199#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306200int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006201 beacon_data_t **ppBeacon,
6202 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006203#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306204int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006205 beacon_data_t **ppBeacon,
6206 struct cfg80211_beacon_data *params,
6207 int dtim_period)
6208#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306209{
Jeff Johnson295189b2012-06-20 16:38:30 -07006210 int size;
6211 beacon_data_t *beacon = NULL;
6212 beacon_data_t *old = NULL;
6213 int head_len,tail_len;
6214
Jeff Johnsone7245742012-09-05 17:12:55 -07006215 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006216 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306217 {
6218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6219 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006220 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306221 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006222
6223 old = pAdapter->sessionCtx.ap.beacon;
6224
6225 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306226 {
6227 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6228 FL("session(%d) old and new heads points to NULL"),
6229 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006230 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306231 }
6232
6233 if (params->tail && !params->tail_len)
6234 {
6235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6236 FL("tail_len is zero but tail is not NULL"));
6237 return -EINVAL;
6238 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006239
Jeff Johnson295189b2012-06-20 16:38:30 -07006240#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
6241 /* Kernel 3.0 is not updating dtim_period for set beacon */
6242 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306243 {
6244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6245 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006246 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306247 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006248#endif
6249
6250 if(params->head)
6251 head_len = params->head_len;
6252 else
6253 head_len = old->head_len;
6254
6255 if(params->tail || !old)
6256 tail_len = params->tail_len;
6257 else
6258 tail_len = old->tail_len;
6259
6260 size = sizeof(beacon_data_t) + head_len + tail_len;
6261
6262 beacon = kzalloc(size, GFP_KERNEL);
6263
6264 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306265 {
6266 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6267 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006268 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306269 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006270
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006271#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006272 if(params->dtim_period || !old )
6273 beacon->dtim_period = params->dtim_period;
6274 else
6275 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006276#else
6277 if(dtim_period || !old )
6278 beacon->dtim_period = dtim_period;
6279 else
6280 beacon->dtim_period = old->dtim_period;
6281#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306282
Jeff Johnson295189b2012-06-20 16:38:30 -07006283 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6284 beacon->tail = beacon->head + head_len;
6285 beacon->head_len = head_len;
6286 beacon->tail_len = tail_len;
6287
6288 if(params->head) {
6289 memcpy (beacon->head,params->head,beacon->head_len);
6290 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306291 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07006292 if(old)
6293 memcpy (beacon->head,old->head,beacon->head_len);
6294 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306295
Jeff Johnson295189b2012-06-20 16:38:30 -07006296 if(params->tail) {
6297 memcpy (beacon->tail,params->tail,beacon->tail_len);
6298 }
6299 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306300 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07006301 memcpy (beacon->tail,old->tail,beacon->tail_len);
6302 }
6303
6304 *ppBeacon = beacon;
6305
6306 kfree(old);
6307
6308 return 0;
6309
6310}
Jeff Johnson295189b2012-06-20 16:38:30 -07006311
6312v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
6313{
6314 int left = length;
6315 v_U8_t *ptr = pIes;
6316 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306317
Jeff Johnson295189b2012-06-20 16:38:30 -07006318 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306319 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006320 elem_id = ptr[0];
6321 elem_len = ptr[1];
6322 left -= 2;
6323 if(elem_len > left)
6324 {
6325 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006326 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006327 eid,elem_len,left);
6328 return NULL;
6329 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306330 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006331 {
6332 return ptr;
6333 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306334
Jeff Johnson295189b2012-06-20 16:38:30 -07006335 left -= elem_len;
6336 ptr += (elem_len + 2);
6337 }
6338 return NULL;
6339}
6340
Jeff Johnson295189b2012-06-20 16:38:30 -07006341/* Check if rate is 11g rate or not */
6342static int wlan_hdd_rate_is_11g(u8 rate)
6343{
Sanjay Devnani28322e22013-06-21 16:13:40 -07006344 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006345 u8 i;
6346 for (i = 0; i < 8; i++)
6347 {
6348 if(rate == gRateArray[i])
6349 return TRUE;
6350 }
6351 return FALSE;
6352}
6353
6354/* Check for 11g rate and set proper 11g only mode */
6355static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
6356 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
6357{
6358 u8 i, num_rates = pIe[0];
6359
6360 pIe += 1;
6361 for ( i = 0; i < num_rates; i++)
6362 {
6363 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
6364 {
6365 /* If rate set have 11g rate than change the mode to 11G */
6366 *pSapHw_mode = eSAP_DOT11_MODE_11g;
6367 if (pIe[i] & BASIC_RATE_MASK)
6368 {
6369 /* If we have 11g rate as basic rate, it means mode
6370 is 11g only mode.
6371 */
6372 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
6373 *pCheckRatesfor11g = FALSE;
6374 }
6375 }
6376 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6377 {
6378 *require_ht = TRUE;
6379 }
6380 }
6381 return;
6382}
6383
6384static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
6385{
6386 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6387 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6388 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6389 u8 checkRatesfor11g = TRUE;
6390 u8 require_ht = FALSE;
6391 u8 *pIe=NULL;
6392
6393 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
6394
6395 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6396 pBeacon->head_len, WLAN_EID_SUPP_RATES);
6397 if (pIe != NULL)
6398 {
6399 pIe += 1;
6400 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6401 &pConfig->SapHw_mode);
6402 }
6403
6404 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6405 WLAN_EID_EXT_SUPP_RATES);
6406 if (pIe != NULL)
6407 {
6408
6409 pIe += 1;
6410 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6411 &pConfig->SapHw_mode);
6412 }
6413
6414 if( pConfig->channel > 14 )
6415 {
6416 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
6417 }
6418
6419 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6420 WLAN_EID_HT_CAPABILITY);
6421
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306422 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006423 {
6424 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
6425 if(require_ht)
6426 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
6427 }
6428}
6429
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306430static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
6431 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
6432{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006433 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306434 v_U8_t *pIe = NULL;
6435 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6436
6437 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6438 pBeacon->tail, pBeacon->tail_len);
6439
6440 if (pIe)
6441 {
6442 ielen = pIe[1] + 2;
6443 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6444 {
6445 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
6446 }
6447 else
6448 {
6449 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
6450 return -EINVAL;
6451 }
6452 *total_ielen += ielen;
6453 }
6454 return 0;
6455}
6456
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006457static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
6458 v_U8_t *genie, v_U8_t *total_ielen)
6459{
6460 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6461 int left = pBeacon->tail_len;
6462 v_U8_t *ptr = pBeacon->tail;
6463 v_U8_t elem_id, elem_len;
6464 v_U16_t ielen = 0;
6465
6466 if ( NULL == ptr || 0 == left )
6467 return;
6468
6469 while (left >= 2)
6470 {
6471 elem_id = ptr[0];
6472 elem_len = ptr[1];
6473 left -= 2;
6474 if (elem_len > left)
6475 {
6476 hddLog( VOS_TRACE_LEVEL_ERROR,
6477 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
6478 elem_id, elem_len, left);
6479 return;
6480 }
6481 if (IE_EID_VENDOR == elem_id)
6482 {
6483 /* skipping the VSIE's which we don't want to include or
6484 * it will be included by existing code
6485 */
6486 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
6487#ifdef WLAN_FEATURE_WFD
6488 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
6489#endif
6490 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6491 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6492 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
6493 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6494 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
6495 {
6496 ielen = ptr[1] + 2;
6497 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6498 {
6499 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
6500 *total_ielen += ielen;
6501 }
6502 else
6503 {
6504 hddLog( VOS_TRACE_LEVEL_ERROR,
6505 "IE Length is too big "
6506 "IEs eid=%d elem_len=%d total_ie_lent=%d",
6507 elem_id, elem_len, *total_ielen);
6508 }
6509 }
6510 }
6511
6512 left -= elem_len;
6513 ptr += (elem_len + 2);
6514 }
6515 return;
6516}
6517
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006518#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006519static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6520 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006521#else
6522static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6523 struct cfg80211_beacon_data *params)
6524#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006525{
6526 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306527 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006528 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07006529 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006530
6531 genie = vos_mem_malloc(MAX_GENIE_LEN);
6532
6533 if(genie == NULL) {
6534
6535 return -ENOMEM;
6536 }
6537
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306538 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6539 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006540 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306541 hddLog(LOGE,
6542 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306543 ret = -EINVAL;
6544 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006545 }
6546
6547#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306548 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6549 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
6550 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306551 hddLog(LOGE,
6552 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306553 ret = -EINVAL;
6554 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006555 }
6556#endif
6557
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306558 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6559 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006560 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306561 hddLog(LOGE,
6562 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306563 ret = -EINVAL;
6564 goto done;
6565 }
6566
6567 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
6568 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006569 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07006570 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006571
6572 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6573 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
6574 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6575 {
6576 hddLog(LOGE,
6577 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006578 ret = -EINVAL;
6579 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006580 }
6581
6582 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6583 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6584 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6585 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6586 ==eHAL_STATUS_FAILURE)
6587 {
6588 hddLog(LOGE,
6589 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006590 ret = -EINVAL;
6591 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006592 }
6593
6594 // Added for ProResp IE
6595 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
6596 {
6597 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
6598 u8 probe_rsp_ie_len[3] = {0};
6599 u8 counter = 0;
6600 /* Check Probe Resp Length if it is greater then 255 then Store
6601 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
6602 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
6603 Store More then 255 bytes into One Variable.
6604 */
6605 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6606 {
6607 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6608 {
6609 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6610 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6611 }
6612 else
6613 {
6614 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6615 rem_probe_resp_ie_len = 0;
6616 }
6617 }
6618
6619 rem_probe_resp_ie_len = 0;
6620
6621 if (probe_rsp_ie_len[0] > 0)
6622 {
6623 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6624 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6625 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6626 probe_rsp_ie_len[0], NULL,
6627 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6628 {
6629 hddLog(LOGE,
6630 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006631 ret = -EINVAL;
6632 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006633 }
6634 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6635 }
6636
6637 if (probe_rsp_ie_len[1] > 0)
6638 {
6639 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6640 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6641 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6642 probe_rsp_ie_len[1], NULL,
6643 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6644 {
6645 hddLog(LOGE,
6646 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006647 ret = -EINVAL;
6648 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006649 }
6650 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6651 }
6652
6653 if (probe_rsp_ie_len[2] > 0)
6654 {
6655 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6656 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6657 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6658 probe_rsp_ie_len[2], NULL,
6659 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6660 {
6661 hddLog(LOGE,
6662 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006663 ret = -EINVAL;
6664 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006665 }
6666 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6667 }
6668
6669 if (probe_rsp_ie_len[1] == 0 )
6670 {
6671 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6672 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6673 eANI_BOOLEAN_FALSE) )
6674 {
6675 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006676 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006677 }
6678 }
6679
6680 if (probe_rsp_ie_len[2] == 0 )
6681 {
6682 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6683 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6684 eANI_BOOLEAN_FALSE) )
6685 {
6686 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006687 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006688 }
6689 }
6690
6691 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6692 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6693 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6694 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6695 == eHAL_STATUS_FAILURE)
6696 {
6697 hddLog(LOGE,
6698 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006699 ret = -EINVAL;
6700 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006701 }
6702 }
6703 else
6704 {
6705 // Reset WNI_CFG_PROBE_RSP Flags
6706 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
6707
6708 hddLog(VOS_TRACE_LEVEL_INFO,
6709 "%s: No Probe Response IE received in set beacon",
6710 __func__);
6711 }
6712
6713 // Added for AssocResp IE
6714 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
6715 {
6716 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6717 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
6718 params->assocresp_ies_len, NULL,
6719 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6720 {
6721 hddLog(LOGE,
6722 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006723 ret = -EINVAL;
6724 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006725 }
6726
6727 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6728 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
6729 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6730 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6731 == eHAL_STATUS_FAILURE)
6732 {
6733 hddLog(LOGE,
6734 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006735 ret = -EINVAL;
6736 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006737 }
6738 }
6739 else
6740 {
6741 hddLog(VOS_TRACE_LEVEL_INFO,
6742 "%s: No Assoc Response IE received in set beacon",
6743 __func__);
6744
6745 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6746 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6747 eANI_BOOLEAN_FALSE) )
6748 {
6749 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006750 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006751 }
6752 }
6753
Jeff Johnsone7245742012-09-05 17:12:55 -07006754done:
Jeff Johnson295189b2012-06-20 16:38:30 -07006755 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306756 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006757}
Jeff Johnson295189b2012-06-20 16:38:30 -07006758
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306759/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006760 * FUNCTION: wlan_hdd_validate_operation_channel
6761 * called by wlan_hdd_cfg80211_start_bss() and
6762 * wlan_hdd_cfg80211_set_channel()
6763 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306764 * channel list.
6765 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006766VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006767{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306768
Jeff Johnson295189b2012-06-20 16:38:30 -07006769 v_U32_t num_ch = 0;
6770 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6771 u32 indx = 0;
6772 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306773 v_U8_t fValidChannel = FALSE, count = 0;
6774 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306775
Jeff Johnson295189b2012-06-20 16:38:30 -07006776 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6777
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306778 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006779 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306780 /* Validate the channel */
6781 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006782 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306783 if ( channel == rfChannels[count].channelNum )
6784 {
6785 fValidChannel = TRUE;
6786 break;
6787 }
6788 }
6789 if (fValidChannel != TRUE)
6790 {
6791 hddLog(VOS_TRACE_LEVEL_ERROR,
6792 "%s: Invalid Channel [%d]", __func__, channel);
6793 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006794 }
6795 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306796 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006797 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306798 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6799 valid_ch, &num_ch))
6800 {
6801 hddLog(VOS_TRACE_LEVEL_ERROR,
6802 "%s: failed to get valid channel list", __func__);
6803 return VOS_STATUS_E_FAILURE;
6804 }
6805 for (indx = 0; indx < num_ch; indx++)
6806 {
6807 if (channel == valid_ch[indx])
6808 {
6809 break;
6810 }
6811 }
6812
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306813 if (indx >= num_ch)
6814 {
6815 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6816 {
6817 eCsrBand band;
6818 unsigned int freq;
6819
6820 sme_GetFreqBand(hHal, &band);
6821
6822 if (eCSR_BAND_5G == band)
6823 {
6824#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6825 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6826 {
6827 freq = ieee80211_channel_to_frequency(channel,
6828 IEEE80211_BAND_2GHZ);
6829 }
6830 else
6831 {
6832 freq = ieee80211_channel_to_frequency(channel,
6833 IEEE80211_BAND_5GHZ);
6834 }
6835#else
6836 freq = ieee80211_channel_to_frequency(channel);
6837#endif
6838 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6839 return VOS_STATUS_SUCCESS;
6840 }
6841 }
6842
6843 hddLog(VOS_TRACE_LEVEL_ERROR,
6844 "%s: Invalid Channel [%d]", __func__, channel);
6845 return VOS_STATUS_E_FAILURE;
6846 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006847 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306848
Jeff Johnson295189b2012-06-20 16:38:30 -07006849 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306850
Jeff Johnson295189b2012-06-20 16:38:30 -07006851}
6852
Viral Modi3a32cc52013-02-08 11:14:52 -08006853/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306854 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08006855 * This function is used to set the channel number
6856 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306857static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08006858 struct ieee80211_channel *chan,
6859 enum nl80211_channel_type channel_type
6860 )
6861{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306862 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006863 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006864 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006865 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306866 hdd_context_t *pHddCtx;
6867 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006868
6869 ENTER();
6870
6871 if( NULL == dev )
6872 {
6873 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006874 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006875 return -ENODEV;
6876 }
6877 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306878
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306879 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6880 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6881 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006882 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306883 "%s: device_mode = %s (%d) freq = %d", __func__,
6884 hdd_device_modetoString(pAdapter->device_mode),
6885 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306886
6887 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6888 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306889 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006890 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306891 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006892 }
6893
6894 /*
6895 * Do freq to chan conversion
6896 * TODO: for 11a
6897 */
6898
6899 channel = ieee80211_frequency_to_channel(freq);
6900
6901 /* Check freq range */
6902 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6903 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6904 {
6905 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006906 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006907 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6908 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6909 return -EINVAL;
6910 }
6911
6912 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6913
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306914 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6915 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006916 {
6917 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6918 {
6919 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006920 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006921 return -EINVAL;
6922 }
6923 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6924 "%s: set channel to [%d] for device mode =%d",
6925 __func__, channel,pAdapter->device_mode);
6926 }
6927 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006928 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006929 )
6930 {
6931 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6932 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6933 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6934
6935 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6936 {
6937 /* Link is up then return cant set channel*/
6938 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006939 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006940 return -EINVAL;
6941 }
6942
6943 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6944 pHddStaCtx->conn_info.operationChannel = channel;
6945 pRoamProfile->ChannelInfo.ChannelList =
6946 &pHddStaCtx->conn_info.operationChannel;
6947 }
6948 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006949 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006950 )
6951 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306952 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6953 {
6954 if(VOS_STATUS_SUCCESS !=
6955 wlan_hdd_validate_operation_channel(pAdapter,channel))
6956 {
6957 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006958 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306959 return -EINVAL;
6960 }
6961 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6962 }
6963 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006964 {
6965 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6966
6967 /* If auto channel selection is configured as enable/ 1 then ignore
6968 channel set by supplicant
6969 */
6970 if ( cfg_param->apAutoChannelSelection )
6971 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306972 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6973 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006974 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306975 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6976 __func__, hdd_device_modetoString(pAdapter->device_mode),
6977 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006978 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306979 else
6980 {
6981 if(VOS_STATUS_SUCCESS !=
6982 wlan_hdd_validate_operation_channel(pAdapter,channel))
6983 {
6984 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006985 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306986 return -EINVAL;
6987 }
6988 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6989 }
Viral Modi3a32cc52013-02-08 11:14:52 -08006990 }
6991 }
6992 else
6993 {
6994 hddLog(VOS_TRACE_LEVEL_FATAL,
6995 "%s: Invalid device mode failed to set valid channel", __func__);
6996 return -EINVAL;
6997 }
6998 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306999 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007000}
7001
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307002static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
7003 struct net_device *dev,
7004 struct ieee80211_channel *chan,
7005 enum nl80211_channel_type channel_type
7006 )
7007{
7008 int ret;
7009
7010 vos_ssr_protect(__func__);
7011 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
7012 vos_ssr_unprotect(__func__);
7013
7014 return ret;
7015}
7016
Jeff Johnson295189b2012-06-20 16:38:30 -07007017#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7018static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7019 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007020#else
7021static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7022 struct cfg80211_beacon_data *params,
7023 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307024 enum nl80211_hidden_ssid hidden_ssid,
7025 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007026#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007027{
7028 tsap_Config_t *pConfig;
7029 beacon_data_t *pBeacon = NULL;
7030 struct ieee80211_mgmt *pMgmt_frame;
7031 v_U8_t *pIe=NULL;
7032 v_U16_t capab_info;
7033 eCsrAuthType RSNAuthType;
7034 eCsrEncryptionType RSNEncryptType;
7035 eCsrEncryptionType mcRSNEncryptType;
7036 int status = VOS_STATUS_SUCCESS;
7037 tpWLAN_SAPEventCB pSapEventCallback;
7038 hdd_hostapd_state_t *pHostapdState;
7039 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
7040 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307041 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007042 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307043 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07007044 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08007045 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05307046 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07007047 v_BOOL_t MFPCapable = VOS_FALSE;
7048 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307049 v_BOOL_t sapEnable11AC =
7050 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07007051 ENTER();
7052
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307053 iniConfig = pHddCtx->cfg_ini;
7054
Jeff Johnson295189b2012-06-20 16:38:30 -07007055 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7056
7057 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7058
7059 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7060
7061 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7062
7063 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7064
7065 //channel is already set in the set_channel Call back
7066 //pConfig->channel = pCommitConfig->channel;
7067
7068 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307069 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07007070 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
7071
7072 pConfig->dtim_period = pBeacon->dtim_period;
7073
Arif Hussain6d2a3322013-11-17 19:50:10 -08007074 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07007075 pConfig->dtim_period);
7076
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08007077 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07007078 {
7079 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007080 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05307081 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
7082 {
7083 tANI_BOOLEAN restartNeeded;
7084 pConfig->ieee80211d = 1;
7085 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
7086 sme_setRegInfo(hHal, pConfig->countryCode);
7087 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
7088 }
7089 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007090 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07007091 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07007092 pConfig->ieee80211d = 1;
7093 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
7094 sme_setRegInfo(hHal, pConfig->countryCode);
7095 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07007096 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007097 else
7098 {
7099 pConfig->ieee80211d = 0;
7100 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307101 /*
7102 * If auto channel is configured i.e. channel is 0,
7103 * so skip channel validation.
7104 */
7105 if( AUTO_CHANNEL_SELECT != pConfig->channel )
7106 {
7107 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
7108 {
7109 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007110 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307111 return -EINVAL;
7112 }
7113 }
7114 else
7115 {
7116 if(1 != pHddCtx->is_dynamic_channel_range_set)
7117 {
7118 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
7119 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
7120 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
7121 }
7122 pHddCtx->is_dynamic_channel_range_set = 0;
7123 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007124 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007125 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007126 {
7127 pConfig->ieee80211d = 0;
7128 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307129
7130#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7131 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7132 pConfig->authType = eSAP_OPEN_SYSTEM;
7133 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7134 pConfig->authType = eSAP_SHARED_KEY;
7135 else
7136 pConfig->authType = eSAP_AUTO_SWITCH;
7137#else
7138 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7139 pConfig->authType = eSAP_OPEN_SYSTEM;
7140 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7141 pConfig->authType = eSAP_SHARED_KEY;
7142 else
7143 pConfig->authType = eSAP_AUTO_SWITCH;
7144#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007145
7146 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307147
7148 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07007149 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
7150
7151 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7152
7153 /*Set wps station to configured*/
7154 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7155
7156 if(pIe)
7157 {
7158 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
7159 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007160 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07007161 return -EINVAL;
7162 }
7163 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
7164 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007165 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07007166 /* Check 15 bit of WPS IE as it contain information for wps state
7167 * WPS state
7168 */
7169 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
7170 {
7171 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
7172 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
7173 {
7174 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7175 }
7176 }
7177 }
7178 else
7179 {
7180 pConfig->wps_state = SAP_WPS_DISABLED;
7181 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307182 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07007183
c_hpothufe599e92014-06-16 11:38:55 +05307184 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7185 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7186 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7187 eCSR_ENCRYPT_TYPE_NONE;
7188
Jeff Johnson295189b2012-06-20 16:38:30 -07007189 pConfig->RSNWPAReqIELength = 0;
7190 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307191 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007192 WLAN_EID_RSN);
7193 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307194 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007195 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7196 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7197 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307198 /* The actual processing may eventually be more extensive than
7199 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07007200 * by the app.
7201 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307202 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007203 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7204 &RSNEncryptType,
7205 &mcRSNEncryptType,
7206 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007207 &MFPCapable,
7208 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007209 pConfig->pRSNWPAReqIE[1]+2,
7210 pConfig->pRSNWPAReqIE );
7211
7212 if( VOS_STATUS_SUCCESS == status )
7213 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307214 /* Now copy over all the security attributes you have
7215 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007216 * */
7217 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7218 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7219 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7220 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307221 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007222 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007223 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7224 }
7225 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307226
Jeff Johnson295189b2012-06-20 16:38:30 -07007227 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7228 pBeacon->tail, pBeacon->tail_len);
7229
7230 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
7231 {
7232 if (pConfig->pRSNWPAReqIE)
7233 {
7234 /*Mixed mode WPA/WPA2*/
7235 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
7236 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7237 }
7238 else
7239 {
7240 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7241 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7242 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307243 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007244 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7245 &RSNEncryptType,
7246 &mcRSNEncryptType,
7247 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007248 &MFPCapable,
7249 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007250 pConfig->pRSNWPAReqIE[1]+2,
7251 pConfig->pRSNWPAReqIE );
7252
7253 if( VOS_STATUS_SUCCESS == status )
7254 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307255 /* Now copy over all the security attributes you have
7256 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007257 * */
7258 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7259 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7260 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7261 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307262 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007263 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007264 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7265 }
7266 }
7267 }
7268
Jeff Johnson4416a782013-03-25 14:17:50 -07007269 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
7270 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
7271 return -EINVAL;
7272 }
7273
Jeff Johnson295189b2012-06-20 16:38:30 -07007274 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
7275
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007276#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007277 if (params->ssid != NULL)
7278 {
7279 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
7280 pConfig->SSIDinfo.ssid.length = params->ssid_len;
7281 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7282 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7283 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007284#else
7285 if (ssid != NULL)
7286 {
7287 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
7288 pConfig->SSIDinfo.ssid.length = ssid_len;
7289 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7290 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7291 }
7292#endif
7293
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307294 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07007295 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307296
Jeff Johnson295189b2012-06-20 16:38:30 -07007297 /* default value */
7298 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7299 pConfig->num_accept_mac = 0;
7300 pConfig->num_deny_mac = 0;
7301
7302 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7303 pBeacon->tail, pBeacon->tail_len);
7304
7305 /* pIe for black list is following form:
7306 type : 1 byte
7307 length : 1 byte
7308 OUI : 4 bytes
7309 acl type : 1 byte
7310 no of mac addr in black list: 1 byte
7311 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307312 */
7313 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007314 {
7315 pConfig->SapMacaddr_acl = pIe[6];
7316 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007317 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007318 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307319 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7320 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007321 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7322 for (i = 0; i < pConfig->num_deny_mac; i++)
7323 {
7324 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7325 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307326 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007327 }
7328 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7329 pBeacon->tail, pBeacon->tail_len);
7330
7331 /* pIe for white list is following form:
7332 type : 1 byte
7333 length : 1 byte
7334 OUI : 4 bytes
7335 acl type : 1 byte
7336 no of mac addr in white list: 1 byte
7337 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307338 */
7339 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007340 {
7341 pConfig->SapMacaddr_acl = pIe[6];
7342 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007343 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007344 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307345 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7346 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007347 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7348 for (i = 0; i < pConfig->num_accept_mac; i++)
7349 {
7350 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7351 acl_entry++;
7352 }
7353 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307354
Jeff Johnson295189b2012-06-20 16:38:30 -07007355 wlan_hdd_set_sapHwmode(pHostapdAdapter);
7356
Jeff Johnsone7245742012-09-05 17:12:55 -07007357#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007358 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307359 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
7360 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05307361 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
7362 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007363 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
7364 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307365 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
7366 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07007367 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307368 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07007369 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307370 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007371
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307372 /* If ACS disable and selected channel <= 14
7373 * OR
7374 * ACS enabled and ACS operating band is choosen as 2.4
7375 * AND
7376 * VHT in 2.4G Disabled
7377 * THEN
7378 * Fallback to 11N mode
7379 */
7380 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
7381 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05307382 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307383 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007384 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307385 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
7386 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007387 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
7388 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007389 }
7390#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307391
Jeff Johnson295189b2012-06-20 16:38:30 -07007392 // ht_capab is not what the name conveys,this is used for protection bitmap
7393 pConfig->ht_capab =
7394 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
7395
7396 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
7397 {
7398 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7399 return -EINVAL;
7400 }
7401
7402 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307403 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07007404 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
7405 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307406 pConfig->obssProtEnabled =
7407 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07007408
Chet Lanctot8cecea22014-02-11 19:09:36 -08007409#ifdef WLAN_FEATURE_11W
7410 pConfig->mfpCapable = MFPCapable;
7411 pConfig->mfpRequired = MFPRequired;
7412 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
7413 pConfig->mfpCapable, pConfig->mfpRequired);
7414#endif
7415
Arif Hussain6d2a3322013-11-17 19:50:10 -08007416 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07007417 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007418 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
7419 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7420 (int)pConfig->channel);
7421 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
7422 pConfig->SapHw_mode, pConfig->privacy,
7423 pConfig->authType);
7424 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
7425 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7426 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7427 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07007428
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307429 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007430 {
7431 //Bss already started. just return.
7432 //TODO Probably it should update some beacon params.
7433 hddLog( LOGE, "Bss Already started...Ignore the request");
7434 EXIT();
7435 return 0;
7436 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307437
Agarwal Ashish51325b52014-06-16 16:50:49 +05307438 if (vos_max_concurrent_connections_reached()) {
7439 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7440 return -EINVAL;
7441 }
7442
Jeff Johnson295189b2012-06-20 16:38:30 -07007443 pConfig->persona = pHostapdAdapter->device_mode;
7444
Peng Xu2446a892014-09-05 17:21:18 +05307445 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
7446 if ( NULL != psmeConfig)
7447 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307448 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05307449 sme_GetConfigParam(hHal, psmeConfig);
7450 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307451#ifdef WLAN_FEATURE_AP_HT40_24G
7452 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7453 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
7454 && pHddCtx->cfg_ini->apHT40_24GEnabled)
7455 {
7456 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
7457 sme_UpdateConfig (hHal, psmeConfig);
7458 }
7459#endif
Peng Xu2446a892014-09-05 17:21:18 +05307460 vos_mem_free(psmeConfig);
7461 }
Peng Xuafc34e32014-09-25 13:23:55 +05307462 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05307463
Jeff Johnson295189b2012-06-20 16:38:30 -07007464 pSapEventCallback = hdd_hostapd_SAPEventCB;
7465 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
7466 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
7467 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007468 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007469 return -EINVAL;
7470 }
7471
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307472 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07007473 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7474
7475 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307476
Jeff Johnson295189b2012-06-20 16:38:30 -07007477 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307478 {
7479 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007480 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07007481 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07007482 VOS_ASSERT(0);
7483 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307484
Jeff Johnson295189b2012-06-20 16:38:30 -07007485 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05307486 /* Initialize WMM configuation */
7487 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307488 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007489
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007490#ifdef WLAN_FEATURE_P2P_DEBUG
7491 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
7492 {
7493 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
7494 {
7495 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7496 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007497 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007498 }
7499 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
7500 {
7501 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7502 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007503 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007504 }
7505 }
7506#endif
7507
Jeff Johnson295189b2012-06-20 16:38:30 -07007508 pHostapdState->bCommit = TRUE;
7509 EXIT();
7510
7511 return 0;
7512}
7513
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007514#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307515static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307516 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007517 struct beacon_parameters *params)
7518{
7519 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307520 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307521 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007522
7523 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307524
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307525 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7526 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
7527 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307528 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
7529 hdd_device_modetoString(pAdapter->device_mode),
7530 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007531
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307532 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7533 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307534 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007535 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307536 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007537 }
7538
Agarwal Ashish51325b52014-06-16 16:50:49 +05307539 if (vos_max_concurrent_connections_reached()) {
7540 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7541 return -EINVAL;
7542 }
7543
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307544 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007545 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007546 )
7547 {
7548 beacon_data_t *old,*new;
7549
7550 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307551
Jeff Johnson295189b2012-06-20 16:38:30 -07007552 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307553 {
7554 hddLog(VOS_TRACE_LEVEL_WARN,
7555 FL("already beacon info added to session(%d)"),
7556 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007557 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307558 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007559
7560 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7561
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307562 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07007563 {
7564 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007565 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007566 return -EINVAL;
7567 }
7568
7569 pAdapter->sessionCtx.ap.beacon = new;
7570
7571 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7572 }
7573
7574 EXIT();
7575 return status;
7576}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307577
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307578static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
7579 struct net_device *dev,
7580 struct beacon_parameters *params)
7581{
7582 int ret;
7583
7584 vos_ssr_protect(__func__);
7585 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
7586 vos_ssr_unprotect(__func__);
7587
7588 return ret;
7589}
7590
7591static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007592 struct net_device *dev,
7593 struct beacon_parameters *params)
7594{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307595 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307596 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7597 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307598 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007599
7600 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307601
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307602 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7603 TRACE_CODE_HDD_CFG80211_SET_BEACON,
7604 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
7605 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7606 __func__, hdd_device_modetoString(pAdapter->device_mode),
7607 pAdapter->device_mode);
7608
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307609 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7610 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307611 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007612 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307613 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007614 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307615
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307616 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007617 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307618 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007619 {
7620 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307621
Jeff Johnson295189b2012-06-20 16:38:30 -07007622 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307623
Jeff Johnson295189b2012-06-20 16:38:30 -07007624 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307625 {
7626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7627 FL("session(%d) old and new heads points to NULL"),
7628 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007629 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307630 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007631
7632 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7633
7634 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307635 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007636 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007637 return -EINVAL;
7638 }
7639
7640 pAdapter->sessionCtx.ap.beacon = new;
7641
7642 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7643 }
7644
7645 EXIT();
7646 return status;
7647}
7648
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307649static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
7650 struct net_device *dev,
7651 struct beacon_parameters *params)
7652{
7653 int ret;
7654
7655 vos_ssr_protect(__func__);
7656 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
7657 vos_ssr_unprotect(__func__);
7658
7659 return ret;
7660}
7661
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007662#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7663
7664#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307665static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007666 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007667#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307668static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007669 struct net_device *dev)
7670#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007671{
7672 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07007673 hdd_context_t *pHddCtx = NULL;
7674 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307675 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307676 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007677
7678 ENTER();
7679
7680 if (NULL == pAdapter)
7681 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307682 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007683 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007684 return -ENODEV;
7685 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007686
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307687 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7688 TRACE_CODE_HDD_CFG80211_STOP_AP,
7689 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307690 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7691 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307692 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007693 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307694 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07007695 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007696
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007697 pScanInfo = &pHddCtx->scan_info;
7698
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307699 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7700 __func__, hdd_device_modetoString(pAdapter->device_mode),
7701 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007702
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307703 ret = wlan_hdd_scan_abort(pAdapter);
7704
Girish Gowli4bf7a632014-06-12 13:42:11 +05307705 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07007706 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7708 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307709
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307710 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07007711 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307712 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7713 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08007714
Jeff Johnsone7245742012-09-05 17:12:55 -07007715 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307716 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07007717 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307718 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07007719 }
7720
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05307721 /* Delete all associated STAs before stopping AP/P2P GO */
7722 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05307723 hdd_hostapd_stop(dev);
7724
Jeff Johnson295189b2012-06-20 16:38:30 -07007725 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007726 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007727 )
7728 {
7729 beacon_data_t *old;
7730
7731 old = pAdapter->sessionCtx.ap.beacon;
7732
7733 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307734 {
7735 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7736 FL("session(%d) beacon data points to NULL"),
7737 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007738 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307739 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007740
Jeff Johnson295189b2012-06-20 16:38:30 -07007741 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007742
7743 mutex_lock(&pHddCtx->sap_lock);
7744 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7745 {
Jeff Johnson4416a782013-03-25 14:17:50 -07007746 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007747 {
7748 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7749
7750 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7751
7752 if (!VOS_IS_STATUS_SUCCESS(status))
7753 {
7754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007755 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007756 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307757 }
7758 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007759 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307760 /* BSS stopped, clear the active sessions for this device mode */
7761 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007762 }
7763 mutex_unlock(&pHddCtx->sap_lock);
7764
7765 if(status != VOS_STATUS_SUCCESS)
7766 {
7767 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007768 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007769 return -EINVAL;
7770 }
7771
Jeff Johnson4416a782013-03-25 14:17:50 -07007772 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007773 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
7774 ==eHAL_STATUS_FAILURE)
7775 {
7776 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007777 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007778 }
7779
Jeff Johnson4416a782013-03-25 14:17:50 -07007780 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007781 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7782 eANI_BOOLEAN_FALSE) )
7783 {
7784 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007785 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007786 }
7787
7788 // Reset WNI_CFG_PROBE_RSP Flags
7789 wlan_hdd_reset_prob_rspies(pAdapter);
7790
7791 pAdapter->sessionCtx.ap.beacon = NULL;
7792 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007793#ifdef WLAN_FEATURE_P2P_DEBUG
7794 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7795 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
7796 {
7797 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
7798 "GO got removed");
7799 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
7800 }
7801#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007802 }
7803 EXIT();
7804 return status;
7805}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007806
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307807#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7808static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
7809 struct net_device *dev)
7810{
7811 int ret;
7812
7813 vos_ssr_protect(__func__);
7814 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
7815 vos_ssr_unprotect(__func__);
7816
7817 return ret;
7818}
7819#else
7820static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7821 struct net_device *dev)
7822{
7823 int ret;
7824
7825 vos_ssr_protect(__func__);
7826 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7827 vos_ssr_unprotect(__func__);
7828
7829 return ret;
7830}
7831#endif
7832
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007833#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7834
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307835static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307836 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007837 struct cfg80211_ap_settings *params)
7838{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307839 hdd_adapter_t *pAdapter;
7840 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307841 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007842
7843 ENTER();
7844
Girish Gowlib143d7a2015-02-18 19:39:55 +05307845 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007846 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05307848 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307849 return -ENODEV;
7850 }
7851
7852 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7853 if (NULL == pAdapter)
7854 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307856 "%s: HDD adapter is Null", __func__);
7857 return -ENODEV;
7858 }
7859
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307860 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7861 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
7862 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307863 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7864 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307866 "%s: HDD adapter magic is invalid", __func__);
7867 return -ENODEV;
7868 }
7869
7870 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307871 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307872 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307873 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307874 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307875 }
7876
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307877 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7878 __func__, hdd_device_modetoString(pAdapter->device_mode),
7879 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307880
7881 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007882 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007883 )
7884 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307885 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007886
7887 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307888
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007889 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307890 {
7891 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7892 FL("already beacon info added to session(%d)"),
7893 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007894 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307895 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007896
Girish Gowlib143d7a2015-02-18 19:39:55 +05307897#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7898 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7899 &new,
7900 &params->beacon);
7901#else
7902 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7903 &new,
7904 &params->beacon,
7905 params->dtim_period);
7906#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007907
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307908 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007909 {
7910 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307911 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007912 return -EINVAL;
7913 }
7914 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007915#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007916 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7917#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7918 params->channel, params->channel_type);
7919#else
7920 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7921#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007922#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007923 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307924 params->ssid_len, params->hidden_ssid,
7925 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007926 }
7927
7928 EXIT();
7929 return status;
7930}
7931
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307932static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7933 struct net_device *dev,
7934 struct cfg80211_ap_settings *params)
7935{
7936 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007937
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307938 vos_ssr_protect(__func__);
7939 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
7940 vos_ssr_unprotect(__func__);
7941
7942 return ret;
7943}
7944
7945static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007946 struct net_device *dev,
7947 struct cfg80211_beacon_data *params)
7948{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307949 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307950 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307951 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007952
7953 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307954
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307955 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7956 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7957 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007958 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007959 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307960
7961 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7962 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307963 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007964 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307965 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007966 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007967
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307968 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007969 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307970 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007971 {
7972 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307973
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007974 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307975
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007976 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307977 {
7978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7979 FL("session(%d) beacon data points to NULL"),
7980 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007981 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307982 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007983
7984 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
7985
7986 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307987 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007988 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007989 return -EINVAL;
7990 }
7991
7992 pAdapter->sessionCtx.ap.beacon = new;
7993
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307994 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
7995 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007996 }
7997
7998 EXIT();
7999 return status;
8000}
8001
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308002static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8003 struct net_device *dev,
8004 struct cfg80211_beacon_data *params)
8005{
8006 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008007
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308008 vos_ssr_protect(__func__);
8009 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8010 vos_ssr_unprotect(__func__);
8011
8012 return ret;
8013}
8014
8015#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008016
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308017static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008018 struct net_device *dev,
8019 struct bss_parameters *params)
8020{
8021 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308022 hdd_context_t *pHddCtx;
8023 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008024
8025 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308026
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308027 if (NULL == pAdapter)
8028 {
8029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8030 "%s: HDD adapter is Null", __func__);
8031 return -ENODEV;
8032 }
8033 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308034 ret = wlan_hdd_validate_context(pHddCtx);
8035 if (0 != ret)
8036 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308037 return ret;
8038 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308039 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8040 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
8041 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308042 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8043 __func__, hdd_device_modetoString(pAdapter->device_mode),
8044 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008045
8046 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008047 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308048 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008049 {
8050 /* ap_isolate == -1 means that in change bss, upper layer doesn't
8051 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308052 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07008053 {
8054 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308055 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008056 }
8057
8058 EXIT();
8059 return 0;
8060}
8061
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308062static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
8063 struct net_device *dev,
8064 struct bss_parameters *params)
8065{
8066 int ret;
8067
8068 vos_ssr_protect(__func__);
8069 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
8070 vos_ssr_unprotect(__func__);
8071
8072 return ret;
8073}
Kiet Lam10841362013-11-01 11:36:50 +05308074/* FUNCTION: wlan_hdd_change_country_code_cd
8075* to wait for contry code completion
8076*/
8077void* wlan_hdd_change_country_code_cb(void *pAdapter)
8078{
8079 hdd_adapter_t *call_back_pAdapter = pAdapter;
8080 complete(&call_back_pAdapter->change_country_code);
8081 return NULL;
8082}
8083
Jeff Johnson295189b2012-06-20 16:38:30 -07008084/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308085 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07008086 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
8087 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308088int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008089 struct net_device *ndev,
8090 enum nl80211_iftype type,
8091 u32 *flags,
8092 struct vif_params *params
8093 )
8094{
8095 struct wireless_dev *wdev;
8096 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008097 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07008098 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008099 tCsrRoamProfile *pRoamProfile = NULL;
8100 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308101 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008102 eMib_dot11DesiredBssType connectedBssType;
8103 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308104 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008105
8106 ENTER();
8107
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308108 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008109 {
8110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8111 "%s: Adapter context is null", __func__);
8112 return VOS_STATUS_E_FAILURE;
8113 }
8114
8115 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8116 if (!pHddCtx)
8117 {
8118 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8119 "%s: HDD context is null", __func__);
8120 return VOS_STATUS_E_FAILURE;
8121 }
8122
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308123 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8124 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
8125 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308126 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308127 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07008128 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308129 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008130 }
8131
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308132 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8133 __func__, hdd_device_modetoString(pAdapter->device_mode),
8134 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008135
Agarwal Ashish51325b52014-06-16 16:50:49 +05308136 if (vos_max_concurrent_connections_reached()) {
8137 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8138 return -EINVAL;
8139 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308140 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07008141 wdev = ndev->ieee80211_ptr;
8142
8143#ifdef WLAN_BTAMP_FEATURE
8144 if((NL80211_IFTYPE_P2P_CLIENT == type)||
8145 (NL80211_IFTYPE_ADHOC == type)||
8146 (NL80211_IFTYPE_AP == type)||
8147 (NL80211_IFTYPE_P2P_GO == type))
8148 {
8149 pHddCtx->isAmpAllowed = VOS_FALSE;
8150 // stop AMP traffic
8151 status = WLANBAP_StopAmp();
8152 if(VOS_STATUS_SUCCESS != status )
8153 {
8154 pHddCtx->isAmpAllowed = VOS_TRUE;
8155 hddLog(VOS_TRACE_LEVEL_FATAL,
8156 "%s: Failed to stop AMP", __func__);
8157 return -EINVAL;
8158 }
8159 }
8160#endif //WLAN_BTAMP_FEATURE
8161 /* Reset the current device mode bit mask*/
8162 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8163
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +05308164 /* Notify Mode change in case of concurrency.
8165 * Below function invokes TDLS teardown Functionality Since TDLS is
8166 * not Supported in case of concurrency i.e Once P2P session
8167 * is detected disable offchannel and teardown TDLS links
8168 */
8169 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
8170
Jeff Johnson295189b2012-06-20 16:38:30 -07008171 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008172 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07008173 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008174 )
8175 {
8176 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008177 if (!pWextState)
8178 {
8179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8180 "%s: pWextState is null", __func__);
8181 return VOS_STATUS_E_FAILURE;
8182 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008183 pRoamProfile = &pWextState->roamProfile;
8184 LastBSSType = pRoamProfile->BSSType;
8185
8186 switch (type)
8187 {
8188 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008189 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008190 hddLog(VOS_TRACE_LEVEL_INFO,
8191 "%s: setting interface Type to INFRASTRUCTURE", __func__);
8192 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008193#ifdef WLAN_FEATURE_11AC
8194 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
8195 {
8196 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
8197 }
8198#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308199 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07008200 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008201 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008202 //Check for sub-string p2p to confirm its a p2p interface
8203 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308204 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008205 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8206 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8207 }
8208 else
8209 {
8210 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008211 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008212 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008213 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05308214
Jeff Johnson295189b2012-06-20 16:38:30 -07008215 case NL80211_IFTYPE_ADHOC:
8216 hddLog(VOS_TRACE_LEVEL_INFO,
8217 "%s: setting interface Type to ADHOC", __func__);
8218 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
8219 pRoamProfile->phyMode =
8220 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07008221 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008222 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05308223 hdd_set_ibss_ops( pAdapter );
8224 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +05308225
8226 status = hdd_sta_id_hash_attach(pAdapter);
8227 if (VOS_STATUS_SUCCESS != status) {
8228 hddLog(VOS_TRACE_LEVEL_ERROR,
8229 FL("Failed to initialize hash for IBSS"));
8230 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008231 break;
8232
8233 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008234 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008235 {
8236 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8237 "%s: setting interface Type to %s", __func__,
8238 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
8239
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008240 //Cancel any remain on channel for GO mode
8241 if (NL80211_IFTYPE_P2P_GO == type)
8242 {
8243 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
8244 }
Mohit Khanna0f232092012-09-11 14:46:08 -07008245 if (NL80211_IFTYPE_AP == type)
8246 {
8247 /* As Loading WLAN Driver one interface being created for p2p device
8248 * address. This will take one HW STA and the max number of clients
8249 * that can connect to softAP will be reduced by one. so while changing
8250 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
8251 * interface as it is not required in SoftAP mode.
8252 */
8253
8254 // Get P2P Adapter
8255 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
8256
8257 if (pP2pAdapter)
8258 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308259 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05308260 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07008261 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
8262 }
8263 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05308264 //Disable IMPS & BMPS for SAP/GO
8265 if(VOS_STATUS_E_FAILURE ==
8266 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
8267 {
8268 //Fail to Exit BMPS
8269 VOS_ASSERT(0);
8270 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05308271
8272 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
8273
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308274#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07008275
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308276 /* A Mutex Lock is introduced while changing the mode to
8277 * protect the concurrent access for the Adapters by TDLS
8278 * module.
8279 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308280 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308281#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008282 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05308283 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008284 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07008285 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8286 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308287#ifdef FEATURE_WLAN_TDLS
8288 mutex_unlock(&pHddCtx->tdls_lock);
8289#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008290 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
8291 (pConfig->apRandomBssidEnabled))
8292 {
8293 /* To meet Android requirements create a randomized
8294 MAC address of the form 02:1A:11:Fx:xx:xx */
8295 get_random_bytes(&ndev->dev_addr[3], 3);
8296 ndev->dev_addr[0] = 0x02;
8297 ndev->dev_addr[1] = 0x1A;
8298 ndev->dev_addr[2] = 0x11;
8299 ndev->dev_addr[3] |= 0xF0;
8300 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
8301 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08008302 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
8303 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008304 }
8305
Jeff Johnson295189b2012-06-20 16:38:30 -07008306 hdd_set_ap_ops( pAdapter->dev );
8307
Kiet Lam10841362013-11-01 11:36:50 +05308308 /* This is for only SAP mode where users can
8309 * control country through ini.
8310 * P2P GO follows station country code
8311 * acquired during the STA scanning. */
8312 if((NL80211_IFTYPE_AP == type) &&
8313 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
8314 {
8315 int status = 0;
8316 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
8317 "%s: setting country code from INI ", __func__);
8318 init_completion(&pAdapter->change_country_code);
8319 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
8320 (void *)(tSmeChangeCountryCallback)
8321 wlan_hdd_change_country_code_cb,
8322 pConfig->apCntryCode, pAdapter,
8323 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308324 eSIR_FALSE,
8325 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05308326 if (eHAL_STATUS_SUCCESS == status)
8327 {
8328 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308329 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05308330 &pAdapter->change_country_code,
8331 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308332 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05308333 {
8334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308335 FL("SME Timed out while setting country code %ld"),
8336 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08008337
8338 if (pHddCtx->isLogpInProgress)
8339 {
8340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8341 "%s: LOGP in Progress. Ignore!!!", __func__);
8342 return -EAGAIN;
8343 }
Kiet Lam10841362013-11-01 11:36:50 +05308344 }
8345 }
8346 else
8347 {
8348 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008349 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05308350 return -EINVAL;
8351 }
8352 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008353 status = hdd_init_ap_mode(pAdapter);
8354 if(status != VOS_STATUS_SUCCESS)
8355 {
8356 hddLog(VOS_TRACE_LEVEL_FATAL,
8357 "%s: Error initializing the ap mode", __func__);
8358 return -EINVAL;
8359 }
8360 hdd_set_conparam(1);
8361
Nirav Shah7e3c8132015-06-22 23:51:42 +05308362 status = hdd_sta_id_hash_attach(pAdapter);
8363 if (VOS_STATUS_SUCCESS != status)
8364 {
8365 hddLog(VOS_TRACE_LEVEL_ERROR,
8366 FL("Failed to initialize hash for AP"));
8367 return -EINVAL;
8368 }
8369
Jeff Johnson295189b2012-06-20 16:38:30 -07008370 /*interface type changed update in wiphy structure*/
8371 if(wdev)
8372 {
8373 wdev->iftype = type;
8374 pHddCtx->change_iface = type;
8375 }
8376 else
8377 {
8378 hddLog(VOS_TRACE_LEVEL_ERROR,
8379 "%s: ERROR !!!! Wireless dev is NULL", __func__);
8380 return -EINVAL;
8381 }
8382 goto done;
8383 }
8384
8385 default:
8386 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8387 __func__);
8388 return -EOPNOTSUPP;
8389 }
8390 }
8391 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008392 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008393 )
8394 {
8395 switch(type)
8396 {
8397 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008398 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008399 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05308400
8401 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308402#ifdef FEATURE_WLAN_TDLS
8403
8404 /* A Mutex Lock is introduced while changing the mode to
8405 * protect the concurrent access for the Adapters by TDLS
8406 * module.
8407 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308408 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308409#endif
c_hpothu002231a2015-02-05 14:58:51 +05308410 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008411 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008412 //Check for sub-string p2p to confirm its a p2p interface
8413 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008414 {
8415 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8416 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8417 }
8418 else
8419 {
8420 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008421 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008422 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008423 hdd_set_conparam(0);
8424 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008425 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
8426 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308427#ifdef FEATURE_WLAN_TDLS
8428 mutex_unlock(&pHddCtx->tdls_lock);
8429#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308430 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008431 if( VOS_STATUS_SUCCESS != status )
8432 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07008433 /* In case of JB, for P2P-GO, only change interface will be called,
8434 * This is the right place to enable back bmps_imps()
8435 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308436 if (pHddCtx->hdd_wlan_suspended)
8437 {
8438 hdd_set_pwrparams(pHddCtx);
8439 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008440 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008441 goto done;
8442 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008443 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008444 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008445 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8446 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008447 goto done;
8448 default:
8449 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8450 __func__);
8451 return -EOPNOTSUPP;
8452
8453 }
8454
8455 }
8456 else
8457 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308458 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
8459 __func__, hdd_device_modetoString(pAdapter->device_mode),
8460 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008461 return -EOPNOTSUPP;
8462 }
8463
8464
8465 if(pRoamProfile)
8466 {
8467 if ( LastBSSType != pRoamProfile->BSSType )
8468 {
8469 /*interface type changed update in wiphy structure*/
8470 wdev->iftype = type;
8471
8472 /*the BSS mode changed, We need to issue disconnect
8473 if connected or in IBSS disconnect state*/
8474 if ( hdd_connGetConnectedBssType(
8475 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
8476 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
8477 {
8478 /*need to issue a disconnect to CSR.*/
8479 INIT_COMPLETION(pAdapter->disconnect_comp_var);
8480 if( eHAL_STATUS_SUCCESS ==
8481 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
8482 pAdapter->sessionId,
8483 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
8484 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308485 ret = wait_for_completion_interruptible_timeout(
8486 &pAdapter->disconnect_comp_var,
8487 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
8488 if (ret <= 0)
8489 {
8490 hddLog(VOS_TRACE_LEVEL_ERROR,
8491 FL("wait on disconnect_comp_var failed %ld"), ret);
8492 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008493 }
8494 }
8495 }
8496 }
8497
8498done:
8499 /*set bitmask based on updated value*/
8500 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07008501
8502 /* Only STA mode support TM now
8503 * all other mode, TM feature should be disabled */
8504 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
8505 (~VOS_STA & pHddCtx->concurrency_mode) )
8506 {
8507 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
8508 }
8509
Jeff Johnson295189b2012-06-20 16:38:30 -07008510#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308511 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05308512 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07008513 {
8514 //we are ok to do AMP
8515 pHddCtx->isAmpAllowed = VOS_TRUE;
8516 }
8517#endif //WLAN_BTAMP_FEATURE
8518 EXIT();
8519 return 0;
8520}
8521
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308522/*
8523 * FUNCTION: wlan_hdd_cfg80211_change_iface
8524 * wrapper function to protect the actual implementation from SSR.
8525 */
8526int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
8527 struct net_device *ndev,
8528 enum nl80211_iftype type,
8529 u32 *flags,
8530 struct vif_params *params
8531 )
8532{
8533 int ret;
8534
8535 vos_ssr_protect(__func__);
8536 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
8537 vos_ssr_unprotect(__func__);
8538
8539 return ret;
8540}
8541
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008542#ifdef FEATURE_WLAN_TDLS
8543static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
8544 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
8545{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008546 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008547 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308548 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308549 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308550 hdd_adapter_t *pAdapter;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008551
8552 ENTER();
8553
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308554 if (!dev) {
8555 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
8556 return -EINVAL;
8557 }
8558
8559 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8560 if (!pAdapter) {
8561 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
8562 return -EINVAL;
8563 }
8564
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308565 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008566 {
8567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8568 "Invalid arguments");
8569 return -EINVAL;
8570 }
Hoonki Lee27511902013-03-14 18:19:06 -07008571
8572 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
8573 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
8574 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07008576 "%s: TDLS mode is disabled OR not enabled in FW."
8577 MAC_ADDRESS_STR " Request declined.",
8578 __func__, MAC_ADDR_ARRAY(mac));
8579 return -ENOTSUPP;
8580 }
8581
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008582 if (pHddCtx->isLogpInProgress)
8583 {
8584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8585 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05308586 wlan_hdd_tdls_set_link_status(pAdapter,
8587 mac,
8588 eTDLS_LINK_IDLE,
8589 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008590 return -EBUSY;
8591 }
8592
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308593 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05308594 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008595
8596 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308597 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008598 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
8599 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308600 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008601 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008602 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308603 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008604
8605 /* in add station, we accept existing valid staId if there is */
8606 if ((0 == update) &&
8607 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
8608 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008609 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308610 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008611 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008612 " link_status %d. staId %d. add station ignored.",
8613 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
8614 return 0;
8615 }
8616 /* in change station, we accept only when staId is valid */
8617 if ((1 == update) &&
8618 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
8619 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
8620 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008622 "%s: " MAC_ADDRESS_STR
8623 " link status %d. staId %d. change station %s.",
8624 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
8625 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
8626 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008627 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008628
8629 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05308630 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008631 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008632 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8633 "%s: " MAC_ADDRESS_STR
8634 " TDLS setup is ongoing. Request declined.",
8635 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07008636 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008637 }
8638
8639 /* first to check if we reached to maximum supported TDLS peer.
8640 TODO: for now, return -EPERM looks working fine,
8641 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308642 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8643 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008644 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8646 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308647 " TDLS Max peer already connected. Request declined."
8648 " Num of peers (%d), Max allowed (%d).",
8649 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
8650 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008651 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008652 }
8653 else
8654 {
8655 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308656 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008657 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008658 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8660 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
8661 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008662 return -EPERM;
8663 }
8664 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008665 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05308666 wlan_hdd_tdls_set_link_status(pAdapter,
8667 mac,
8668 eTDLS_LINK_CONNECTING,
8669 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008670
Jeff Johnsond75fe012013-04-06 10:53:06 -07008671 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308672 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008673 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008675 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008676 if(StaParams->htcap_present)
8677 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008679 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008681 "ht_capa->extended_capabilities: %0x",
8682 StaParams->HTCap.extendedHtCapInfo);
8683 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008685 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308686 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008687 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008688 if(StaParams->vhtcap_present)
8689 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008691 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
8692 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
8693 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
8694 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008695 {
8696 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008697 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008698 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308699 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008700 "[%d]: %x ", i, StaParams->supported_rates[i]);
8701 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07008702 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308703 else if ((1 == update) && (NULL == StaParams))
8704 {
8705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8706 "%s : update is true, but staParams is NULL. Error!", __func__);
8707 return -EPERM;
8708 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008709
8710 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
8711
8712 if (!update)
8713 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308714 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008715 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308716 if (ret != eHAL_STATUS_SUCCESS) {
8717 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to add TDLS peer STA"));
8718 return -EPERM;
8719 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008720 }
8721 else
8722 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308723 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008724 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308725 if (ret != eHAL_STATUS_SUCCESS) {
8726 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
8727 return -EPERM;
8728 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008729 }
8730
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308731 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008732 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
8733
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308734 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008735 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308737 "%s: timeout waiting for tdls add station indication %ld",
8738 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008739 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008740 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308741
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008742 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
8743 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008745 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008746 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008747 }
8748
8749 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008750
8751error:
Atul Mittal115287b2014-07-08 13:26:33 +05308752 wlan_hdd_tdls_set_link_status(pAdapter,
8753 mac,
8754 eTDLS_LINK_IDLE,
8755 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008756 return -EPERM;
8757
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008758}
8759#endif
8760
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308761static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008762 struct net_device *dev,
8763 u8 *mac,
8764 struct station_parameters *params)
8765{
8766 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308767 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308768 hdd_context_t *pHddCtx;
8769 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008770 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308771 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008772#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008773 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008774 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308775 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008776#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008777
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308778 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308779
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308780 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308781 if ((NULL == pAdapter))
8782 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308784 "invalid adapter ");
8785 return -EINVAL;
8786 }
8787
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308788 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8789 TRACE_CODE_HDD_CHANGE_STATION,
8790 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05308791 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308792
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308793 ret = wlan_hdd_validate_context(pHddCtx);
8794 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05308795 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308796 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308797 }
8798
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308799 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8800
8801 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008802 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8804 "invalid HDD station context");
8805 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008806 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008807 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
8808
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008809 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8810 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07008811 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008812 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07008813 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308814 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07008815 WLANTL_STA_AUTHENTICATED);
8816
Gopichand Nakkala29149562013-05-10 21:43:41 +05308817 if (status != VOS_STATUS_SUCCESS)
8818 {
8819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8820 "%s: Not able to change TL state to AUTHENTICATED", __func__);
8821 return -EINVAL;
8822 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008823 }
8824 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07008825 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8826 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308827#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008828 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8829 StaParams.capability = params->capability;
8830 StaParams.uapsd_queues = params->uapsd_queues;
8831 StaParams.max_sp = params->max_sp;
8832
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308833 /* Convert (first channel , number of channels) tuple to
8834 * the total list of channels. This goes with the assumption
8835 * that if the first channel is < 14, then the next channels
8836 * are an incremental of 1 else an incremental of 4 till the number
8837 * of channels.
8838 */
8839 if (0 != params->supported_channels_len) {
8840 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
8841 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
8842 {
8843 int wifi_chan_index;
8844 StaParams.supported_channels[j] = params->supported_channels[i];
8845 wifi_chan_index =
8846 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
8847 no_of_channels = params->supported_channels[i+1];
8848 for(k=1; k <= no_of_channels; k++)
8849 {
8850 StaParams.supported_channels[j+1] =
8851 StaParams.supported_channels[j] + wifi_chan_index;
8852 j+=1;
8853 }
8854 }
8855 StaParams.supported_channels_len = j;
8856 }
8857 vos_mem_copy(StaParams.supported_oper_classes,
8858 params->supported_oper_classes,
8859 params->supported_oper_classes_len);
8860 StaParams.supported_oper_classes_len =
8861 params->supported_oper_classes_len;
8862
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008863 if (0 != params->ext_capab_len)
8864 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
8865 sizeof(StaParams.extn_capability));
8866
8867 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008868 {
8869 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008870 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008871 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008872
8873 StaParams.supported_rates_len = params->supported_rates_len;
8874
8875 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
8876 * The supported_rates array , for all the structures propogating till Add Sta
8877 * to the firmware has to be modified , if the supplicant (ieee80211) is
8878 * modified to send more rates.
8879 */
8880
8881 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
8882 */
8883 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
8884 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
8885
8886 if (0 != StaParams.supported_rates_len) {
8887 int i = 0;
8888 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
8889 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008890 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008891 "Supported Rates with Length %d", StaParams.supported_rates_len);
8892 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008894 "[%d]: %0x", i, StaParams.supported_rates[i]);
8895 }
8896
8897 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008898 {
8899 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008900 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008901 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008902
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008903 if (0 != params->ext_capab_len ) {
8904 /*Define A Macro : TODO Sunil*/
8905 if ((1<<4) & StaParams.extn_capability[3]) {
8906 isBufSta = 1;
8907 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308908 /* TDLS Channel Switching Support */
8909 if ((1<<6) & StaParams.extn_capability[3]) {
8910 isOffChannelSupported = 1;
8911 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008912 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308913 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
8914 &StaParams, isBufSta,
8915 isOffChannelSupported);
8916
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308917 if (VOS_STATUS_SUCCESS != status) {
8918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8919 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
8920 return -EINVAL;
8921 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008922 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
8923
8924 if (VOS_STATUS_SUCCESS != status) {
8925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8926 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
8927 return -EINVAL;
8928 }
8929 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008930#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05308931 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008932 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008933 return status;
8934}
8935
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308936static int wlan_hdd_change_station(struct wiphy *wiphy,
8937 struct net_device *dev,
8938 u8 *mac,
8939 struct station_parameters *params)
8940{
8941 int ret;
8942
8943 vos_ssr_protect(__func__);
8944 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
8945 vos_ssr_unprotect(__func__);
8946
8947 return ret;
8948}
8949
Jeff Johnson295189b2012-06-20 16:38:30 -07008950/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308951 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008952 * This function is used to initialize the key information
8953 */
8954#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308955static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008956 struct net_device *ndev,
8957 u8 key_index, bool pairwise,
8958 const u8 *mac_addr,
8959 struct key_params *params
8960 )
8961#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308962static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008963 struct net_device *ndev,
8964 u8 key_index, const u8 *mac_addr,
8965 struct key_params *params
8966 )
8967#endif
8968{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008969 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07008970 tCsrRoamSetKey setKey;
8971 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308972 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008973 v_U32_t roamId= 0xFF;
8974 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008975 hdd_hostapd_state_t *pHostapdState;
8976 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008977 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308978 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008979
8980 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308981
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308982 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8983 TRACE_CODE_HDD_CFG80211_ADD_KEY,
8984 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308985 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8986 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308987 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008988 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308989 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008990 }
8991
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308992 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8993 __func__, hdd_device_modetoString(pAdapter->device_mode),
8994 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008995
8996 if (CSR_MAX_NUM_KEY <= key_index)
8997 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008998 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008999 key_index);
9000
9001 return -EINVAL;
9002 }
9003
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009004 if (CSR_MAX_KEY_LEN < params->key_len)
9005 {
9006 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
9007 params->key_len);
9008
9009 return -EINVAL;
9010 }
9011
9012 hddLog(VOS_TRACE_LEVEL_INFO,
9013 "%s: called with key index = %d & key length %d",
9014 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009015
9016 /*extract key idx, key len and key*/
9017 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9018 setKey.keyId = key_index;
9019 setKey.keyLength = params->key_len;
9020 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
9021
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009022 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009023 {
9024 case WLAN_CIPHER_SUITE_WEP40:
9025 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
9026 break;
9027
9028 case WLAN_CIPHER_SUITE_WEP104:
9029 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
9030 break;
9031
9032 case WLAN_CIPHER_SUITE_TKIP:
9033 {
9034 u8 *pKey = &setKey.Key[0];
9035 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
9036
9037 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
9038
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009039 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07009040
9041 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009042 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009043 |--------------|----------|----------|
9044 <---16bytes---><--8bytes--><--8bytes-->
9045
9046 */
9047 /*Sme expects the 32 bytes key to be in the below order
9048
9049 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009050 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009051 |--------------|----------|----------|
9052 <---16bytes---><--8bytes--><--8bytes-->
9053 */
9054 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009055 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07009056
9057 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009058 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009059
9060 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009061 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009062
9063
9064 break;
9065 }
9066
9067 case WLAN_CIPHER_SUITE_CCMP:
9068 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
9069 break;
9070
9071#ifdef FEATURE_WLAN_WAPI
9072 case WLAN_CIPHER_SUITE_SMS4:
9073 {
9074 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9075 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
9076 params->key, params->key_len);
9077 return 0;
9078 }
9079#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009080
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009081#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009082 case WLAN_CIPHER_SUITE_KRK:
9083 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
9084 break;
9085#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009086
9087#ifdef WLAN_FEATURE_11W
9088 case WLAN_CIPHER_SUITE_AES_CMAC:
9089 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07009090 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07009091#endif
9092
Jeff Johnson295189b2012-06-20 16:38:30 -07009093 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009094 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009095 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309096 status = -EOPNOTSUPP;
9097 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009098 }
9099
9100 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
9101 __func__, setKey.encType);
9102
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009103 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07009104#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9105 (!pairwise)
9106#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009107 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07009108#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009109 )
9110 {
9111 /* set group key*/
9112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9113 "%s- %d: setting Broadcast key",
9114 __func__, __LINE__);
9115 setKey.keyDirection = eSIR_RX_ONLY;
9116 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9117 }
9118 else
9119 {
9120 /* set pairwise key*/
9121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9122 "%s- %d: setting pairwise key",
9123 __func__, __LINE__);
9124 setKey.keyDirection = eSIR_TX_RX;
9125 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9126 }
9127 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
9128 {
9129 setKey.keyDirection = eSIR_TX_RX;
9130 /*Set the group key*/
9131 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9132 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07009133
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009134 if ( 0 != status )
9135 {
9136 hddLog(VOS_TRACE_LEVEL_ERROR,
9137 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309138 status = -EINVAL;
9139 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009140 }
9141 /*Save the keys here and call sme_RoamSetKey for setting
9142 the PTK after peer joins the IBSS network*/
9143 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
9144 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309145 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009146 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05309147 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
9148 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
9149 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009150 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009151 if( pHostapdState->bssState == BSS_START )
9152 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009153 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9154 vos_status = wlan_hdd_check_ula_done(pAdapter);
9155
9156 if ( vos_status != VOS_STATUS_SUCCESS )
9157 {
9158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9159 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9160 __LINE__, vos_status );
9161
9162 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9163
9164 status = -EINVAL;
9165 goto end;
9166 }
9167
Jeff Johnson295189b2012-06-20 16:38:30 -07009168 status = WLANSAP_SetKeySta( pVosContext, &setKey);
9169
9170 if ( status != eHAL_STATUS_SUCCESS )
9171 {
9172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9173 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9174 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309175 status = -EINVAL;
9176 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009177 }
9178 }
9179
9180 /* Saving WEP keys */
9181 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
9182 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
9183 {
9184 //Save the wep key in ap context. Issue setkey after the BSS is started.
9185 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9186 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
9187 }
9188 else
9189 {
9190 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009191 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009192 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
9193 }
9194 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009195 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
9196 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009197 {
9198 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9199 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9200
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309201#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9202 if (!pairwise)
9203#else
9204 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9205#endif
9206 {
9207 /* set group key*/
9208 if (pHddStaCtx->roam_info.deferKeyComplete)
9209 {
9210 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9211 "%s- %d: Perform Set key Complete",
9212 __func__, __LINE__);
9213 hdd_PerformRoamSetKeyComplete(pAdapter);
9214 }
9215 }
9216
Jeff Johnson295189b2012-06-20 16:38:30 -07009217 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
9218
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08009219 pWextState->roamProfile.Keys.defaultIndex = key_index;
9220
9221
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009222 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009223 params->key, params->key_len);
9224
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309225
Jeff Johnson295189b2012-06-20 16:38:30 -07009226 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9227
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309228 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009229 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309230 __func__, setKey.peerMac[0], setKey.peerMac[1],
9231 setKey.peerMac[2], setKey.peerMac[3],
9232 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009233 setKey.keyDirection);
9234
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009235 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +05309236
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009237 if ( vos_status != VOS_STATUS_SUCCESS )
9238 {
9239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009240 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9241 __LINE__, vos_status );
9242
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009243 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009244
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009245 status = -EINVAL;
9246 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009247
9248 }
9249
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009250#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309251 /* The supplicant may attempt to set the PTK once pre-authentication
9252 is done. Save the key in the UMAC and include it in the ADD BSS
9253 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009254 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309255 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009256 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309257 hddLog(VOS_TRACE_LEVEL_INFO_MED,
9258 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309259 status = 0;
9260 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309261 }
9262 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
9263 {
9264 hddLog(VOS_TRACE_LEVEL_ERROR,
9265 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309266 status = -EINVAL;
9267 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009268 }
9269#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07009270
9271 /* issue set key request to SME*/
9272 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9273 pAdapter->sessionId, &setKey, &roamId );
9274
9275 if ( 0 != status )
9276 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309277 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009278 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
9279 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309280 status = -EINVAL;
9281 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009282 }
9283
9284
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309285 /* in case of IBSS as there was no information available about WEP keys during
9286 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07009287 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309288 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
9289 !( ( IW_AUTH_KEY_MGMT_802_1X
9290 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07009291 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
9292 )
9293 &&
9294 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
9295 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
9296 )
9297 )
9298 {
9299 setKey.keyDirection = eSIR_RX_ONLY;
9300 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9301
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309302 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009303 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309304 __func__, setKey.peerMac[0], setKey.peerMac[1],
9305 setKey.peerMac[2], setKey.peerMac[3],
9306 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009307 setKey.keyDirection);
9308
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309309 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009310 pAdapter->sessionId, &setKey, &roamId );
9311
9312 if ( 0 != status )
9313 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309314 hddLog(VOS_TRACE_LEVEL_ERROR,
9315 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009316 __func__, status);
9317 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309318 status = -EINVAL;
9319 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009320 }
9321 }
9322 }
9323
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309324end:
9325 /* Need to clear any trace of key value in the memory.
9326 * Thus zero out the memory even though it is local
9327 * variable.
9328 */
9329 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309330 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309331 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009332}
9333
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309334#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9335static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9336 struct net_device *ndev,
9337 u8 key_index, bool pairwise,
9338 const u8 *mac_addr,
9339 struct key_params *params
9340 )
9341#else
9342static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9343 struct net_device *ndev,
9344 u8 key_index, const u8 *mac_addr,
9345 struct key_params *params
9346 )
9347#endif
9348{
9349 int ret;
9350 vos_ssr_protect(__func__);
9351#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9352 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
9353 mac_addr, params);
9354#else
9355 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
9356 params);
9357#endif
9358 vos_ssr_unprotect(__func__);
9359
9360 return ret;
9361}
9362
Jeff Johnson295189b2012-06-20 16:38:30 -07009363/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309364 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009365 * This function is used to get the key information
9366 */
9367#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309368static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309369 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009370 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309371 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009372 const u8 *mac_addr, void *cookie,
9373 void (*callback)(void *cookie, struct key_params*)
9374 )
9375#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309376static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309377 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009378 struct net_device *ndev,
9379 u8 key_index, const u8 *mac_addr, void *cookie,
9380 void (*callback)(void *cookie, struct key_params*)
9381 )
9382#endif
9383{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309384 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309385 hdd_wext_state_t *pWextState = NULL;
9386 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009387 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309388 hdd_context_t *pHddCtx;
9389 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009390
9391 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309392
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309393 if (NULL == pAdapter)
9394 {
9395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9396 "%s: HDD adapter is Null", __func__);
9397 return -ENODEV;
9398 }
9399
9400 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9401 ret = wlan_hdd_validate_context(pHddCtx);
9402 if (0 != ret)
9403 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309404 return ret;
9405 }
9406
9407 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9408 pRoamProfile = &(pWextState->roamProfile);
9409
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309410 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9411 __func__, hdd_device_modetoString(pAdapter->device_mode),
9412 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309413
Jeff Johnson295189b2012-06-20 16:38:30 -07009414 memset(&params, 0, sizeof(params));
9415
9416 if (CSR_MAX_NUM_KEY <= key_index)
9417 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309418 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07009419 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309420 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009421
9422 switch(pRoamProfile->EncryptionType.encryptionType[0])
9423 {
9424 case eCSR_ENCRYPT_TYPE_NONE:
9425 params.cipher = IW_AUTH_CIPHER_NONE;
9426 break;
9427
9428 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
9429 case eCSR_ENCRYPT_TYPE_WEP40:
9430 params.cipher = WLAN_CIPHER_SUITE_WEP40;
9431 break;
9432
9433 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
9434 case eCSR_ENCRYPT_TYPE_WEP104:
9435 params.cipher = WLAN_CIPHER_SUITE_WEP104;
9436 break;
9437
9438 case eCSR_ENCRYPT_TYPE_TKIP:
9439 params.cipher = WLAN_CIPHER_SUITE_TKIP;
9440 break;
9441
9442 case eCSR_ENCRYPT_TYPE_AES:
9443 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
9444 break;
9445
9446 default:
9447 params.cipher = IW_AUTH_CIPHER_NONE;
9448 break;
9449 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309450
c_hpothuaaf19692014-05-17 17:01:48 +05309451 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9452 TRACE_CODE_HDD_CFG80211_GET_KEY,
9453 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309454
Jeff Johnson295189b2012-06-20 16:38:30 -07009455 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
9456 params.seq_len = 0;
9457 params.seq = NULL;
9458 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
9459 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309460 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009461 return 0;
9462}
9463
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309464#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9465static int wlan_hdd_cfg80211_get_key(
9466 struct wiphy *wiphy,
9467 struct net_device *ndev,
9468 u8 key_index, bool pairwise,
9469 const u8 *mac_addr, void *cookie,
9470 void (*callback)(void *cookie, struct key_params*)
9471 )
9472#else
9473static int wlan_hdd_cfg80211_get_key(
9474 struct wiphy *wiphy,
9475 struct net_device *ndev,
9476 u8 key_index, const u8 *mac_addr, void *cookie,
9477 void (*callback)(void *cookie, struct key_params*)
9478 )
9479#endif
9480{
9481 int ret;
9482
9483 vos_ssr_protect(__func__);
9484#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9485 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
9486 mac_addr, cookie, callback);
9487#else
9488 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
9489 callback);
9490#endif
9491 vos_ssr_unprotect(__func__);
9492
9493 return ret;
9494}
9495
Jeff Johnson295189b2012-06-20 16:38:30 -07009496/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309497 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009498 * This function is used to delete the key information
9499 */
9500#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309501static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009502 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309503 u8 key_index,
9504 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009505 const u8 *mac_addr
9506 )
9507#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309508static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009509 struct net_device *ndev,
9510 u8 key_index,
9511 const u8 *mac_addr
9512 )
9513#endif
9514{
9515 int status = 0;
9516
9517 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309518 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009519 //it is observed that this is invalidating peer
9520 //key index whenever re-key is done. This is affecting data link.
9521 //It should be ok to ignore del_key.
9522#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309523 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
9524 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009525 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
9526 tCsrRoamSetKey setKey;
9527 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309528
Jeff Johnson295189b2012-06-20 16:38:30 -07009529 ENTER();
9530
9531 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
9532 __func__,pAdapter->device_mode);
9533
9534 if (CSR_MAX_NUM_KEY <= key_index)
9535 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309536 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009537 key_index);
9538
9539 return -EINVAL;
9540 }
9541
9542 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9543 setKey.keyId = key_index;
9544
9545 if (mac_addr)
9546 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9547 else
9548 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
9549
9550 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
9551
9552 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009553 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309554 )
9555 {
9556
9557 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07009558 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9559 if( pHostapdState->bssState == BSS_START)
9560 {
9561 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309562
Jeff Johnson295189b2012-06-20 16:38:30 -07009563 if ( status != eHAL_STATUS_SUCCESS )
9564 {
9565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9566 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9567 __LINE__, status );
9568 }
9569 }
9570 }
9571 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309572 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07009573 )
9574 {
9575 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9576
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309577 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9578
9579 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009580 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309581 __func__, setKey.peerMac[0], setKey.peerMac[1],
9582 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07009583 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309584 if(pAdapter->sessionCtx.station.conn_info.connState ==
9585 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07009586 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309587 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309589
Jeff Johnson295189b2012-06-20 16:38:30 -07009590 if ( 0 != status )
9591 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309592 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009593 "%s: sme_RoamSetKey failure, returned %d",
9594 __func__, status);
9595 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9596 return -EINVAL;
9597 }
9598 }
9599 }
9600#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009601 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009602 return status;
9603}
9604
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309605#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9606static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9607 struct net_device *ndev,
9608 u8 key_index,
9609 bool pairwise,
9610 const u8 *mac_addr
9611 )
9612#else
9613static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9614 struct net_device *ndev,
9615 u8 key_index,
9616 const u8 *mac_addr
9617 )
9618#endif
9619{
9620 int ret;
9621
9622 vos_ssr_protect(__func__);
9623#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9624 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
9625 mac_addr);
9626#else
9627 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
9628#endif
9629 vos_ssr_unprotect(__func__);
9630
9631 return ret;
9632}
9633
Jeff Johnson295189b2012-06-20 16:38:30 -07009634/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309635 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009636 * This function is used to set the default tx key index
9637 */
9638#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309639static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009640 struct net_device *ndev,
9641 u8 key_index,
9642 bool unicast, bool multicast)
9643#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309644static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009645 struct net_device *ndev,
9646 u8 key_index)
9647#endif
9648{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309649 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309650 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309651 hdd_wext_state_t *pWextState;
9652 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309653 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009654
9655 ENTER();
9656
Gopichand Nakkala29149562013-05-10 21:43:41 +05309657 if ((NULL == pAdapter))
9658 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309660 "invalid adapter");
9661 return -EINVAL;
9662 }
9663
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309664 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9665 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
9666 pAdapter->sessionId, key_index));
9667
Gopichand Nakkala29149562013-05-10 21:43:41 +05309668 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9669 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9670
9671 if ((NULL == pWextState) || (NULL == pHddStaCtx))
9672 {
9673 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9674 "invalid Wext state or HDD context");
9675 return -EINVAL;
9676 }
9677
Arif Hussain6d2a3322013-11-17 19:50:10 -08009678 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009679 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309680
Jeff Johnson295189b2012-06-20 16:38:30 -07009681 if (CSR_MAX_NUM_KEY <= key_index)
9682 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309683 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009684 key_index);
9685
9686 return -EINVAL;
9687 }
9688
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309689 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9690 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309691 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009692 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309693 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009694 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309695
Jeff Johnson295189b2012-06-20 16:38:30 -07009696 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07009697 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309698 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009699 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309700 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08009701 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309702 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08009703 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07009704 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309705 {
9706 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07009707 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309708
Jeff Johnson295189b2012-06-20 16:38:30 -07009709 tCsrRoamSetKey setKey;
9710 v_U32_t roamId= 0xFF;
9711 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309712
9713 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009714 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309715
Jeff Johnson295189b2012-06-20 16:38:30 -07009716 Keys->defaultIndex = (u8)key_index;
9717 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9718 setKey.keyId = key_index;
9719 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309720
9721 vos_mem_copy(&setKey.Key[0],
9722 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009723 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309724
Gopichand Nakkala29149562013-05-10 21:43:41 +05309725 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309726
9727 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07009728 &pHddStaCtx->conn_info.bssId[0],
9729 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309730
Gopichand Nakkala29149562013-05-10 21:43:41 +05309731 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
9732 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
9733 eCSR_ENCRYPT_TYPE_WEP104)
9734 {
9735 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
9736 even though ap is configured for WEP-40 encryption. In this canse the key length
9737 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
9738 type(104) and switching encryption type to 40*/
9739 pWextState->roamProfile.EncryptionType.encryptionType[0] =
9740 eCSR_ENCRYPT_TYPE_WEP40;
9741 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
9742 eCSR_ENCRYPT_TYPE_WEP40;
9743 }
9744
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309745 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07009746 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309747
Jeff Johnson295189b2012-06-20 16:38:30 -07009748 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309749 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009750 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309751
Jeff Johnson295189b2012-06-20 16:38:30 -07009752 if ( 0 != status )
9753 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309754 hddLog(VOS_TRACE_LEVEL_ERROR,
9755 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009756 status);
9757 return -EINVAL;
9758 }
9759 }
9760 }
9761
9762 /* In SoftAp mode setting key direction for default mode */
9763 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
9764 {
9765 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
9766 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
9767 (eCSR_ENCRYPT_TYPE_AES !=
9768 pWextState->roamProfile.EncryptionType.encryptionType[0])
9769 )
9770 {
9771 /* Saving key direction for default key index to TX default */
9772 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9773 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
9774 }
9775 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309776 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009777 return status;
9778}
9779
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309780#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9781static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9782 struct net_device *ndev,
9783 u8 key_index,
9784 bool unicast, bool multicast)
9785#else
9786static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9787 struct net_device *ndev,
9788 u8 key_index)
9789#endif
9790{
9791 int ret;
9792 vos_ssr_protect(__func__);
9793#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9794 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
9795 multicast);
9796#else
9797 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
9798#endif
9799 vos_ssr_unprotect(__func__);
9800
9801 return ret;
9802}
9803
Jeff Johnson295189b2012-06-20 16:38:30 -07009804/*
9805 * FUNCTION: wlan_hdd_cfg80211_inform_bss
9806 * This function is used to inform the BSS details to nl80211 interface.
9807 */
9808static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
9809 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
9810{
9811 struct net_device *dev = pAdapter->dev;
9812 struct wireless_dev *wdev = dev->ieee80211_ptr;
9813 struct wiphy *wiphy = wdev->wiphy;
9814 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
9815 int chan_no;
9816 int ie_length;
9817 const char *ie;
9818 unsigned int freq;
9819 struct ieee80211_channel *chan;
9820 int rssi = 0;
9821 struct cfg80211_bss *bss = NULL;
9822
Jeff Johnson295189b2012-06-20 16:38:30 -07009823 if( NULL == pBssDesc )
9824 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009825 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009826 return bss;
9827 }
9828
9829 chan_no = pBssDesc->channelId;
9830 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
9831 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
9832
9833 if( NULL == ie )
9834 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009835 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009836 return bss;
9837 }
9838
9839#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9840 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9841 {
9842 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9843 }
9844 else
9845 {
9846 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9847 }
9848#else
9849 freq = ieee80211_channel_to_frequency(chan_no);
9850#endif
9851
9852 chan = __ieee80211_get_channel(wiphy, freq);
9853
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05309854 if (!chan) {
9855 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
9856 return NULL;
9857 }
9858
Abhishek Singhaee43942014-06-16 18:55:47 +05309859 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07009860
Abhishek Singhaee43942014-06-16 18:55:47 +05309861 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309862 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07009863 pBssDesc->capabilityInfo,
9864 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05309865 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07009866}
9867
9868
9869
9870/*
9871 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
9872 * This function is used to inform the BSS details to nl80211 interface.
9873 */
9874struct cfg80211_bss*
9875wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
9876 tSirBssDescription *bss_desc
9877 )
9878{
9879 /*
9880 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
9881 already exists in bss data base of cfg80211 for that particular BSS ID.
9882 Using cfg80211_inform_bss_frame to update the bss entry instead of
9883 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
9884 now there is no possibility to get the mgmt(probe response) frame from PE,
9885 converting bss_desc to ieee80211_mgmt(probe response) and passing to
9886 cfg80211_inform_bss_frame.
9887 */
9888 struct net_device *dev = pAdapter->dev;
9889 struct wireless_dev *wdev = dev->ieee80211_ptr;
9890 struct wiphy *wiphy = wdev->wiphy;
9891 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009892#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9893 qcom_ie_age *qie_age = NULL;
9894 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
9895#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009896 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009897#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009898 const char *ie =
9899 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
9900 unsigned int freq;
9901 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309902 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009903 struct cfg80211_bss *bss_status = NULL;
9904 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
9905 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07009906 hdd_context_t *pHddCtx;
9907 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07009908#ifdef WLAN_OPEN_SOURCE
9909 struct timespec ts;
9910#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009911
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309912
Wilson Yangf80a0542013-10-07 13:02:37 -07009913 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9914 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -07009915 if (0 != status)
9916 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009917 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009918 }
9919
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309920 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07009921 if (!mgmt)
9922 {
9923 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9924 "%s: memory allocation failed ", __func__);
9925 return NULL;
9926 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009927
Jeff Johnson295189b2012-06-20 16:38:30 -07009928 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07009929
9930#ifdef WLAN_OPEN_SOURCE
9931 /* Android does not want the timestamp from the frame.
9932 Instead it wants a monotonic increasing value */
9933 get_monotonic_boottime(&ts);
9934 mgmt->u.probe_resp.timestamp =
9935 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
9936#else
9937 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009938 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
9939 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07009940
9941#endif
9942
Jeff Johnson295189b2012-06-20 16:38:30 -07009943 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
9944 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009945
9946#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9947 /* GPS Requirement: need age ie per entry. Using vendor specific. */
9948 /* Assuming this is the last IE, copy at the end */
9949 ie_length -=sizeof(qcom_ie_age);
9950 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
9951 qie_age->element_id = QCOM_VENDOR_IE_ID;
9952 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
9953 qie_age->oui_1 = QCOM_OUI1;
9954 qie_age->oui_2 = QCOM_OUI2;
9955 qie_age->oui_3 = QCOM_OUI3;
9956 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
9957 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
9958#endif
9959
Jeff Johnson295189b2012-06-20 16:38:30 -07009960 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05309961 if (bss_desc->fProbeRsp)
9962 {
9963 mgmt->frame_control |=
9964 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
9965 }
9966 else
9967 {
9968 mgmt->frame_control |=
9969 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
9970 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009971
9972#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309973 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009974 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
9975 {
9976 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9977 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309978 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009979 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
9980
9981 {
9982 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9983 }
9984 else
9985 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309986 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
9987 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07009988 kfree(mgmt);
9989 return NULL;
9990 }
9991#else
9992 freq = ieee80211_channel_to_frequency(chan_no);
9993#endif
9994 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009995 /*when the band is changed on the fly using the GUI, three things are done
9996 * 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)
9997 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
9998 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
9999 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
10000 * and discards the channels correponding to previous band and calls back with zero bss results.
10001 * 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
10002 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
10003 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
10004 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
10005 * So drop the bss and continue to next bss.
10006 */
10007 if(chan == NULL)
10008 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010009 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070010010 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010011 return NULL;
10012 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053010013 /*To keep the rssi icon of the connected AP in the scan window
10014 *and the rssi icon of the wireless networks in sync
10015 * */
10016 if (( eConnectionState_Associated ==
10017 pAdapter->sessionCtx.station.conn_info.connState ) &&
10018 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
10019 pAdapter->sessionCtx.station.conn_info.bssId,
10020 WNI_CFG_BSSID_LEN)) &&
10021 (pHddCtx->hdd_wlan_suspended == FALSE))
10022 {
10023 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
10024 rssi = (pAdapter->rssi * 100);
10025 }
10026 else
10027 {
10028 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
10029 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010030
Nirav Shah20ac06f2013-12-12 18:14:06 +053010031 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053010032 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
10033 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053010034
Jeff Johnson295189b2012-06-20 16:38:30 -070010035 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
10036 frame_len, rssi, GFP_KERNEL);
10037 kfree(mgmt);
10038 return bss_status;
10039}
10040
10041/*
10042 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
10043 * This function is used to update the BSS data base of CFG8011
10044 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010045struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010046 tCsrRoamInfo *pRoamInfo
10047 )
10048{
10049 tCsrRoamConnectedProfile roamProfile;
10050 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10051 struct cfg80211_bss *bss = NULL;
10052
10053 ENTER();
10054
10055 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
10056 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
10057
10058 if (NULL != roamProfile.pBssDesc)
10059 {
Girish Gowlif4b68022014-08-28 23:18:57 +053010060 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10061 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070010062
10063 if (NULL == bss)
10064 {
10065 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
10066 __func__);
10067 }
10068
10069 sme_RoamFreeConnectProfile(hHal, &roamProfile);
10070 }
10071 else
10072 {
10073 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
10074 __func__);
10075 }
10076 return bss;
10077}
10078
10079/*
10080 * FUNCTION: wlan_hdd_cfg80211_update_bss
10081 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010082static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
10083 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070010084 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010085{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010086 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010087 tCsrScanResultInfo *pScanResult;
10088 eHalStatus status = 0;
10089 tScanResultHandle pResult;
10090 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010091 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010092 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070010093 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010094
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010095 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10096 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
10097 NO_SESSION, pAdapter->sessionId));
10098
Wilson Yangf80a0542013-10-07 13:02:37 -070010099 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10100
10101 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070010102 {
Wilson Yangf80a0542013-10-07 13:02:37 -070010103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10104 "%s:LOGP in Progress. Ignore!!!",__func__);
10105 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010106 }
10107
Wilson Yangf80a0542013-10-07 13:02:37 -070010108
10109 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053010110 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070010111 {
10112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10113 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
10114 return VOS_STATUS_E_PERM;
10115 }
10116
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010117 if (pAdapter->request != NULL)
10118 {
10119 if ((pAdapter->request->n_ssids == 1)
10120 && (pAdapter->request->ssids != NULL)
10121 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
10122 is_p2p_scan = true;
10123 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010124 /*
10125 * start getting scan results and populate cgf80211 BSS database
10126 */
10127 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
10128
10129 /* no scan results */
10130 if (NULL == pResult)
10131 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010132 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
10133 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053010134 wlan_hdd_get_frame_logs(pAdapter,
10135 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070010136 return status;
10137 }
10138
10139 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
10140
10141 while (pScanResult)
10142 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010143 /*
10144 * cfg80211_inform_bss() is not updating ie field of bss entry, if
10145 * entry already exists in bss data base of cfg80211 for that
10146 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
10147 * bss entry instead of cfg80211_inform_bss, But this call expects
10148 * mgmt packet as input. As of now there is no possibility to get
10149 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070010150 * ieee80211_mgmt(probe response) and passing to c
10151 * fg80211_inform_bss_frame.
10152 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010153 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
10154 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
10155 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010156 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10157 continue; //Skip the non p2p bss entries
10158 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010159 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10160 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010161
Jeff Johnson295189b2012-06-20 16:38:30 -070010162
10163 if (NULL == bss_status)
10164 {
10165 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010166 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010167 }
10168 else
10169 {
Yue Maf49ba872013-08-19 12:04:25 -070010170 cfg80211_put_bss(
10171#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
10172 wiphy,
10173#endif
10174 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010175 }
10176
10177 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10178 }
10179
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010180 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010181 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010182 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010183}
10184
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010185void
10186hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
10187{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010188 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080010189 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010190} /****** end hddPrintMacAddr() ******/
10191
10192void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010193hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010194{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010195 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010196 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010197 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
10198 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
10199 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010200} /****** end hddPrintPmkId() ******/
10201
10202//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
10203//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
10204
10205//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
10206//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
10207
10208#define dump_bssid(bssid) \
10209 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010210 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
10211 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010212 }
10213
10214#define dump_pmkid(pMac, pmkid) \
10215 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010216 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
10217 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010218 }
10219
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070010220#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010221/*
10222 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
10223 * This function is used to notify the supplicant of a new PMKSA candidate.
10224 */
10225int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010226 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010227 int index, bool preauth )
10228{
Jeff Johnsone7245742012-09-05 17:12:55 -070010229#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010230 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010231 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010232
10233 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070010234 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010235
10236 if( NULL == pRoamInfo )
10237 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010238 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010239 return -EINVAL;
10240 }
10241
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010242 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
10243 {
10244 dump_bssid(pRoamInfo->bssid);
10245 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010246 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010247 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010248#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010249 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010250}
10251#endif //FEATURE_WLAN_LFR
10252
Yue Maef608272013-04-08 23:09:17 -070010253#ifdef FEATURE_WLAN_LFR_METRICS
10254/*
10255 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
10256 * 802.11r/LFR metrics reporting function to report preauth initiation
10257 *
10258 */
10259#define MAX_LFR_METRICS_EVENT_LENGTH 100
10260VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
10261 tCsrRoamInfo *pRoamInfo)
10262{
10263 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10264 union iwreq_data wrqu;
10265
10266 ENTER();
10267
10268 if (NULL == pAdapter)
10269 {
10270 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10271 return VOS_STATUS_E_FAILURE;
10272 }
10273
10274 /* create the event */
10275 memset(&wrqu, 0, sizeof(wrqu));
10276 memset(metrics_notification, 0, sizeof(metrics_notification));
10277
10278 wrqu.data.pointer = metrics_notification;
10279 wrqu.data.length = scnprintf(metrics_notification,
10280 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
10281 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10282
10283 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10284
10285 EXIT();
10286
10287 return VOS_STATUS_SUCCESS;
10288}
10289
10290/*
10291 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
10292 * 802.11r/LFR metrics reporting function to report preauth completion
10293 * or failure
10294 */
10295VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
10296 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
10297{
10298 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10299 union iwreq_data wrqu;
10300
10301 ENTER();
10302
10303 if (NULL == pAdapter)
10304 {
10305 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10306 return VOS_STATUS_E_FAILURE;
10307 }
10308
10309 /* create the event */
10310 memset(&wrqu, 0, sizeof(wrqu));
10311 memset(metrics_notification, 0, sizeof(metrics_notification));
10312
10313 scnprintf(metrics_notification, sizeof(metrics_notification),
10314 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
10315 MAC_ADDR_ARRAY(pRoamInfo->bssid));
10316
10317 if (1 == preauth_status)
10318 strncat(metrics_notification, " TRUE", 5);
10319 else
10320 strncat(metrics_notification, " FALSE", 6);
10321
10322 wrqu.data.pointer = metrics_notification;
10323 wrqu.data.length = strlen(metrics_notification);
10324
10325 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10326
10327 EXIT();
10328
10329 return VOS_STATUS_SUCCESS;
10330}
10331
10332/*
10333 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
10334 * 802.11r/LFR metrics reporting function to report handover initiation
10335 *
10336 */
10337VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
10338 tCsrRoamInfo *pRoamInfo)
10339{
10340 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10341 union iwreq_data wrqu;
10342
10343 ENTER();
10344
10345 if (NULL == pAdapter)
10346 {
10347 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10348 return VOS_STATUS_E_FAILURE;
10349 }
10350
10351 /* create the event */
10352 memset(&wrqu, 0, sizeof(wrqu));
10353 memset(metrics_notification, 0, sizeof(metrics_notification));
10354
10355 wrqu.data.pointer = metrics_notification;
10356 wrqu.data.length = scnprintf(metrics_notification,
10357 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
10358 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10359
10360 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10361
10362 EXIT();
10363
10364 return VOS_STATUS_SUCCESS;
10365}
10366#endif
10367
Jeff Johnson295189b2012-06-20 16:38:30 -070010368/*
10369 * FUNCTION: hdd_cfg80211_scan_done_callback
10370 * scanning callback function, called after finishing scan
10371 *
10372 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010373static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070010374 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
10375{
10376 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010377 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070010378 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010379 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010380 struct cfg80211_scan_request *req = NULL;
10381 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010382 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010383 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010384 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010385 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010386
10387 ENTER();
10388
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010389 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053010390 if (NULL == pHddCtx) {
10391 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010392 goto allow_suspend;
10393 }
10394
10395 pScanInfo = &pHddCtx->scan_info;
10396
Jeff Johnson295189b2012-06-20 16:38:30 -070010397 hddLog(VOS_TRACE_LEVEL_INFO,
10398 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080010399 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010400 __func__, halHandle, pContext, (int) scanId, (int) status);
10401
Kiet Lamac06e2c2013-10-23 16:25:07 +053010402 pScanInfo->mScanPendingCounter = 0;
10403
Jeff Johnson295189b2012-06-20 16:38:30 -070010404 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010405 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070010406 &pScanInfo->scan_req_completion_event,
10407 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010408 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070010409 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010410 hddLog(VOS_TRACE_LEVEL_ERROR,
10411 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070010412 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010413 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010414 }
10415
Yue Maef608272013-04-08 23:09:17 -070010416 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010417 {
10418 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010419 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010420 }
10421
10422 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010423 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070010424 {
10425 hddLog(VOS_TRACE_LEVEL_INFO,
10426 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010427 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070010428 (int) scanId);
10429 }
10430
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010431 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010432 pAdapter);
10433
10434 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010435 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010436
10437
10438 /* If any client wait scan result through WEXT
10439 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010440 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070010441 {
10442 /* The other scan request waiting for current scan finish
10443 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010444 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010445 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010446 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070010447 }
10448 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010449 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010450 {
10451 struct net_device *dev = pAdapter->dev;
10452 union iwreq_data wrqu;
10453 int we_event;
10454 char *msg;
10455
10456 memset(&wrqu, '\0', sizeof(wrqu));
10457 we_event = SIOCGIWSCAN;
10458 msg = NULL;
10459 wireless_send_event(dev, we_event, &wrqu, msg);
10460 }
10461 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010462 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010463
10464 /* Get the Scan Req */
10465 req = pAdapter->request;
10466
10467 if (!req)
10468 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010469 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010470 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010471 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010472 }
10473
Jeff Johnson295189b2012-06-20 16:38:30 -070010474 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070010475 /* Scan is no longer pending */
10476 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010477
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010478 /* last_scan_timestamp is used to decide if new scan
10479 * is needed or not on station interface. If last station
10480 * scan time and new station scan time is less then
10481 * last_scan_timestamp ; driver will return cached scan.
10482 */
10483 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
10484 {
10485 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
10486
10487 if ( req->n_channels )
10488 {
10489 for (i = 0; i < req->n_channels ; i++ )
10490 {
10491 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
10492 }
10493 /* store no of channel scanned */
10494 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
10495 }
10496
10497 }
10498
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070010499 /*
10500 * cfg80211_scan_done informing NL80211 about completion
10501 * of scanning
10502 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010503 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
10504 {
10505 aborted = true;
10506 }
10507 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080010508 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010509
Siddharth Bhal76972212014-10-15 16:22:51 +053010510 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
10511 /* Generate new random mac addr for next scan */
10512 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
10513 hdd_processSpoofMacAddrRequest(pHddCtx);
10514 }
10515
Jeff Johnsone7245742012-09-05 17:12:55 -070010516allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010517 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010518 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010519
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010520 /* Acquire wakelock to handle the case where APP's tries to suspend
10521 * immediatly after the driver gets connect request(i.e after scan)
10522 * from supplicant, this result in app's is suspending and not able
10523 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010524 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010525
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010526#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010527 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010528#endif
10529
Jeff Johnson295189b2012-06-20 16:38:30 -070010530 EXIT();
10531 return 0;
10532}
10533
10534/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053010535 * FUNCTION: hdd_isConnectionInProgress
10536 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010537 *
10538 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010539v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010540{
10541 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10542 hdd_station_ctx_t *pHddStaCtx = NULL;
10543 hdd_adapter_t *pAdapter = NULL;
10544 VOS_STATUS status = 0;
10545 v_U8_t staId = 0;
10546 v_U8_t *staMac = NULL;
10547
c_hpothu9b781ba2013-12-30 20:57:45 +053010548 if (TRUE == pHddCtx->btCoexModeSet)
10549 {
10550 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053010551 FL("BTCoex Mode operation in progress"));
10552 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053010553 }
10554
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010555 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10556
10557 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10558 {
10559 pAdapter = pAdapterNode->pAdapter;
10560
10561 if( pAdapter )
10562 {
10563 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010564 "%s: Adapter with device mode %s (%d) exists",
10565 __func__, hdd_device_modetoString(pAdapter->device_mode),
10566 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010567 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053010568 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10569 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
10570 (eConnectionState_Connecting ==
10571 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
10572 {
10573 hddLog(VOS_TRACE_LEVEL_ERROR,
10574 "%s: %p(%d) Connection is in progress", __func__,
10575 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10576 return VOS_TRUE;
10577 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010578 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053010579 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010580 {
10581 hddLog(VOS_TRACE_LEVEL_ERROR,
10582 "%s: %p(%d) Reassociation is in progress", __func__,
10583 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10584 return VOS_TRUE;
10585 }
10586 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010587 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10588 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010589 {
10590 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10591 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010592 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010593 {
10594 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
10595 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010596 "%s: client " MAC_ADDRESS_STR
10597 " is in the middle of WPS/EAPOL exchange.", __func__,
10598 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010599 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010600 }
10601 }
10602 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
10603 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
10604 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010605 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10606 ptSapContext pSapCtx = NULL;
10607 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10608 if(pSapCtx == NULL){
10609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10610 FL("psapCtx is NULL"));
10611 return VOS_FALSE;
10612 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010613 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
10614 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010615 if ((pSapCtx->aStaInfo[staId].isUsed) &&
10616 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010617 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010618 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010619
10620 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010621 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
10622 "middle of WPS/EAPOL exchange.", __func__,
10623 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010624 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010625 }
10626 }
10627 }
10628 }
10629 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10630 pAdapterNode = pNext;
10631 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053010632 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010633}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010634
10635/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010636 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070010637 * this scan respond to scan trigger and update cfg80211 scan database
10638 * later, scan dump command can be used to recieve scan results
10639 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010640int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010641#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10642 struct net_device *dev,
10643#endif
10644 struct cfg80211_scan_request *request)
10645{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010646 hdd_adapter_t *pAdapter = NULL;
10647 hdd_context_t *pHddCtx = NULL;
10648 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010649 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010650 tCsrScanRequest scanRequest;
10651 tANI_U8 *channelList = NULL, i;
10652 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010653 int status;
10654 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010655 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010656 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053010657 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010658 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053010659 v_S7_t rssi=0;
10660 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010661
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010662#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
10663 struct net_device *dev = NULL;
10664 if (NULL == request)
10665 {
10666 hddLog(VOS_TRACE_LEVEL_ERROR,
10667 "%s: scan req param null", __func__);
10668 return -EINVAL;
10669 }
10670 dev = request->wdev->netdev;
10671#endif
10672
10673 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
10674 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
10675 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10676
Jeff Johnson295189b2012-06-20 16:38:30 -070010677 ENTER();
10678
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010679 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10680 __func__, hdd_device_modetoString(pAdapter->device_mode),
10681 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010682
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010683 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010684 if (0 != status)
10685 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010686 return status;
10687 }
10688
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010689 if (NULL == pwextBuf)
10690 {
10691 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
10692 __func__);
10693 return -EIO;
10694 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010695 cfg_param = pHddCtx->cfg_ini;
10696 pScanInfo = &pHddCtx->scan_info;
10697
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053010698 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10699 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
10700 {
10701 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
10702 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
10703 }
10704
Jeff Johnson295189b2012-06-20 16:38:30 -070010705#ifdef WLAN_BTAMP_FEATURE
10706 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010707 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070010708 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010709 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010710 "%s: No scanning when AMP is on", __func__);
10711 return -EOPNOTSUPP;
10712 }
10713#endif
10714 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010715 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010716 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010717 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010718 "%s: Not scanning on device_mode = %s (%d)",
10719 __func__, hdd_device_modetoString(pAdapter->device_mode),
10720 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010721 return -EOPNOTSUPP;
10722 }
10723
10724 if (TRUE == pScanInfo->mScanPending)
10725 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010726 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
10727 {
10728 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
10729 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010730 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010731 }
10732
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010733 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070010734 //Channel and action frame is pending
10735 //Otherwise Cancel Remain On Channel and allow Scan
10736 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010737 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070010738 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010739 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010740 return -EBUSY;
10741 }
10742
Jeff Johnson295189b2012-06-20 16:38:30 -070010743 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
10744 {
10745 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080010746 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010747 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010748 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010749 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
10750 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010751 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010752 "%s: MAX TM Level Scan not allowed", __func__);
10753 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010754 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010755 }
10756 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
10757
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010758 /* Check if scan is allowed at this point of time.
10759 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010760 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010761 {
10762 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
10763 return -EBUSY;
10764 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010765
Jeff Johnson295189b2012-06-20 16:38:30 -070010766 vos_mem_zero( &scanRequest, sizeof(scanRequest));
10767
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010768 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
10769 * Becasue of this, driver is assuming that this is not wildcard scan and so
10770 * is not aging out the scan results.
10771 */
10772 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010773 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010774 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010775 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010776
10777 if ((request->ssids) && (0 < request->n_ssids))
10778 {
10779 tCsrSSIDInfo *SsidInfo;
10780 int j;
10781 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
10782 /* Allocate num_ssid tCsrSSIDInfo structure */
10783 SsidInfo = scanRequest.SSIDs.SSIDList =
10784 ( tCsrSSIDInfo *)vos_mem_malloc(
10785 request->n_ssids*sizeof(tCsrSSIDInfo));
10786
10787 if(NULL == scanRequest.SSIDs.SSIDList)
10788 {
10789 hddLog(VOS_TRACE_LEVEL_ERROR,
10790 "%s: memory alloc failed SSIDInfo buffer", __func__);
10791 return -ENOMEM;
10792 }
10793
10794 /* copy all the ssid's and their length */
10795 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
10796 {
10797 /* get the ssid length */
10798 SsidInfo->SSID.length = request->ssids[j].ssid_len;
10799 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
10800 SsidInfo->SSID.length);
10801 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
10802 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
10803 j, SsidInfo->SSID.ssId);
10804 }
10805 /* set the scan type to active */
10806 scanRequest.scanType = eSIR_ACTIVE_SCAN;
10807 }
10808 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070010809 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010810 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10811 TRACE_CODE_HDD_CFG80211_SCAN,
10812 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070010813 /* set the scan type to active */
10814 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010815 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010816 else
10817 {
10818 /*Set the scan type to default type, in this case it is ACTIVE*/
10819 scanRequest.scanType = pScanInfo->scan_mode;
10820 }
10821 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
10822 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070010823
10824 /* set BSSType to default type */
10825 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
10826
10827 /*TODO: scan the requested channels only*/
10828
10829 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010830 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070010831 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010832 hddLog(VOS_TRACE_LEVEL_WARN,
10833 "No of Scan Channels exceeded limit: %d", request->n_channels);
10834 request->n_channels = MAX_CHANNEL;
10835 }
10836
10837 hddLog(VOS_TRACE_LEVEL_INFO,
10838 "No of Scan Channels: %d", request->n_channels);
10839
10840
10841 if( request->n_channels )
10842 {
10843 char chList [(request->n_channels*5)+1];
10844 int len;
10845 channelList = vos_mem_malloc( request->n_channels );
10846 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053010847 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010848 hddLog(VOS_TRACE_LEVEL_ERROR,
10849 "%s: memory alloc failed channelList", __func__);
10850 status = -ENOMEM;
10851 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053010852 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010853
10854 for( i = 0, len = 0; i < request->n_channels ; i++ )
10855 {
10856 channelList[i] = request->channels[i]->hw_value;
10857 len += snprintf(chList+len, 5, "%d ", channelList[i]);
10858 }
10859
Nirav Shah20ac06f2013-12-12 18:14:06 +053010860 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010861 "Channel-List: %s ", chList);
10862 }
c_hpothu53512302014-04-15 18:49:53 +053010863
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010864 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
10865 scanRequest.ChannelInfo.ChannelList = channelList;
10866
10867 /* set requestType to full scan */
10868 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10869
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010870 /* if there is back to back scan happening in driver with in
10871 * nDeferScanTimeInterval interval driver should defer new scan request
10872 * and should provide last cached scan results instead of new channel list.
10873 * This rule is not applicable if scan is p2p scan.
10874 * This condition will work only in case when last request no of channels
10875 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053010876 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053010877 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010878 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010879
Sushant Kaushik86592172015-04-27 16:35:03 +053010880 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
10881 /* if wps ie is NULL , then only defer scan */
10882 if ( pWpsIe == NULL &&
10883 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053010884 {
10885 if ( pScanInfo->last_scan_timestamp !=0 &&
10886 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
10887 {
10888 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
10889 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
10890 vos_mem_compare(pScanInfo->last_scan_channelList,
10891 channelList, pScanInfo->last_scan_numChannels))
10892 {
10893 hddLog(VOS_TRACE_LEVEL_WARN,
10894 " New and old station scan time differ is less then %u",
10895 pHddCtx->cfg_ini->nDeferScanTimeInterval);
10896
10897 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010898 pAdapter);
10899
Agarwal Ashish57e84372014-12-05 18:26:53 +053010900 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010901 "Return old cached scan as all channels and no of channels are same");
10902
Agarwal Ashish57e84372014-12-05 18:26:53 +053010903 if (0 > ret)
10904 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010905
Agarwal Ashish57e84372014-12-05 18:26:53 +053010906 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010907
10908 status = eHAL_STATUS_SUCCESS;
10909 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053010910 }
10911 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010912 }
10913
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010914 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10915 * search (Flush on both full scan and social scan but not on single
10916 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10917 */
10918
10919 /* Supplicant does single channel scan after 8-way handshake
10920 * and in that case driver shoudnt flush scan results. If
10921 * driver flushes the scan results here and unfortunately if
10922 * the AP doesnt respond to our probe req then association
10923 * fails which is not desired
10924 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010925 if ((request->n_ssids == 1)
10926 && (request->ssids != NULL)
10927 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
10928 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010929
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010930 if( is_p2p_scan ||
10931 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010932 {
10933 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
10934 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
10935 pAdapter->sessionId );
10936 }
10937
10938 if( request->ie_len )
10939 {
10940 /* save this for future association (join requires this) */
10941 /*TODO: Array needs to be converted to dynamic allocation,
10942 * as multiple ie.s can be sent in cfg80211_scan_request structure
10943 * CR 597966
10944 */
10945 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
10946 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
10947 pScanInfo->scanAddIE.length = request->ie_len;
10948
10949 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10950 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10951 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010952 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053010953 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070010954 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010955 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
10956 memcpy( pwextBuf->roamProfile.addIEScan,
10957 request->ie, request->ie_len);
10958 }
10959 else
10960 {
10961 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
10962 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070010963 }
10964
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010965 }
10966 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
10967 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
10968
10969 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
10970 request->ie_len);
10971 if (pP2pIe != NULL)
10972 {
10973#ifdef WLAN_FEATURE_P2P_DEBUG
10974 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
10975 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
10976 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053010977 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010978 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
10979 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10980 "Go nego completed to Connection is started");
10981 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10982 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053010983 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010984 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
10985 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010986 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010987 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
10988 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10989 "Disconnected state to Connection is started");
10990 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10991 "for 4way Handshake");
10992 }
10993#endif
10994
10995 /* no_cck will be set during p2p find to disable 11b rates */
10996 if(TRUE == request->no_cck)
10997 {
10998 hddLog(VOS_TRACE_LEVEL_INFO,
10999 "%s: This is a P2P Search", __func__);
11000 scanRequest.p2pSearch = 1;
11001
11002 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053011003 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011004 /* set requestType to P2P Discovery */
11005 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
11006 }
11007
11008 /*
11009 Skip Dfs Channel in case of P2P Search
11010 if it is set in ini file
11011 */
11012 if(cfg_param->skipDfsChnlInP2pSearch)
11013 {
11014 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011015 }
11016 else
11017 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011018 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011019 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011020
Agarwal Ashish4f616132013-12-30 23:32:50 +053011021 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011022 }
11023 }
11024
11025 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
11026
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011027#ifdef FEATURE_WLAN_TDLS
11028 /* if tdls disagree scan right now, return immediately.
11029 tdls will schedule the scan when scan is allowed. (return SUCCESS)
11030 or will reject the scan if any TDLS is in progress. (return -EBUSY)
11031 */
11032 status = wlan_hdd_tdls_scan_callback (pAdapter,
11033 wiphy,
11034#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11035 dev,
11036#endif
11037 request);
11038 if(status <= 0)
11039 {
11040 if(!status)
11041 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
11042 "scan rejected %d", __func__, status);
11043 else
11044 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
11045 __func__, status);
11046
11047 return status;
11048 }
11049#endif
11050
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011051 /* acquire the wakelock to avoid the apps suspend during the scan. To
11052 * address the following issues.
11053 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
11054 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
11055 * for long time, this result in apps running at full power for long time.
11056 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
11057 * be stuck in full power because of resume BMPS
11058 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011059 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011060
Nirav Shah20ac06f2013-12-12 18:14:06 +053011061 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11062 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011063 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
11064 scanRequest.requestType, scanRequest.scanType,
11065 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053011066 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
11067
Siddharth Bhal76972212014-10-15 16:22:51 +053011068 if (pHddCtx->spoofMacAddr.isEnabled)
11069 {
11070 hddLog(VOS_TRACE_LEVEL_INFO,
11071 "%s: MAC Spoofing enabled for current scan", __func__);
11072 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
11073 * to fill TxBds for probe request during current scan
11074 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011075 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053011076 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011077
11078 if(status != VOS_STATUS_SUCCESS)
11079 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011080 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011081 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053011082#ifdef FEATURE_WLAN_TDLS
11083 wlan_hdd_tdls_scan_done_callback(pAdapter);
11084#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011085 goto free_mem;
11086 }
Siddharth Bhal76972212014-10-15 16:22:51 +053011087 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053011088 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070011089 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011090 pAdapter->sessionId, &scanRequest, &scanId,
11091 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070011092
Jeff Johnson295189b2012-06-20 16:38:30 -070011093 if (eHAL_STATUS_SUCCESS != status)
11094 {
11095 hddLog(VOS_TRACE_LEVEL_ERROR,
11096 "%s: sme_ScanRequest returned error %d", __func__, status);
11097 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011098 if(eHAL_STATUS_RESOURCES == status)
11099 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011100 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
11101 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011102 status = -EBUSY;
11103 } else {
11104 status = -EIO;
11105 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011106 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011107
11108#ifdef FEATURE_WLAN_TDLS
11109 wlan_hdd_tdls_scan_done_callback(pAdapter);
11110#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011111 goto free_mem;
11112 }
11113
11114 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011115 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011116 pAdapter->request = request;
11117 pScanInfo->scanId = scanId;
11118
11119 complete(&pScanInfo->scan_req_completion_event);
11120
11121free_mem:
11122 if( scanRequest.SSIDs.SSIDList )
11123 {
11124 vos_mem_free(scanRequest.SSIDs.SSIDList);
11125 }
11126
11127 if( channelList )
11128 vos_mem_free( channelList );
11129
11130 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011131 return status;
11132}
11133
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011134int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
11135#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11136 struct net_device *dev,
11137#endif
11138 struct cfg80211_scan_request *request)
11139{
11140 int ret;
11141
11142 vos_ssr_protect(__func__);
11143 ret = __wlan_hdd_cfg80211_scan(wiphy,
11144#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11145 dev,
11146#endif
11147 request);
11148 vos_ssr_unprotect(__func__);
11149
11150 return ret;
11151}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011152
11153void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
11154{
11155 v_U8_t iniDot11Mode =
11156 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
11157 eHddDot11Mode hddDot11Mode = iniDot11Mode;
11158
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011159 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
11160 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011161 switch ( iniDot11Mode )
11162 {
11163 case eHDD_DOT11_MODE_AUTO:
11164 case eHDD_DOT11_MODE_11ac:
11165 case eHDD_DOT11_MODE_11ac_ONLY:
11166#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053011167 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
11168 sme_IsFeatureSupportedByFW(DOT11AC) )
11169 hddDot11Mode = eHDD_DOT11_MODE_11ac;
11170 else
11171 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011172#else
11173 hddDot11Mode = eHDD_DOT11_MODE_11n;
11174#endif
11175 break;
11176 case eHDD_DOT11_MODE_11n:
11177 case eHDD_DOT11_MODE_11n_ONLY:
11178 hddDot11Mode = eHDD_DOT11_MODE_11n;
11179 break;
11180 default:
11181 hddDot11Mode = iniDot11Mode;
11182 break;
11183 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011184#ifdef WLAN_FEATURE_AP_HT40_24G
11185 if (operationChannel > SIR_11B_CHANNEL_END)
11186#endif
11187 {
11188 /* This call decides required channel bonding mode */
11189 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011190 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
11191 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011192 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011193}
11194
Jeff Johnson295189b2012-06-20 16:38:30 -070011195/*
11196 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011197 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011198 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011199int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011200 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070011201{
11202 int status = 0;
11203 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080011204 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011205 v_U32_t roamId;
11206 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070011207 eCsrAuthType RSNAuthType;
11208
11209 ENTER();
11210
11211 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080011212 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11213
11214 status = wlan_hdd_validate_context(pHddCtx);
11215 if (status)
11216 {
Yue Mae36e3552014-03-05 17:06:20 -080011217 return status;
11218 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011219
Jeff Johnson295189b2012-06-20 16:38:30 -070011220 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
11221 {
11222 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
11223 return -EINVAL;
11224 }
11225
11226 pRoamProfile = &pWextState->roamProfile;
11227
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011228 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070011229 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011230 hdd_station_ctx_t *pHddStaCtx;
11231 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011232
Siddharth Bhalda0d1622015-04-24 15:47:49 +053011233 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
11234
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011235 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070011236 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
11237 {
11238 /*QoS not enabled in cfg file*/
11239 pRoamProfile->uapsd_mask = 0;
11240 }
11241 else
11242 {
11243 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011244 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070011245 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
11246 }
11247
11248 pRoamProfile->SSIDs.numOfSSIDs = 1;
11249 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
11250 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011251 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070011252 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
11253 ssid, ssid_len);
11254
11255 if (bssid)
11256 {
11257 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
11258 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
11259 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011260 /* Save BSSID in seperate variable as well, as RoamProfile
11261 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070011262 case of join failure we should send valid BSSID to supplicant
11263 */
11264 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
11265 WNI_CFG_BSSID_LEN);
11266 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070011267 else
11268 {
11269 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
11270 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011271
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011272 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
11273 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011274 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
11275 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011276 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011277 /*set gen ie*/
11278 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
11279 /*set auth*/
11280 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
11281 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011282#ifdef FEATURE_WLAN_WAPI
11283 if (pAdapter->wapi_info.nWapiMode)
11284 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011285 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011286 switch (pAdapter->wapi_info.wapiAuthMode)
11287 {
11288 case WAPI_AUTH_MODE_PSK:
11289 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011290 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011291 pAdapter->wapi_info.wapiAuthMode);
11292 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
11293 break;
11294 }
11295 case WAPI_AUTH_MODE_CERT:
11296 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011297 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011298 pAdapter->wapi_info.wapiAuthMode);
11299 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
11300 break;
11301 }
11302 } // End of switch
11303 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
11304 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
11305 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011306 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011307 pRoamProfile->AuthType.numEntries = 1;
11308 pRoamProfile->EncryptionType.numEntries = 1;
11309 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11310 pRoamProfile->mcEncryptionType.numEntries = 1;
11311 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11312 }
11313 }
11314#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011315#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011316 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011317 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11318 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
11319 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011320 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
11321 sizeof (tSirGtkOffloadParams));
11322 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011323 }
11324#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011325 pRoamProfile->csrPersona = pAdapter->device_mode;
11326
Jeff Johnson32d95a32012-09-10 13:15:23 -070011327 if( operatingChannel )
11328 {
11329 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
11330 pRoamProfile->ChannelInfo.numOfChannels = 1;
11331 }
Chet Lanctot186b5732013-03-18 10:26:30 -070011332 else
11333 {
11334 pRoamProfile->ChannelInfo.ChannelList = NULL;
11335 pRoamProfile->ChannelInfo.numOfChannels = 0;
11336 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011337 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
11338 {
11339 hdd_select_cbmode(pAdapter,operatingChannel);
11340 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011341
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011342 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
11343 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011344 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011345 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011346 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
11347 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011348 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11349 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053011350 {
11351 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11352 "%s: Set HDD connState to eConnectionState_Connecting",
11353 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011354 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
11355 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053011356 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011357 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011358 pAdapter->sessionId, pRoamProfile, &roamId);
11359
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011360 if ((eHAL_STATUS_SUCCESS != status) &&
11361 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11362 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011363
11364 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011365 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
11366 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
11367 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011368 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011369 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011370 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011371
11372 pRoamProfile->ChannelInfo.ChannelList = NULL;
11373 pRoamProfile->ChannelInfo.numOfChannels = 0;
11374
Jeff Johnson295189b2012-06-20 16:38:30 -070011375 }
11376 else
11377 {
11378 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
11379 return -EINVAL;
11380 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011381 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011382 return status;
11383}
11384
11385/*
11386 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
11387 * This function is used to set the authentication type (OPEN/SHARED).
11388 *
11389 */
11390static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
11391 enum nl80211_auth_type auth_type)
11392{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011393 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011394 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11395
11396 ENTER();
11397
11398 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011399 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070011400 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011401 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011402 hddLog(VOS_TRACE_LEVEL_INFO,
11403 "%s: set authentication type to AUTOSWITCH", __func__);
11404 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
11405 break;
11406
11407 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011408#ifdef WLAN_FEATURE_VOWIFI_11R
11409 case NL80211_AUTHTYPE_FT:
11410#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011411 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011412 "%s: set authentication type to OPEN", __func__);
11413 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11414 break;
11415
11416 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011417 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011418 "%s: set authentication type to SHARED", __func__);
11419 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
11420 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011421#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011422 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011423 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011424 "%s: set authentication type to CCKM WPA", __func__);
11425 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
11426 break;
11427#endif
11428
11429
11430 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011431 hddLog(VOS_TRACE_LEVEL_ERROR,
11432 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011433 auth_type);
11434 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
11435 return -EINVAL;
11436 }
11437
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011438 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011439 pHddStaCtx->conn_info.authType;
11440 return 0;
11441}
11442
11443/*
11444 * FUNCTION: wlan_hdd_set_akm_suite
11445 * This function is used to set the key mgmt type(PSK/8021x).
11446 *
11447 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011448static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011449 u32 key_mgmt
11450 )
11451{
11452 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11453 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053011454 /* Should be in ieee802_11_defs.h */
11455#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
11456#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070011457 /*set key mgmt type*/
11458 switch(key_mgmt)
11459 {
11460 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053011461 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011462#ifdef WLAN_FEATURE_VOWIFI_11R
11463 case WLAN_AKM_SUITE_FT_PSK:
11464#endif
11465 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070011466 __func__);
11467 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
11468 break;
11469
11470 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053011471 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011472#ifdef WLAN_FEATURE_VOWIFI_11R
11473 case WLAN_AKM_SUITE_FT_8021X:
11474#endif
11475 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070011476 __func__);
11477 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11478 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011479#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011480#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
11481#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
11482 case WLAN_AKM_SUITE_CCKM:
11483 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
11484 __func__);
11485 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
11486 break;
11487#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070011488#ifndef WLAN_AKM_SUITE_OSEN
11489#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
11490 case WLAN_AKM_SUITE_OSEN:
11491 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
11492 __func__);
11493 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11494 break;
11495#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011496
11497 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011498 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011499 __func__, key_mgmt);
11500 return -EINVAL;
11501
11502 }
11503 return 0;
11504}
11505
11506/*
11507 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011508 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070011509 * (NONE/WEP40/WEP104/TKIP/CCMP).
11510 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011511static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
11512 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070011513 bool ucast
11514 )
11515{
11516 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011517 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011518 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11519
11520 ENTER();
11521
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011522 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011523 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011524 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070011525 __func__, cipher);
11526 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11527 }
11528 else
11529 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011530
Jeff Johnson295189b2012-06-20 16:38:30 -070011531 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011532 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011533 {
11534 case IW_AUTH_CIPHER_NONE:
11535 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11536 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011537
Jeff Johnson295189b2012-06-20 16:38:30 -070011538 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011539 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070011540 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011541
Jeff Johnson295189b2012-06-20 16:38:30 -070011542 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011543 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070011544 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011545
Jeff Johnson295189b2012-06-20 16:38:30 -070011546 case WLAN_CIPHER_SUITE_TKIP:
11547 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
11548 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011549
Jeff Johnson295189b2012-06-20 16:38:30 -070011550 case WLAN_CIPHER_SUITE_CCMP:
11551 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11552 break;
11553#ifdef FEATURE_WLAN_WAPI
11554 case WLAN_CIPHER_SUITE_SMS4:
11555 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
11556 break;
11557#endif
11558
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011559#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011560 case WLAN_CIPHER_SUITE_KRK:
11561 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
11562 break;
11563#endif
11564 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011565 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011566 __func__, cipher);
11567 return -EOPNOTSUPP;
11568 }
11569 }
11570
11571 if (ucast)
11572 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011573 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011574 __func__, encryptionType);
11575 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11576 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011577 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011578 encryptionType;
11579 }
11580 else
11581 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011582 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011583 __func__, encryptionType);
11584 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
11585 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
11586 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
11587 }
11588
11589 return 0;
11590}
11591
11592
11593/*
11594 * FUNCTION: wlan_hdd_cfg80211_set_ie
11595 * This function is used to parse WPA/RSN IE's.
11596 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011597int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
11598 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070011599 size_t ie_len
11600 )
11601{
11602 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11603 u8 *genie = ie;
11604 v_U16_t remLen = ie_len;
11605#ifdef FEATURE_WLAN_WAPI
11606 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
11607 u16 *tmp;
11608 v_U16_t akmsuiteCount;
11609 int *akmlist;
11610#endif
11611 ENTER();
11612
11613 /* clear previous assocAddIE */
11614 pWextState->assocAddIE.length = 0;
11615 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011616 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011617
11618 while (remLen >= 2)
11619 {
11620 v_U16_t eLen = 0;
11621 v_U8_t elementId;
11622 elementId = *genie++;
11623 eLen = *genie++;
11624 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011625
Arif Hussain6d2a3322013-11-17 19:50:10 -080011626 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070011627 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011628
11629 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070011630 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011631 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011632 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 -070011633 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011634 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011635 "%s: Invalid WPA IE", __func__);
11636 return -EINVAL;
11637 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011638 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070011639 {
11640 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011641 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011642 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011643
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011644 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011645 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011646 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
11647 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011648 VOS_ASSERT(0);
11649 return -ENOMEM;
11650 }
11651 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11652 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11653 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011654
Jeff Johnson295189b2012-06-20 16:38:30 -070011655 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
11656 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11657 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11658 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011659 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
11660 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011661 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
11662 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11663 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
11664 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
11665 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
11666 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011667 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053011668 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011669 {
11670 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011671 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011672 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011673
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011674 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011675 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011676 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11677 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011678 VOS_ASSERT(0);
11679 return -ENOMEM;
11680 }
11681 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11682 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11683 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011684
Jeff Johnson295189b2012-06-20 16:38:30 -070011685 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11686 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11687 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011688#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011689 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
11690 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011691 /*Consider WFD IE, only for P2P Client */
11692 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11693 {
11694 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011695 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011696 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011697
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011698 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011699 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011700 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11701 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011702 VOS_ASSERT(0);
11703 return -ENOMEM;
11704 }
11705 // WFD IE is saved to Additional IE ; it should be accumulated to handle
11706 // WPS IE + P2P IE + WFD IE
11707 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11708 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011709
Jeff Johnson295189b2012-06-20 16:38:30 -070011710 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11711 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11712 }
11713#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011714 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011715 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011716 HS20_OUI_TYPE_SIZE)) )
11717 {
11718 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011719 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011720 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011721
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011722 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011723 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011724 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11725 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011726 VOS_ASSERT(0);
11727 return -ENOMEM;
11728 }
11729 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11730 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011731
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011732 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11733 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11734 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011735 /* Appending OSEN Information Element in Assiciation Request */
11736 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
11737 OSEN_OUI_TYPE_SIZE)) )
11738 {
11739 v_U16_t curAddIELen = pWextState->assocAddIE.length;
11740 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
11741 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011742
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011743 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011744 {
11745 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11746 "Need bigger buffer space");
11747 VOS_ASSERT(0);
11748 return -ENOMEM;
11749 }
11750 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11751 pWextState->assocAddIE.length += eLen + 2;
11752
11753 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
11754 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11755 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11756 }
11757
Abhishek Singh4322e622015-06-10 15:42:54 +053011758 /* Update only for WPA IE */
11759 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
11760 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070011761
11762 /* populating as ADDIE in beacon frames */
11763 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11764 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
11765 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
11766 {
11767 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11768 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
11769 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11770 {
11771 hddLog(LOGE,
11772 "Coldn't pass "
11773 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
11774 }
11775 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
11776 else
11777 hddLog(LOGE,
11778 "Could not pass on "
11779 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
11780
11781 /* IBSS mode doesn't contain params->proberesp_ies still
11782 beaconIE's need to be populated in probe response frames */
11783 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
11784 {
11785 u16 rem_probe_resp_ie_len = eLen + 2;
11786 u8 probe_rsp_ie_len[3] = {0};
11787 u8 counter = 0;
11788
11789 /* Check Probe Resp Length if it is greater then 255 then
11790 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
11791 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
11792 not able Store More then 255 bytes into One Variable */
11793
11794 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
11795 {
11796 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
11797 {
11798 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
11799 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
11800 }
11801 else
11802 {
11803 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
11804 rem_probe_resp_ie_len = 0;
11805 }
11806 }
11807
11808 rem_probe_resp_ie_len = 0;
11809
11810 if (probe_rsp_ie_len[0] > 0)
11811 {
11812 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11813 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
11814 (tANI_U8*)(genie - 2),
11815 probe_rsp_ie_len[0], NULL,
11816 eANI_BOOLEAN_FALSE)
11817 == eHAL_STATUS_FAILURE)
11818 {
11819 hddLog(LOGE,
11820 "Could not pass"
11821 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
11822 }
11823 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
11824 }
11825
11826 if (probe_rsp_ie_len[1] > 0)
11827 {
11828 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11829 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
11830 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11831 probe_rsp_ie_len[1], NULL,
11832 eANI_BOOLEAN_FALSE)
11833 == eHAL_STATUS_FAILURE)
11834 {
11835 hddLog(LOGE,
11836 "Could not pass"
11837 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
11838 }
11839 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
11840 }
11841
11842 if (probe_rsp_ie_len[2] > 0)
11843 {
11844 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11845 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
11846 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11847 probe_rsp_ie_len[2], NULL,
11848 eANI_BOOLEAN_FALSE)
11849 == eHAL_STATUS_FAILURE)
11850 {
11851 hddLog(LOGE,
11852 "Could not pass"
11853 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
11854 }
11855 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
11856 }
11857
11858 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11859 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
11860 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11861 {
11862 hddLog(LOGE,
11863 "Could not pass"
11864 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
11865 }
11866 }
11867 else
11868 {
11869 // Reset WNI_CFG_PROBE_RSP Flags
11870 wlan_hdd_reset_prob_rspies(pAdapter);
11871
11872 hddLog(VOS_TRACE_LEVEL_INFO,
11873 "%s: No Probe Response IE received in set beacon",
11874 __func__);
11875 }
11876 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011877 break;
11878 case DOT11F_EID_RSN:
11879 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
11880 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11881 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
11882 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
11883 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
11884 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053011885
11886 /* Appending Extended Capabilities with Interworking bit set
11887 * in Assoc Req.
11888 *
11889 * In assoc req this EXT Cap will only be taken into account if
11890 * interworkingService bit is set to 1. Currently
11891 * driver is only interested in interworkingService capability
11892 * from supplicant. If in future any other EXT Cap info is
11893 * required from supplicat, it needs to be handled while
11894 * sending Assoc Req in LIM.
11895 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011896 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011897 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011898 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011899 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011900 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011901
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011902 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011903 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011904 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11905 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011906 VOS_ASSERT(0);
11907 return -ENOMEM;
11908 }
11909 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11910 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011911
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011912 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11913 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11914 break;
11915 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011916#ifdef FEATURE_WLAN_WAPI
11917 case WLAN_EID_WAPI:
11918 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011919 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011920 pAdapter->wapi_info.nWapiMode);
11921 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011922 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070011923 akmsuiteCount = WPA_GET_LE16(tmp);
11924 tmp = tmp + 1;
11925 akmlist = (int *)(tmp);
11926 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
11927 {
11928 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
11929 }
11930 else
11931 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011932 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070011933 VOS_ASSERT(0);
11934 return -EINVAL;
11935 }
11936
11937 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
11938 {
11939 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011940 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011941 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011942 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011943 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011944 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011945 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011946 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011947 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
11948 }
11949 break;
11950#endif
11951 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011952 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011953 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011954 /* when Unknown IE is received we should break and continue
11955 * to the next IE in the buffer instead we were returning
11956 * so changing this to break */
11957 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011958 }
11959 genie += eLen;
11960 remLen -= eLen;
11961 }
11962 EXIT();
11963 return 0;
11964}
11965
11966/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053011967 * FUNCTION: hdd_isWPAIEPresent
11968 * Parse the received IE to find the WPA IE
11969 *
11970 */
11971static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
11972{
11973 v_U8_t eLen = 0;
11974 v_U16_t remLen = ie_len;
11975 v_U8_t elementId = 0;
11976
11977 while (remLen >= 2)
11978 {
11979 elementId = *ie++;
11980 eLen = *ie++;
11981 remLen -= 2;
11982 if (eLen > remLen)
11983 {
11984 hddLog(VOS_TRACE_LEVEL_ERROR,
11985 "%s: IE length is wrong %d", __func__, eLen);
11986 return FALSE;
11987 }
11988 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
11989 {
11990 /* OUI - 0x00 0X50 0XF2
11991 WPA Information Element - 0x01
11992 WPA version - 0x01*/
11993 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
11994 return TRUE;
11995 }
11996 ie += eLen;
11997 remLen -= eLen;
11998 }
11999 return FALSE;
12000}
12001
12002/*
Jeff Johnson295189b2012-06-20 16:38:30 -070012003 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012004 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012005 * parameters during connect operation.
12006 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012007int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012008 struct cfg80211_connect_params *req
12009 )
12010{
12011 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012012 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012013 ENTER();
12014
12015 /*set wpa version*/
12016 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
12017
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012018 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012019 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053012020 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012021 {
12022 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12023 }
12024 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
12025 {
12026 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12027 }
12028 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012029
12030 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012031 pWextState->wpaVersion);
12032
12033 /*set authentication type*/
12034 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
12035
12036 if (0 > status)
12037 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012038 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012039 "%s: failed to set authentication type ", __func__);
12040 return status;
12041 }
12042
12043 /*set key mgmt type*/
12044 if (req->crypto.n_akm_suites)
12045 {
12046 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
12047 if (0 > status)
12048 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012049 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070012050 __func__);
12051 return status;
12052 }
12053 }
12054
12055 /*set pairwise cipher type*/
12056 if (req->crypto.n_ciphers_pairwise)
12057 {
12058 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
12059 req->crypto.ciphers_pairwise[0], true);
12060 if (0 > status)
12061 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012062 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012063 "%s: failed to set unicast cipher type", __func__);
12064 return status;
12065 }
12066 }
12067 else
12068 {
12069 /*Reset previous cipher suite to none*/
12070 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
12071 if (0 > status)
12072 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012073 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012074 "%s: failed to set unicast cipher type", __func__);
12075 return status;
12076 }
12077 }
12078
12079 /*set group cipher type*/
12080 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
12081 false);
12082
12083 if (0 > status)
12084 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012085 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070012086 __func__);
12087 return status;
12088 }
12089
Chet Lanctot186b5732013-03-18 10:26:30 -070012090#ifdef WLAN_FEATURE_11W
12091 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
12092#endif
12093
Jeff Johnson295189b2012-06-20 16:38:30 -070012094 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
12095 if (req->ie_len)
12096 {
12097 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
12098 if ( 0 > status)
12099 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012100 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012101 __func__);
12102 return status;
12103 }
12104 }
12105
12106 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012107 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012108 {
12109 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
12110 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
12111 )
12112 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012113 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070012114 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
12115 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012116 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012117 __func__);
12118 return -EOPNOTSUPP;
12119 }
12120 else
12121 {
12122 u8 key_len = req->key_len;
12123 u8 key_idx = req->key_idx;
12124
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012125 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012126 && (CSR_MAX_NUM_KEY > key_idx)
12127 )
12128 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012129 hddLog(VOS_TRACE_LEVEL_INFO,
12130 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012131 __func__, key_idx, key_len);
12132 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012133 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012134 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012135 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012136 (u8)key_len;
12137 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
12138 }
12139 }
12140 }
12141 }
12142
12143 return status;
12144}
12145
12146/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012147 * FUNCTION: wlan_hdd_try_disconnect
12148 * This function is used to disconnect from previous
12149 * connection
12150 */
12151static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
12152{
12153 long ret = 0;
12154 hdd_station_ctx_t *pHddStaCtx;
12155 eMib_dot11DesiredBssType connectedBssType;
12156
12157 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12158
12159 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
12160
12161 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
12162 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
12163 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
12164 {
12165 /* Issue disconnect to CSR */
12166 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12167 if( eHAL_STATUS_SUCCESS ==
12168 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12169 pAdapter->sessionId,
12170 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12171 {
12172 ret = wait_for_completion_interruptible_timeout(
12173 &pAdapter->disconnect_comp_var,
12174 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12175 if (0 >= ret)
12176 {
12177 hddLog(LOGE, FL("Failed to receive disconnect event"));
12178 return -EALREADY;
12179 }
12180 }
12181 }
12182 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
12183 {
12184 ret = wait_for_completion_interruptible_timeout(
12185 &pAdapter->disconnect_comp_var,
12186 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12187 if (0 >= ret)
12188 {
12189 hddLog(LOGE, FL("Failed to receive disconnect event"));
12190 return -EALREADY;
12191 }
12192 }
12193
12194 return 0;
12195}
12196
12197/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053012198 * FUNCTION: __wlan_hdd_cfg80211_connect
12199 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070012200 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012201static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012202 struct net_device *ndev,
12203 struct cfg80211_connect_params *req
12204 )
12205{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012206 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012207 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012208 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053012209 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012210
12211 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012212
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012213 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12214 TRACE_CODE_HDD_CFG80211_CONNECT,
12215 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012216 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012217 "%s: device_mode = %s (%d)", __func__,
12218 hdd_device_modetoString(pAdapter->device_mode),
12219 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012220
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012221 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012222 if (!pHddCtx)
12223 {
12224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12225 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053012226 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012227 }
12228
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012229 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012230 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012231 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012232 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012233 }
12234
Agarwal Ashish51325b52014-06-16 16:50:49 +053012235 if (vos_max_concurrent_connections_reached()) {
12236 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12237 return -ECONNREFUSED;
12238 }
12239
Jeff Johnson295189b2012-06-20 16:38:30 -070012240#ifdef WLAN_BTAMP_FEATURE
12241 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012242 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070012243 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012244 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012245 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012246 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070012247 }
12248#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012249
12250 //If Device Mode is Station Concurrent Sessions Exit BMps
12251 //P2P Mode will be taken care in Open/close adapter
12252 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012253 (vos_concurrent_open_sessions_running())) {
12254 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
12255 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012256 }
12257
12258 /*Try disconnecting if already in connected state*/
12259 status = wlan_hdd_try_disconnect(pAdapter);
12260 if ( 0 > status)
12261 {
12262 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12263 " connection"));
12264 return -EALREADY;
12265 }
12266
Jeff Johnson295189b2012-06-20 16:38:30 -070012267 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012268 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070012269
12270 if ( 0 > status)
12271 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012272 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070012273 __func__);
12274 return status;
12275 }
Mohit Khanna765234a2012-09-11 15:08:35 -070012276 if ( req->channel )
12277 {
12278 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
12279 req->ssid_len, req->bssid,
12280 req->channel->hw_value);
12281 }
12282 else
12283 {
12284 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012285 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070012286 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012287
Sushant Kaushikd7083982015-03-18 14:33:24 +053012288 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012289 {
12290 //ReEnable BMPS if disabled
12291 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
12292 (NULL != pHddCtx))
12293 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012294 if (pHddCtx->hdd_wlan_suspended)
12295 {
12296 hdd_set_pwrparams(pHddCtx);
12297 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012298 //ReEnable Bmps and Imps back
12299 hdd_enable_bmps_imps(pHddCtx);
12300 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053012301 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070012302 return status;
12303 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012304 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012305 EXIT();
12306 return status;
12307}
12308
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012309static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
12310 struct net_device *ndev,
12311 struct cfg80211_connect_params *req)
12312{
12313 int ret;
12314 vos_ssr_protect(__func__);
12315 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
12316 vos_ssr_unprotect(__func__);
12317
12318 return ret;
12319}
Jeff Johnson295189b2012-06-20 16:38:30 -070012320
12321/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012322 * FUNCTION: wlan_hdd_disconnect
12323 * This function is used to issue a disconnect request to SME
12324 */
12325int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
12326{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012327 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012328 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012329 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012330 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012331
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012332 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012333
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012334 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012335 if (0 != status)
12336 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012337 return status;
12338 }
12339
Sushant Kaushikb4834d22015-07-15 15:29:05 +053012340 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
12341 {
12342 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
12343 pAdapter->sessionId);
12344 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012345 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012346
Agarwal Ashish47d18112014-08-04 19:55:07 +053012347 /* Need to apply spin lock before decreasing active sessions
12348 * as there can be chance for double decrement if context switch
12349 * Calls hdd_DisConnectHandler.
12350 */
12351
12352 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012353 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
12354 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012355 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
12356 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053012357 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
12358 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012359
Abhishek Singhf4669da2014-05-26 15:07:49 +053012360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053012361 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
12362
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012363 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012364
Mihir Shete182a0b22014-08-18 16:08:48 +053012365 /*
12366 * stop tx queues before deleting STA/BSS context from the firmware.
12367 * tx has to be disabled because the firmware can get busy dropping
12368 * the tx frames after BSS/STA has been deleted and will not send
12369 * back a response resulting in WDI timeout
12370 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053012371 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053012372 netif_tx_disable(pAdapter->dev);
12373 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012374
Mihir Shete182a0b22014-08-18 16:08:48 +053012375 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012376 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12377 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012378 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
12379 {
12380 hddLog(VOS_TRACE_LEVEL_INFO,
12381 FL("status = %d, already disconnected"),
12382 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012383
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012384 }
12385 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012386 {
12387 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012388 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012389 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012390 result = -EINVAL;
12391 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012392 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012393 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012394 &pAdapter->disconnect_comp_var,
12395 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012396 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012397 {
12398 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012399 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012400 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012401 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012402 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012403 {
12404 hddLog(VOS_TRACE_LEVEL_ERROR,
12405 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012406 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012407 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012408disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12410 FL("Set HDD connState to eConnectionState_NotConnected"));
12411 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
12412
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012413 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012414 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012415}
12416
12417
12418/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012419 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070012420 * This function is used to issue a disconnect request to SME
12421 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012422static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012423 struct net_device *dev,
12424 u16 reason
12425 )
12426{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012427 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012428 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012429 tCsrRoamProfile *pRoamProfile;
12430 hdd_station_ctx_t *pHddStaCtx;
12431 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012432#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012433 tANI_U8 staIdx;
12434#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012435
Jeff Johnson295189b2012-06-20 16:38:30 -070012436 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012437
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012438 if (!pAdapter) {
12439 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
12440 return -EINVAL;
12441 }
12442
12443 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12444 if (!pHddStaCtx) {
12445 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
12446 return -EINVAL;
12447 }
12448
12449 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12450 status = wlan_hdd_validate_context(pHddCtx);
12451 if (0 != status)
12452 {
12453 return status;
12454 }
12455
12456 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
12457
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012458 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12459 TRACE_CODE_HDD_CFG80211_DISCONNECT,
12460 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012461 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
12462 __func__, hdd_device_modetoString(pAdapter->device_mode),
12463 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012464
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012465 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
12466 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070012467
Jeff Johnson295189b2012-06-20 16:38:30 -070012468 if (NULL != pRoamProfile)
12469 {
12470 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012471 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
12472 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070012473 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012474 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070012475 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012476 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012477 switch(reason)
12478 {
12479 case WLAN_REASON_MIC_FAILURE:
12480 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
12481 break;
12482
12483 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
12484 case WLAN_REASON_DISASSOC_AP_BUSY:
12485 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
12486 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
12487 break;
12488
12489 case WLAN_REASON_PREV_AUTH_NOT_VALID:
12490 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053012491 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070012492 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
12493 break;
12494
Jeff Johnson295189b2012-06-20 16:38:30 -070012495 default:
12496 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
12497 break;
12498 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012499 pScanInfo = &pHddCtx->scan_info;
12500 if (pScanInfo->mScanPending)
12501 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012502 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012503 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012504 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012505 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012506 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012507
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012508#ifdef FEATURE_WLAN_TDLS
12509 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012510 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012511 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012512 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
12513 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012514 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012515 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012516 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012518 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012519 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012520 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012521 status = sme_DeleteTdlsPeerSta(
12522 WLAN_HDD_GET_HAL_CTX(pAdapter),
12523 pAdapter->sessionId,
12524 mac);
12525 if (status != eHAL_STATUS_SUCCESS) {
12526 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
12527 return -EPERM;
12528 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012529 }
12530 }
12531#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012532 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012533 status = wlan_hdd_disconnect(pAdapter, reasonCode);
12534 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070012535 {
12536 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012537 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012538 __func__, (int)status );
12539 return -EINVAL;
12540 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012541 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012542 else
12543 {
12544 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
12545 "called while in %d state", __func__,
12546 pHddStaCtx->conn_info.connState);
12547 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012548 }
12549 else
12550 {
12551 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
12552 }
12553
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012554 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012555 return status;
12556}
12557
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012558static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
12559 struct net_device *dev,
12560 u16 reason
12561 )
12562{
12563 int ret;
12564 vos_ssr_protect(__func__);
12565 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
12566 vos_ssr_unprotect(__func__);
12567
12568 return ret;
12569}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012570
Jeff Johnson295189b2012-06-20 16:38:30 -070012571/*
12572 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012573 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012574 * settings in IBSS mode.
12575 */
12576static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012577 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012578 struct cfg80211_ibss_params *params
12579 )
12580{
12581 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012582 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012583 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12584 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012585
Jeff Johnson295189b2012-06-20 16:38:30 -070012586 ENTER();
12587
12588 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070012589 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070012590
12591 if (params->ie_len && ( NULL != params->ie) )
12592 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012593 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12594 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012595 {
12596 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12597 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12598 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012599 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012600 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012601 tDot11fIEWPA dot11WPAIE;
12602 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012603 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012604
Wilson Yang00256342013-10-10 23:13:38 -070012605 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012606 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12607 params->ie_len, DOT11F_EID_WPA);
12608 if ( NULL != ie )
12609 {
12610 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12611 // Unpack the WPA IE
12612 //Skip past the EID byte and length byte - and four byte WiFi OUI
12613 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
12614 &ie[2+4],
12615 ie[1] - 4,
12616 &dot11WPAIE);
12617 /*Extract the multicast cipher, the encType for unicast
12618 cipher for wpa-none is none*/
12619 encryptionType =
12620 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
12621 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012622 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012623
Jeff Johnson295189b2012-06-20 16:38:30 -070012624 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
12625
12626 if (0 > status)
12627 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012628 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012629 __func__);
12630 return status;
12631 }
12632 }
12633
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012634 pWextState->roamProfile.AuthType.authType[0] =
12635 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012636 eCSR_AUTH_TYPE_OPEN_SYSTEM;
12637
12638 if (params->privacy)
12639 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012640 /* Security enabled IBSS, At this time there is no information available
12641 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070012642 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012643 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070012644 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012645 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070012646 *enable privacy bit in beacons */
12647
12648 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12649 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012650 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
12651 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070012652 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12653 pWextState->roamProfile.EncryptionType.numEntries = 1;
12654 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070012655 return status;
12656}
12657
12658/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012659 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012660 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012661 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012662static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012663 struct net_device *dev,
12664 struct cfg80211_ibss_params *params
12665 )
12666{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012667 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012668 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12669 tCsrRoamProfile *pRoamProfile;
12670 int status;
krunal sonie9002db2013-11-25 14:24:17 -080012671 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012672 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12673 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012674
12675 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012676
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012677 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12678 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
12679 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012680 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012681 "%s: device_mode = %s (%d)", __func__,
12682 hdd_device_modetoString(pAdapter->device_mode),
12683 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012684
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012685 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012686 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012687 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012688 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012689 }
12690
12691 if (NULL == pWextState)
12692 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012693 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012694 __func__);
12695 return -EIO;
12696 }
12697
Agarwal Ashish51325b52014-06-16 16:50:49 +053012698 if (vos_max_concurrent_connections_reached()) {
12699 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12700 return -ECONNREFUSED;
12701 }
12702
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012703 /*Try disconnecting if already in connected state*/
12704 status = wlan_hdd_try_disconnect(pAdapter);
12705 if ( 0 > status)
12706 {
12707 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12708 " IBSS connection"));
12709 return -EALREADY;
12710 }
12711
Jeff Johnson295189b2012-06-20 16:38:30 -070012712 pRoamProfile = &pWextState->roamProfile;
12713
12714 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
12715 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012716 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012717 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012718 return -EINVAL;
12719 }
12720
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012721 /* BSSID is provided by upper layers hence no need to AUTO generate */
12722 if (NULL != params->bssid) {
12723 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12724 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
12725 hddLog (VOS_TRACE_LEVEL_ERROR,
12726 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12727 return -EIO;
12728 }
12729 }
krunal sonie9002db2013-11-25 14:24:17 -080012730 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
12731 {
12732 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12733 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
12734 {
12735 hddLog (VOS_TRACE_LEVEL_ERROR,
12736 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12737 return -EIO;
12738 }
Sachin Ahuja46ff4912015-03-23 22:48:43 +053012739 params->bssid = vos_mem_malloc(VOS_MAC_ADDR_SIZE);
krunal sonie9002db2013-11-25 14:24:17 -080012740 if (!params->bssid)
12741 {
12742 hddLog (VOS_TRACE_LEVEL_ERROR,
12743 "%s:Failed memory allocation", __func__);
12744 return -EIO;
12745 }
12746 vos_mem_copy((v_U8_t *)params->bssid,
12747 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
12748 VOS_MAC_ADDR_SIZE);
12749 alloc_bssid = VOS_TRUE;
12750 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012751
Jeff Johnson295189b2012-06-20 16:38:30 -070012752 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070012753 if (NULL !=
12754#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12755 params->chandef.chan)
12756#else
12757 params->channel)
12758#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012759 {
12760 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012761 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12762 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
12763 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12764 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012765
12766 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012767 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070012768 ieee80211_frequency_to_channel(
12769#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12770 params->chandef.chan->center_freq);
12771#else
12772 params->channel->center_freq);
12773#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012774
12775 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12776 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070012777 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012778 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
12779 __func__);
12780 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012781 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012782
12783 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012784 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012785 if (channelNum == validChan[indx])
12786 {
12787 break;
12788 }
12789 }
12790 if (indx >= numChans)
12791 {
12792 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012793 __func__, channelNum);
12794 return -EINVAL;
12795 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012796 /* Set the Operational Channel */
12797 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
12798 channelNum);
12799 pRoamProfile->ChannelInfo.numOfChannels = 1;
12800 pHddStaCtx->conn_info.operationChannel = channelNum;
12801 pRoamProfile->ChannelInfo.ChannelList =
12802 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070012803 }
12804
12805 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012806 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070012807 if (status < 0)
12808 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012809 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070012810 __func__);
12811 return status;
12812 }
12813
12814 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012815 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012816 params->ssid_len, params->bssid,
12817 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012818
12819 if (0 > status)
12820 {
12821 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
12822 return status;
12823 }
12824
krunal sonie9002db2013-11-25 14:24:17 -080012825 if (NULL != params->bssid &&
12826 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
12827 alloc_bssid == VOS_TRUE)
12828 {
12829 vos_mem_free(params->bssid);
12830 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012831 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012832 return 0;
12833}
12834
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012835static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
12836 struct net_device *dev,
12837 struct cfg80211_ibss_params *params
12838 )
12839{
12840 int ret = 0;
12841
12842 vos_ssr_protect(__func__);
12843 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
12844 vos_ssr_unprotect(__func__);
12845
12846 return ret;
12847}
12848
Jeff Johnson295189b2012-06-20 16:38:30 -070012849/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012850 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012851 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012852 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012853static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012854 struct net_device *dev
12855 )
12856{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012857 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012858 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12859 tCsrRoamProfile *pRoamProfile;
12860 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012861 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012862
12863 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012864
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012865 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12866 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
12867 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012868 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012869 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012870 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012871 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012872 }
12873
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012874 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
12875 hdd_device_modetoString(pAdapter->device_mode),
12876 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012877 if (NULL == pWextState)
12878 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012879 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012880 __func__);
12881 return -EIO;
12882 }
12883
12884 pRoamProfile = &pWextState->roamProfile;
12885
12886 /* Issue disconnect only if interface type is set to IBSS */
12887 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
12888 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012889 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070012890 __func__);
12891 return -EINVAL;
12892 }
12893
12894 /* Issue Disconnect request */
12895 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12896 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12897 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
12898
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012899 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012900 return 0;
12901}
12902
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012903static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
12904 struct net_device *dev
12905 )
12906{
12907 int ret = 0;
12908
12909 vos_ssr_protect(__func__);
12910 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
12911 vos_ssr_unprotect(__func__);
12912
12913 return ret;
12914}
12915
Jeff Johnson295189b2012-06-20 16:38:30 -070012916/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012917 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070012918 * This function is used to set the phy parameters
12919 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
12920 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012921static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012922 u32 changed)
12923{
12924 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
12925 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012926 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012927
12928 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012929
12930 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012931 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
12932 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012933
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012934 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012935 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012936 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012937 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012938 }
12939
Jeff Johnson295189b2012-06-20 16:38:30 -070012940 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
12941 {
12942 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
12943 WNI_CFG_RTS_THRESHOLD_STAMAX :
12944 wiphy->rts_threshold;
12945
12946 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012947 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070012948 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012949 hddLog(VOS_TRACE_LEVEL_ERROR,
12950 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012951 __func__, rts_threshold);
12952 return -EINVAL;
12953 }
12954
12955 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
12956 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012957 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012958 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012959 hddLog(VOS_TRACE_LEVEL_ERROR,
12960 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012961 __func__, rts_threshold);
12962 return -EIO;
12963 }
12964
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012965 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012966 rts_threshold);
12967 }
12968
12969 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
12970 {
12971 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
12972 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
12973 wiphy->frag_threshold;
12974
12975 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012976 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012977 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012978 hddLog(VOS_TRACE_LEVEL_ERROR,
12979 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012980 frag_threshold);
12981 return -EINVAL;
12982 }
12983
12984 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
12985 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012986 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012987 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012988 hddLog(VOS_TRACE_LEVEL_ERROR,
12989 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012990 __func__, frag_threshold);
12991 return -EIO;
12992 }
12993
12994 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
12995 frag_threshold);
12996 }
12997
12998 if ((changed & WIPHY_PARAM_RETRY_SHORT)
12999 || (changed & WIPHY_PARAM_RETRY_LONG))
13000 {
13001 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
13002 wiphy->retry_short :
13003 wiphy->retry_long;
13004
13005 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
13006 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
13007 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013008 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013009 __func__, retry_value);
13010 return -EINVAL;
13011 }
13012
13013 if (changed & WIPHY_PARAM_RETRY_SHORT)
13014 {
13015 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
13016 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013017 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013018 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013019 hddLog(VOS_TRACE_LEVEL_ERROR,
13020 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013021 __func__, retry_value);
13022 return -EIO;
13023 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013024 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013025 __func__, retry_value);
13026 }
13027 else if (changed & WIPHY_PARAM_RETRY_SHORT)
13028 {
13029 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
13030 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013031 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013032 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013033 hddLog(VOS_TRACE_LEVEL_ERROR,
13034 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013035 __func__, retry_value);
13036 return -EIO;
13037 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013038 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013039 __func__, retry_value);
13040 }
13041 }
13042
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013043 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013044 return 0;
13045}
13046
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013047static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
13048 u32 changed)
13049{
13050 int ret;
13051
13052 vos_ssr_protect(__func__);
13053 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
13054 vos_ssr_unprotect(__func__);
13055
13056 return ret;
13057}
13058
Jeff Johnson295189b2012-06-20 16:38:30 -070013059/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013060 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013061 * This function is used to set the txpower
13062 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013063static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013064#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13065 struct wireless_dev *wdev,
13066#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013067#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013068 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013069#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013070 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013071#endif
13072 int dbm)
13073{
13074 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013075 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013076 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13077 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013078 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013079
13080 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013081
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013082 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13083 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
13084 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013085 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013086 if (0 != status)
13087 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013088 return status;
13089 }
13090
13091 hHal = pHddCtx->hHal;
13092
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013093 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
13094 dbm, ccmCfgSetCallback,
13095 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013096 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013097 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013098 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
13099 return -EIO;
13100 }
13101
13102 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
13103 dbm);
13104
13105 switch(type)
13106 {
13107 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
13108 /* Fall through */
13109 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
13110 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
13111 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013112 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
13113 __func__);
13114 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013115 }
13116 break;
13117 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013118 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070013119 __func__);
13120 return -EOPNOTSUPP;
13121 break;
13122 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013123 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
13124 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070013125 return -EIO;
13126 }
13127
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013128 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013129 return 0;
13130}
13131
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013132static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
13133#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13134 struct wireless_dev *wdev,
13135#endif
13136#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13137 enum tx_power_setting type,
13138#else
13139 enum nl80211_tx_power_setting type,
13140#endif
13141 int dbm)
13142{
13143 int ret;
13144 vos_ssr_protect(__func__);
13145 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
13146#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13147 wdev,
13148#endif
13149#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13150 type,
13151#else
13152 type,
13153#endif
13154 dbm);
13155 vos_ssr_unprotect(__func__);
13156
13157 return ret;
13158}
13159
Jeff Johnson295189b2012-06-20 16:38:30 -070013160/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013161 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013162 * This function is used to read the txpower
13163 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013164static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013165#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13166 struct wireless_dev *wdev,
13167#endif
13168 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070013169{
13170
13171 hdd_adapter_t *pAdapter;
13172 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013173 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013174
Jeff Johnsone7245742012-09-05 17:12:55 -070013175 ENTER();
13176
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013177 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013178 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013179 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013180 *dbm = 0;
13181 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013182 }
13183
Jeff Johnson295189b2012-06-20 16:38:30 -070013184 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
13185 if (NULL == pAdapter)
13186 {
13187 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
13188 return -ENOENT;
13189 }
13190
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053013191 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13192 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
13193 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013194 wlan_hdd_get_classAstats(pAdapter);
13195 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
13196
Jeff Johnsone7245742012-09-05 17:12:55 -070013197 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013198 return 0;
13199}
13200
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013201static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
13202#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13203 struct wireless_dev *wdev,
13204#endif
13205 int *dbm)
13206{
13207 int ret;
13208
13209 vos_ssr_protect(__func__);
13210 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
13211#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13212 wdev,
13213#endif
13214 dbm);
13215 vos_ssr_unprotect(__func__);
13216
13217 return ret;
13218}
13219
13220
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013221static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070013222 u8* mac, struct station_info *sinfo)
13223{
13224 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13225 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13226 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053013227 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013228
13229 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
13230 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070013231
13232 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
13233 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
13234 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
13235 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
13236 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
13237 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
13238 tANI_U16 maxRate = 0;
13239 tANI_U16 myRate;
13240 tANI_U16 currentRate = 0;
13241 tANI_U8 maxSpeedMCS = 0;
13242 tANI_U8 maxMCSIdx = 0;
13243 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053013244 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013245 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013246 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013247
Leo Chang6f8870f2013-03-26 18:11:36 -070013248#ifdef WLAN_FEATURE_11AC
13249 tANI_U32 vht_mcs_map;
13250 eDataRate11ACMaxMcs vhtMaxMcs;
13251#endif /* WLAN_FEATURE_11AC */
13252
Jeff Johnsone7245742012-09-05 17:12:55 -070013253 ENTER();
13254
Jeff Johnson295189b2012-06-20 16:38:30 -070013255 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
13256 (0 == ssidlen))
13257 {
13258 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
13259 " Invalid ssidlen, %d", __func__, ssidlen);
13260 /*To keep GUI happy*/
13261 return 0;
13262 }
13263
Mukul Sharma811205f2014-07-09 21:07:30 +053013264 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
13265 {
13266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13267 "%s: Roaming in progress, so unable to proceed this request", __func__);
13268 return 0;
13269 }
13270
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013271 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013272 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013273 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013274 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013275 }
13276
Jeff Johnson295189b2012-06-20 16:38:30 -070013277
Kiet Lam3b17fc82013-09-27 05:24:08 +053013278 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
13279 sinfo->filled |= STATION_INFO_SIGNAL;
13280
c_hpothu09f19542014-05-30 21:53:31 +053013281 wlan_hdd_get_station_stats(pAdapter);
13282 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
13283
13284 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053013285 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
13286 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053013287 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053013288 {
13289 rate_flags = pAdapter->maxRateFlags;
13290 }
c_hpothu44ff4e02014-05-08 00:13:57 +053013291
Jeff Johnson295189b2012-06-20 16:38:30 -070013292 //convert to the UI units of 100kbps
13293 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
13294
13295#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070013296 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 -070013297 sinfo->signal,
13298 pCfg->reportMaxLinkSpeed,
13299 myRate,
13300 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013301 (int) pCfg->linkSpeedRssiMid,
13302 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070013303 (int) rate_flags,
13304 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013305#endif //LINKSPEED_DEBUG_ENABLED
13306
13307 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
13308 {
13309 // we do not want to necessarily report the current speed
13310 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
13311 {
13312 // report the max possible speed
13313 rssidx = 0;
13314 }
13315 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
13316 {
13317 // report the max possible speed with RSSI scaling
13318 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
13319 {
13320 // report the max possible speed
13321 rssidx = 0;
13322 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013323 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070013324 {
13325 // report middle speed
13326 rssidx = 1;
13327 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013328 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
13329 {
13330 // report middle speed
13331 rssidx = 2;
13332 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013333 else
13334 {
13335 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013336 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070013337 }
13338 }
13339 else
13340 {
13341 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
13342 hddLog(VOS_TRACE_LEVEL_ERROR,
13343 "%s: Invalid value for reportMaxLinkSpeed: %u",
13344 __func__, pCfg->reportMaxLinkSpeed);
13345 rssidx = 0;
13346 }
13347
13348 maxRate = 0;
13349
13350 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013351 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
13352 OperationalRates, &ORLeng))
13353 {
13354 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13355 /*To keep GUI happy*/
13356 return 0;
13357 }
13358
Jeff Johnson295189b2012-06-20 16:38:30 -070013359 for (i = 0; i < ORLeng; i++)
13360 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013361 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013362 {
13363 /* Validate Rate Set */
13364 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
13365 {
13366 currentRate = supported_data_rate[j].supported_rate[rssidx];
13367 break;
13368 }
13369 }
13370 /* Update MAX rate */
13371 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13372 }
13373
13374 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013375 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
13376 ExtendedRates, &ERLeng))
13377 {
13378 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13379 /*To keep GUI happy*/
13380 return 0;
13381 }
13382
Jeff Johnson295189b2012-06-20 16:38:30 -070013383 for (i = 0; i < ERLeng; i++)
13384 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013385 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013386 {
13387 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
13388 {
13389 currentRate = supported_data_rate[j].supported_rate[rssidx];
13390 break;
13391 }
13392 }
13393 /* Update MAX rate */
13394 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13395 }
c_hpothu79aab322014-07-14 21:11:01 +053013396
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013397 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053013398 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013399 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053013400 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070013401 {
c_hpothu79aab322014-07-14 21:11:01 +053013402 if (rate_flags & eHAL_TX_RATE_VHT80)
13403 mode = 2;
13404 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
13405 mode = 1;
13406 else
13407 mode = 0;
13408
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013409 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
13410 MCSRates, &MCSLeng))
13411 {
13412 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13413 /*To keep GUI happy*/
13414 return 0;
13415 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013416 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070013417#ifdef WLAN_FEATURE_11AC
13418 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013419 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070013420 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013421 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013422 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070013423 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070013424 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013425 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013426 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013427 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070013428 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013429 maxMCSIdx = 7;
13430 }
13431 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
13432 {
13433 maxMCSIdx = 8;
13434 }
13435 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
13436 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013437 //VHT20 is supporting 0~8
13438 if (rate_flags & eHAL_TX_RATE_VHT20)
13439 maxMCSIdx = 8;
13440 else
13441 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070013442 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013443
c_hpothu79aab322014-07-14 21:11:01 +053013444 if (0 != rssidx)/*check for scaled */
13445 {
13446 //get middle rate MCS index if rssi=1/2
13447 for (i=0; i <= maxMCSIdx; i++)
13448 {
13449 if (sinfo->signal <= rssiMcsTbl[mode][i])
13450 {
13451 maxMCSIdx = i;
13452 break;
13453 }
13454 }
13455 }
13456
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013457 if (rate_flags & eHAL_TX_RATE_VHT80)
13458 {
13459 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
13460 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
13461 }
13462 else if (rate_flags & eHAL_TX_RATE_VHT40)
13463 {
13464 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
13465 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
13466 }
13467 else if (rate_flags & eHAL_TX_RATE_VHT20)
13468 {
13469 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
13470 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
13471 }
13472
Leo Chang6f8870f2013-03-26 18:11:36 -070013473 maxSpeedMCS = 1;
13474 if (currentRate > maxRate)
13475 {
13476 maxRate = currentRate;
13477 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013478
Leo Chang6f8870f2013-03-26 18:11:36 -070013479 }
13480 else
13481#endif /* WLAN_FEATURE_11AC */
13482 {
13483 if (rate_flags & eHAL_TX_RATE_HT40)
13484 {
13485 rateFlag |= 1;
13486 }
13487 if (rate_flags & eHAL_TX_RATE_SGI)
13488 {
13489 rateFlag |= 2;
13490 }
13491
Girish Gowli01abcee2014-07-31 20:18:55 +053013492 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053013493 if (rssidx == 1 || rssidx == 2)
13494 {
13495 //get middle rate MCS index if rssi=1/2
13496 for (i=0; i <= 7; i++)
13497 {
13498 if (sinfo->signal <= rssiMcsTbl[mode][i])
13499 {
13500 temp = i+1;
13501 break;
13502 }
13503 }
13504 }
c_hpothu79aab322014-07-14 21:11:01 +053013505
13506 for (i = 0; i < MCSLeng; i++)
13507 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013508 for (j = 0; j < temp; j++)
13509 {
13510 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
13511 {
13512 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053013513 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013514 break;
13515 }
13516 }
13517 if ((j < temp) && (currentRate > maxRate))
13518 {
13519 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070013520 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013521 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053013522 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013523 }
13524 }
13525
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013526 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
13527 {
13528 maxRate = myRate;
13529 maxSpeedMCS = 1;
13530 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13531 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013532 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053013533 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070013534 {
13535 maxRate = myRate;
13536 if (rate_flags & eHAL_TX_RATE_LEGACY)
13537 {
13538 maxSpeedMCS = 0;
13539 }
13540 else
13541 {
13542 maxSpeedMCS = 1;
13543 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13544 }
13545 }
13546
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013547 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070013548 {
13549 sinfo->txrate.legacy = maxRate;
13550#ifdef LINKSPEED_DEBUG_ENABLED
13551 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
13552#endif //LINKSPEED_DEBUG_ENABLED
13553 }
13554 else
13555 {
13556 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070013557#ifdef WLAN_FEATURE_11AC
13558 sinfo->txrate.nss = 1;
13559 if (rate_flags & eHAL_TX_RATE_VHT80)
13560 {
13561 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013562 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070013563 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013564 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070013565 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013566 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13567 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13568 }
13569 else if (rate_flags & eHAL_TX_RATE_VHT20)
13570 {
13571 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13572 }
13573#endif /* WLAN_FEATURE_11AC */
13574 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
13575 {
13576 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13577 if (rate_flags & eHAL_TX_RATE_HT40)
13578 {
13579 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13580 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013581 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013582 if (rate_flags & eHAL_TX_RATE_SGI)
13583 {
13584 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13585 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013586
Jeff Johnson295189b2012-06-20 16:38:30 -070013587#ifdef LINKSPEED_DEBUG_ENABLED
13588 pr_info("Reporting MCS rate %d flags %x\n",
13589 sinfo->txrate.mcs,
13590 sinfo->txrate.flags );
13591#endif //LINKSPEED_DEBUG_ENABLED
13592 }
13593 }
13594 else
13595 {
13596 // report current rate instead of max rate
13597
13598 if (rate_flags & eHAL_TX_RATE_LEGACY)
13599 {
13600 //provide to the UI in units of 100kbps
13601 sinfo->txrate.legacy = myRate;
13602#ifdef LINKSPEED_DEBUG_ENABLED
13603 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
13604#endif //LINKSPEED_DEBUG_ENABLED
13605 }
13606 else
13607 {
13608 //must be MCS
13609 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013610#ifdef WLAN_FEATURE_11AC
13611 sinfo->txrate.nss = 1;
13612 if (rate_flags & eHAL_TX_RATE_VHT80)
13613 {
13614 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13615 }
13616 else
13617#endif /* WLAN_FEATURE_11AC */
13618 {
13619 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13620 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013621 if (rate_flags & eHAL_TX_RATE_SGI)
13622 {
13623 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13624 }
13625 if (rate_flags & eHAL_TX_RATE_HT40)
13626 {
13627 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13628 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013629#ifdef WLAN_FEATURE_11AC
13630 else if (rate_flags & eHAL_TX_RATE_VHT80)
13631 {
13632 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
13633 }
13634#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070013635#ifdef LINKSPEED_DEBUG_ENABLED
13636 pr_info("Reporting actual MCS rate %d flags %x\n",
13637 sinfo->txrate.mcs,
13638 sinfo->txrate.flags );
13639#endif //LINKSPEED_DEBUG_ENABLED
13640 }
13641 }
13642 sinfo->filled |= STATION_INFO_TX_BITRATE;
13643
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013644 sinfo->tx_packets =
13645 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
13646 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
13647 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
13648 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
13649
13650 sinfo->tx_retries =
13651 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
13652 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
13653 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
13654 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
13655
13656 sinfo->tx_failed =
13657 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
13658 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
13659 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
13660 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
13661
13662 sinfo->filled |=
13663 STATION_INFO_TX_PACKETS |
13664 STATION_INFO_TX_RETRIES |
13665 STATION_INFO_TX_FAILED;
13666
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013667 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13668 TRACE_CODE_HDD_CFG80211_GET_STA,
13669 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013670 EXIT();
13671 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013672}
13673
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013674static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13675 u8* mac, struct station_info *sinfo)
13676{
13677 int ret;
13678
13679 vos_ssr_protect(__func__);
13680 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
13681 vos_ssr_unprotect(__func__);
13682
13683 return ret;
13684}
13685
13686static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070013687 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070013688{
13689 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013690 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013691 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013692 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013693
Jeff Johnsone7245742012-09-05 17:12:55 -070013694 ENTER();
13695
Jeff Johnson295189b2012-06-20 16:38:30 -070013696 if (NULL == pAdapter)
13697 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013698 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013699 return -ENODEV;
13700 }
13701
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013702 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13703 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
13704 pAdapter->sessionId, timeout));
13705
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013706 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013707 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013708 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013709 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013710 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013711 }
13712
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013713 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
13714 (TRUE == pHddCtx->hdd_wlan_suspended) &&
13715 (pHddCtx->cfg_ini->fhostArpOffload) &&
13716 (eConnectionState_Associated ==
13717 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13718 {
Amar Singhald53568e2013-09-26 11:03:45 -070013719
13720 hddLog(VOS_TRACE_LEVEL_INFO,
13721 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053013722 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013723 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13724 {
13725 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013726 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013727 __func__, vos_status);
13728 }
13729 }
13730
Jeff Johnson295189b2012-06-20 16:38:30 -070013731 /**The get power cmd from the supplicant gets updated by the nl only
13732 *on successful execution of the function call
13733 *we are oppositely mapped w.r.t mode in the driver
13734 **/
13735 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
13736
13737 if (VOS_STATUS_E_FAILURE == vos_status)
13738 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13740 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013741 return -EINVAL;
13742 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013743 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013744 return 0;
13745}
13746
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013747static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
13748 struct net_device *dev, bool mode, int timeout)
13749{
13750 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013751
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013752 vos_ssr_protect(__func__);
13753 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
13754 vos_ssr_unprotect(__func__);
13755
13756 return ret;
13757}
Jeff Johnson295189b2012-06-20 16:38:30 -070013758#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013759static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
13760 struct net_device *netdev,
13761 u8 key_index)
13762{
13763 ENTER();
13764 return 0;
13765}
13766
Jeff Johnson295189b2012-06-20 16:38:30 -070013767static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013768 struct net_device *netdev,
13769 u8 key_index)
13770{
13771 int ret;
13772 vos_ssr_protect(__func__);
13773 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
13774 vos_ssr_unprotect(__func__);
13775 return ret;
13776}
13777#endif //LINUX_VERSION_CODE
13778
13779#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13780static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13781 struct net_device *dev,
13782 struct ieee80211_txq_params *params)
13783{
13784 ENTER();
13785 return 0;
13786}
13787#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13788static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13789 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013790{
Jeff Johnsone7245742012-09-05 17:12:55 -070013791 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013792 return 0;
13793}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013794#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070013795
13796#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13797static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013798 struct net_device *dev,
13799 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013800{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013801 int ret;
13802
13803 vos_ssr_protect(__func__);
13804 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
13805 vos_ssr_unprotect(__func__);
13806 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013807}
13808#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13809static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
13810 struct ieee80211_txq_params *params)
13811{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013812 int ret;
13813
13814 vos_ssr_protect(__func__);
13815 ret = __wlan_hdd_set_txq_params(wiphy, params);
13816 vos_ssr_unprotect(__func__);
13817 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013818}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013819#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013820
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013821static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013822 struct net_device *dev,
13823 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070013824{
13825 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013826 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013827 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013828 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013829 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013830 v_CONTEXT_t pVosContext = NULL;
13831 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013832
Jeff Johnsone7245742012-09-05 17:12:55 -070013833 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013834
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013835 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070013836 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013837 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013838 return -EINVAL;
13839 }
13840
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013841 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13842 TRACE_CODE_HDD_CFG80211_DEL_STA,
13843 pAdapter->sessionId, pAdapter->device_mode));
13844
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013845 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13846 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013847 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013848 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013849 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013850 }
13851
Jeff Johnson295189b2012-06-20 16:38:30 -070013852 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013853 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013854 )
13855 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013856 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13857 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13858 if(pSapCtx == NULL){
13859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13860 FL("psapCtx is NULL"));
13861 return -ENOENT;
13862 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013863 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013864 {
13865 v_U16_t i;
13866 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13867 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013868 if ((pSapCtx->aStaInfo[i].isUsed) &&
13869 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070013870 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013871 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013872 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013873 ETHER_ADDR_LEN);
13874
Jeff Johnson295189b2012-06-20 16:38:30 -070013875 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013876 "%s: Delete STA with MAC::"
13877 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013878 __func__,
13879 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
13880 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013881 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013882 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013883 }
13884 }
13885 }
13886 else
13887 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013888
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013889 vos_status = hdd_softap_GetStaId(pAdapter,
13890 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013891 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13892 {
13893 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013894 "%s: Skip this DEL STA as this is not used::"
13895 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013896 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013897 return -ENOENT;
13898 }
13899
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013900 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013901 {
13902 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013903 "%s: Skip this DEL STA as deauth is in progress::"
13904 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013905 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013906 return -ENOENT;
13907 }
13908
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013909 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013910
Jeff Johnson295189b2012-06-20 16:38:30 -070013911 hddLog(VOS_TRACE_LEVEL_INFO,
13912 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013913 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013914 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013915 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013916
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013917 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013918 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13919 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013920 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013921 hddLog(VOS_TRACE_LEVEL_INFO,
13922 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013923 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013924 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013925 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013926 return -ENOENT;
13927 }
13928
Jeff Johnson295189b2012-06-20 16:38:30 -070013929 }
13930 }
13931
13932 EXIT();
13933
13934 return 0;
13935}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013936
13937#ifdef CFG80211_DEL_STA_V2
13938static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13939 struct net_device *dev,
13940 struct station_del_parameters *param)
13941#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013942static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13943 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013944#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013945{
13946 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013947 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070013948
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013949 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013950
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013951#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013952 if (NULL == param) {
13953 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013954 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013955 return -EINVAL;
13956 }
13957
13958 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
13959 param->subtype, &delStaParams);
13960
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013961#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053013962 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013963 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013964#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013965 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
13966
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013967 vos_ssr_unprotect(__func__);
13968
13969 return ret;
13970}
13971
13972static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013973 struct net_device *dev, u8 *mac, struct station_parameters *params)
13974{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013975 hdd_adapter_t *pAdapter;
13976 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013977 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013978#ifdef FEATURE_WLAN_TDLS
13979 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013980
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013981 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013982
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013983 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13984 if (NULL == pAdapter)
13985 {
13986 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13987 "%s: Adapter is NULL",__func__);
13988 return -EINVAL;
13989 }
13990 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13991 status = wlan_hdd_validate_context(pHddCtx);
13992 if (0 != status)
13993 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013994 return status;
13995 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013996
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013997 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13998 TRACE_CODE_HDD_CFG80211_ADD_STA,
13999 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014000 mask = params->sta_flags_mask;
14001
14002 set = params->sta_flags_set;
14003
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014004 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014005 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
14006 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014007
14008 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
14009 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014010 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014011 }
14012 }
14013#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014014 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014015 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014016}
14017
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014018static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14019 struct net_device *dev, u8 *mac, struct station_parameters *params)
14020{
14021 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014022
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014023 vos_ssr_protect(__func__);
14024 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
14025 vos_ssr_unprotect(__func__);
14026
14027 return ret;
14028}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014029#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070014030
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014031static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070014032 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014033{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014034 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14035 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014036 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014037 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014038 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014039 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070014040
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014041 ENTER();
14042
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014043 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014044 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014045 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014046 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014047 return -EINVAL;
14048 }
14049
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014050 if (!pmksa) {
14051 hddLog(LOGE, FL("pmksa is NULL"));
14052 return -EINVAL;
14053 }
14054
14055 if (!pmksa->bssid || !pmksa->pmkid) {
14056 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
14057 pmksa->bssid, pmksa->pmkid);
14058 return -EINVAL;
14059 }
14060
14061 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
14062 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14063
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014064 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14065 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014066 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014067 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014068 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014069 }
14070
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014071 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014072 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14073
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014074 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
14075 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014076
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014077 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014078 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014079 &pmk_id, 1, FALSE);
14080
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014081 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14082 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
14083 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014084
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014085 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014086 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014087}
14088
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014089static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
14090 struct cfg80211_pmksa *pmksa)
14091{
14092 int ret;
14093
14094 vos_ssr_protect(__func__);
14095 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
14096 vos_ssr_unprotect(__func__);
14097
14098 return ret;
14099}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014100
Wilson Yang6507c4e2013-10-01 20:11:19 -070014101
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014102static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070014103 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014104{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014105 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14106 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014107 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014108 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014109
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014110 ENTER();
14111
Wilson Yang6507c4e2013-10-01 20:11:19 -070014112 /* Validate pAdapter */
14113 if (NULL == pAdapter)
14114 {
14115 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
14116 return -EINVAL;
14117 }
14118
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014119 if (!pmksa) {
14120 hddLog(LOGE, FL("pmksa is NULL"));
14121 return -EINVAL;
14122 }
14123
14124 if (!pmksa->bssid) {
14125 hddLog(LOGE, FL("pmksa->bssid is NULL"));
14126 return -EINVAL;
14127 }
14128
Kiet Lam98c46a12014-10-31 15:34:57 -070014129 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
14130 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14131
Wilson Yang6507c4e2013-10-01 20:11:19 -070014132 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14133 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014134 if (0 != status)
14135 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014136 return status;
14137 }
14138
14139 /*Retrieve halHandle*/
14140 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14141
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014142 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14143 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
14144 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014145 /* Delete the PMKID CSR cache */
14146 if (eHAL_STATUS_SUCCESS !=
14147 sme_RoamDelPMKIDfromCache(halHandle,
14148 pAdapter->sessionId, pmksa->bssid, FALSE)) {
14149 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
14150 MAC_ADDR_ARRAY(pmksa->bssid));
14151 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014152 }
14153
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014154 EXIT();
14155 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014156}
14157
Wilson Yang6507c4e2013-10-01 20:11:19 -070014158
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014159static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
14160 struct cfg80211_pmksa *pmksa)
14161{
14162 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014163
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014164 vos_ssr_protect(__func__);
14165 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
14166 vos_ssr_unprotect(__func__);
14167
14168 return ret;
14169
14170}
14171
14172static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014173{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014174 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14175 tHalHandle halHandle;
14176 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014177 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014178
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014179 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070014180
14181 /* Validate pAdapter */
14182 if (NULL == pAdapter)
14183 {
14184 hddLog(VOS_TRACE_LEVEL_ERROR,
14185 "%s: Invalid Adapter" ,__func__);
14186 return -EINVAL;
14187 }
14188
14189 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14190 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014191 if (0 != status)
14192 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014193 return status;
14194 }
14195
14196 /*Retrieve halHandle*/
14197 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14198
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014199 /* Flush the PMKID cache in CSR */
14200 if (eHAL_STATUS_SUCCESS !=
14201 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
14202 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
14203 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014204 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014205 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080014206 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014207}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014208
14209static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
14210{
14211 int ret;
14212
14213 vos_ssr_protect(__func__);
14214 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
14215 vos_ssr_unprotect(__func__);
14216
14217 return ret;
14218}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014219#endif
14220
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014221#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014222static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14223 struct net_device *dev,
14224 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014225{
14226 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14227 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014228 hdd_context_t *pHddCtx;
14229 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014230
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014231 ENTER();
14232
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014233 if (NULL == pAdapter)
14234 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014235 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014236 return -ENODEV;
14237 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014238 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14239 ret = wlan_hdd_validate_context(pHddCtx);
14240 if (0 != ret)
14241 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014242 return ret;
14243 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014244 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014245 if (NULL == pHddStaCtx)
14246 {
14247 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
14248 return -EINVAL;
14249 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014250
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014251 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14252 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
14253 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014254 // Added for debug on reception of Re-assoc Req.
14255 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
14256 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014257 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014258 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080014259 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014260 }
14261
14262#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080014263 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014264 ftie->ie_len);
14265#endif
14266
14267 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014268 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
14269 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014270 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014271
14272 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014273 return 0;
14274}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014275
14276static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14277 struct net_device *dev,
14278 struct cfg80211_update_ft_ies_params *ftie)
14279{
14280 int ret;
14281
14282 vos_ssr_protect(__func__);
14283 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
14284 vos_ssr_unprotect(__func__);
14285
14286 return ret;
14287}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014288#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014289
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014290#ifdef FEATURE_WLAN_SCAN_PNO
14291
14292void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
14293 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
14294{
14295 int ret;
14296 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
14297 hdd_context_t *pHddCtx;
14298
Nirav Shah80830bf2013-12-31 16:35:12 +053014299 ENTER();
14300
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014301 if (NULL == pAdapter)
14302 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014304 "%s: HDD adapter is Null", __func__);
14305 return ;
14306 }
14307
14308 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14309 if (NULL == pHddCtx)
14310 {
14311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14312 "%s: HDD context is Null!!!", __func__);
14313 return ;
14314 }
14315
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014316 spin_lock(&pHddCtx->schedScan_lock);
14317 if (TRUE == pHddCtx->isWiphySuspended)
14318 {
14319 pHddCtx->isSchedScanUpdatePending = TRUE;
14320 spin_unlock(&pHddCtx->schedScan_lock);
14321 hddLog(VOS_TRACE_LEVEL_INFO,
14322 "%s: Update cfg80211 scan database after it resume", __func__);
14323 return ;
14324 }
14325 spin_unlock(&pHddCtx->schedScan_lock);
14326
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014327 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
14328
14329 if (0 > ret)
14330 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
14331
14332 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14334 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014335}
14336
14337/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014338 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014339 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014340 */
14341static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
14342{
14343 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14344 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014345 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014346 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14347 int status = 0;
14348 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
14349
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014350 /* The current firmware design does not allow PNO during any
14351 * active sessions. Hence, determine the active sessions
14352 * and return a failure.
14353 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014354 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
14355 {
14356 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014357 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014358
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014359 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
14360 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
14361 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
14362 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
14363 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053014364 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014365 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014366 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014367 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014368 }
14369 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14370 pAdapterNode = pNext;
14371 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014372 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014373}
14374
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014375void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
14376{
14377 hdd_adapter_t *pAdapter = callbackContext;
14378 hdd_context_t *pHddCtx;
14379
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014380 ENTER();
14381
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014382 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
14383 {
14384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14385 FL("Invalid adapter or adapter has invalid magic"));
14386 return;
14387 }
14388
14389 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14390 if (0 != wlan_hdd_validate_context(pHddCtx))
14391 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014392 return;
14393 }
14394
c_hpothub53c45d2014-08-18 16:53:14 +053014395 if (VOS_STATUS_SUCCESS != status)
14396 {
14397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014398 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053014399 pHddCtx->isPnoEnable = FALSE;
14400 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014401
14402 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
14403 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014404 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014405}
14406
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014407/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014408 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
14409 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014410 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014411static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014412 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14413{
14414 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014415 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014416 hdd_context_t *pHddCtx;
14417 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014418 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053014419 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
14420 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014421 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14422 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014423 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014424 hdd_config_t *pConfig = NULL;
14425 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014426
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014427 ENTER();
14428
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014429 if (NULL == pAdapter)
14430 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014432 "%s: HDD adapter is Null", __func__);
14433 return -ENODEV;
14434 }
14435
14436 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014437 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014438
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014439 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014440 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014441 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014442 }
14443
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014444 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014445 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14446 if (NULL == hHal)
14447 {
14448 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14449 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014450 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014451 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014452 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14453 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
14454 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053014455 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014456 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053014457 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014458 {
14459 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14460 "%s: aborting the existing scan is unsuccessfull", __func__);
14461 return -EBUSY;
14462 }
14463
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014464 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014465 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014467 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014468 return -EBUSY;
14469 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014470
c_hpothu37f21312014-04-09 21:49:54 +053014471 if (TRUE == pHddCtx->isPnoEnable)
14472 {
14473 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14474 FL("already PNO is enabled"));
14475 return -EBUSY;
14476 }
c_hpothu225aa7c2014-10-22 17:45:13 +053014477
14478 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
14479 {
14480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14481 "%s: abort ROC failed ", __func__);
14482 return -EBUSY;
14483 }
14484
c_hpothu37f21312014-04-09 21:49:54 +053014485 pHddCtx->isPnoEnable = TRUE;
14486
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014487 pnoRequest.enable = 1; /*Enable PNO */
14488 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014489
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014490 if (( !pnoRequest.ucNetworksCount ) ||
14491 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014492 {
14493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014494 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014495 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014496 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014497 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014498 goto error;
14499 }
14500
14501 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
14502 {
14503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014504 "%s: Incorrect number of channels %d",
14505 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014506 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014507 goto error;
14508 }
14509
14510 /* Framework provides one set of channels(all)
14511 * common for all saved profile */
14512 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14513 channels_allowed, &num_channels_allowed))
14514 {
14515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14516 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014517 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014518 goto error;
14519 }
14520 /* Checking each channel against allowed channel list */
14521 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053014522 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014523 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014524 char chList [(request->n_channels*5)+1];
14525 int len;
14526 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014527 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014528 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014529 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014530 if (request->channels[i]->hw_value == channels_allowed[indx])
14531 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014532 if ((!pConfig->enableDFSPnoChnlScan) &&
14533 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
14534 {
14535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14536 "%s : Dropping DFS channel : %d",
14537 __func__,channels_allowed[indx]);
14538 num_ignore_dfs_ch++;
14539 break;
14540 }
14541
Nirav Shah80830bf2013-12-31 16:35:12 +053014542 valid_ch[num_ch++] = request->channels[i]->hw_value;
14543 len += snprintf(chList+len, 5, "%d ",
14544 request->channels[i]->hw_value);
14545 break ;
14546 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014547 }
14548 }
Nirav Shah80830bf2013-12-31 16:35:12 +053014549 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014550
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014551 /*If all channels are DFS and dropped, then ignore the PNO request*/
14552 if (num_ignore_dfs_ch == request->n_channels)
14553 {
14554 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14555 "%s : All requested channels are DFS channels", __func__);
14556 ret = -EINVAL;
14557 goto error;
14558 }
14559 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014560
14561 pnoRequest.aNetworks =
14562 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14563 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014564 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014565 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14566 FL("failed to allocate memory aNetworks %u"),
14567 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14568 goto error;
14569 }
14570 vos_mem_zero(pnoRequest.aNetworks,
14571 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14572
14573 /* Filling per profile params */
14574 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
14575 {
14576 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014577 request->match_sets[i].ssid.ssid_len;
14578
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014579 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
14580 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014581 {
14582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014583 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014584 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014585 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014586 goto error;
14587 }
14588
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014589 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014590 request->match_sets[i].ssid.ssid,
14591 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14593 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014594 i, pnoRequest.aNetworks[i].ssId.ssId);
14595 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
14596 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
14597 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014598
14599 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014600 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
14601 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014602
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014603 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014604 }
14605
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014606 for (i = 0; i < request->n_ssids; i++)
14607 {
14608 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014609 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014610 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014611 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014612 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014613 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014614 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014615 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014616 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014617 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014618 break;
14619 }
14620 j++;
14621 }
14622 }
14623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14624 "Number of hidden networks being Configured = %d",
14625 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080014627 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014628
14629 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14630 if (pnoRequest.p24GProbeTemplate == NULL)
14631 {
14632 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14633 FL("failed to allocate memory p24GProbeTemplate %u"),
14634 SIR_PNO_MAX_PB_REQ_SIZE);
14635 goto error;
14636 }
14637
14638 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14639 if (pnoRequest.p5GProbeTemplate == NULL)
14640 {
14641 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14642 FL("failed to allocate memory p5GProbeTemplate %u"),
14643 SIR_PNO_MAX_PB_REQ_SIZE);
14644 goto error;
14645 }
14646
14647 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14648 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14649
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053014650 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
14651 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014652 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014653 pnoRequest.us24GProbeTemplateLen = request->ie_len;
14654 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
14655 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014656
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014657 pnoRequest.us5GProbeTemplateLen = request->ie_len;
14658 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
14659 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014660 }
14661
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014662 /* Driver gets only one time interval which is hardcoded in
14663 * supplicant for 10000ms. Taking power consumption into account 6 timers
14664 * will be used, Timervalue is increased exponentially i.e 10,20,40,
14665 * 80,160,320 secs. And number of scan cycle for each timer
14666 * is configurable through INI param gPNOScanTimerRepeatValue.
14667 * If it is set to 0 only one timer will be used and PNO scan cycle
14668 * will be repeated after each interval specified by supplicant
14669 * till PNO is disabled.
14670 */
14671 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014672 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014673 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014674 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014675 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
14676
14677 tempInterval = (request->interval)/1000;
14678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14679 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
14680 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014681 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014682 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014683 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014684 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014685 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014686 tempInterval *= 2;
14687 }
14688 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014689 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014690
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014691 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014692
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014693 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014694 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
14695 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014696 pAdapter->pno_req_status = 0;
14697
Nirav Shah80830bf2013-12-31 16:35:12 +053014698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14699 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014700 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
14701 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053014702
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014703 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014704 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014705 hdd_cfg80211_sched_scan_done_callback, pAdapter);
14706 if (eHAL_STATUS_SUCCESS != status)
14707 {
14708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014709 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014710 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014711 goto error;
14712 }
14713
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014714 ret = wait_for_completion_timeout(
14715 &pAdapter->pno_comp_var,
14716 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
14717 if (0 >= ret)
14718 {
14719 // Did not receive the response for PNO enable in time.
14720 // Assuming the PNO enable was success.
14721 // Returning error from here, because we timeout, results
14722 // in side effect of Wifi (Wifi Setting) not to work.
14723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14724 FL("Timed out waiting for PNO to be Enabled"));
14725 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014726 }
14727
14728 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053014729 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014730
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014731error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14733 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053014734 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014735 if (pnoRequest.aNetworks)
14736 vos_mem_free(pnoRequest.aNetworks);
14737 if (pnoRequest.p24GProbeTemplate)
14738 vos_mem_free(pnoRequest.p24GProbeTemplate);
14739 if (pnoRequest.p5GProbeTemplate)
14740 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014741
14742 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014743 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014744}
14745
14746/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014747 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
14748 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014749 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014750static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
14751 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14752{
14753 int ret;
14754
14755 vos_ssr_protect(__func__);
14756 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
14757 vos_ssr_unprotect(__func__);
14758
14759 return ret;
14760}
14761
14762/*
14763 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
14764 * Function to disable PNO
14765 */
14766static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014767 struct net_device *dev)
14768{
14769 eHalStatus status = eHAL_STATUS_FAILURE;
14770 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14771 hdd_context_t *pHddCtx;
14772 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014773 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014774 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014775
14776 ENTER();
14777
14778 if (NULL == pAdapter)
14779 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014781 "%s: HDD adapter is Null", __func__);
14782 return -ENODEV;
14783 }
14784
14785 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014786
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014787 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014788 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014789 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014790 "%s: HDD context is Null", __func__);
14791 return -ENODEV;
14792 }
14793
14794 /* The return 0 is intentional when isLogpInProgress and
14795 * isLoadUnloadInProgress. We did observe a crash due to a return of
14796 * failure in sched_scan_stop , especially for a case where the unload
14797 * of the happens at the same time. The function __cfg80211_stop_sched_scan
14798 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
14799 * success. If it returns a failure , then its next invocation due to the
14800 * clean up of the second interface will have the dev pointer corresponding
14801 * to the first one leading to a crash.
14802 */
14803 if (pHddCtx->isLogpInProgress)
14804 {
14805 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14806 "%s: LOGP in Progress. Ignore!!!", __func__);
14807 return ret;
14808 }
14809
Mihir Shete18156292014-03-11 15:38:30 +053014810 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014811 {
14812 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14813 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14814 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014815 }
14816
14817 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14818 if (NULL == hHal)
14819 {
14820 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14821 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014822 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014823 }
14824
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014825 pnoRequest.enable = 0; /* Disable PNO */
14826 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014827
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014828 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14829 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
14830 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014831 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014832 pAdapter->sessionId,
14833 NULL, pAdapter);
14834 if (eHAL_STATUS_SUCCESS != status)
14835 {
14836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14837 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014838 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014839 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014840 }
c_hpothu37f21312014-04-09 21:49:54 +053014841 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014842
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014843error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014845 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014846
14847 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014848 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014849}
14850
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014851/*
14852 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
14853 * NL interface to disable PNO
14854 */
14855static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
14856 struct net_device *dev)
14857{
14858 int ret;
14859
14860 vos_ssr_protect(__func__);
14861 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
14862 vos_ssr_unprotect(__func__);
14863
14864 return ret;
14865}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014866#endif /*FEATURE_WLAN_SCAN_PNO*/
14867
14868
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014869#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014870#if TDLS_MGMT_VERSION2
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014871static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014872 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014873 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
14874#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014875static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014876 u8 *peer, u8 action_code, u8 dialog_token,
14877 u16 status_code, const u8 *buf, size_t len)
14878#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014879{
14880
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014881 hdd_adapter_t *pAdapter;
14882 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014883 u8 peerMac[6];
14884 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070014885 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080014886 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070014887 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014888 int ret;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014889#if !(TDLS_MGMT_VERSION2)
14890 u32 peer_capability = 0;
14891#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014892 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014893
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014894 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14895 if (NULL == pAdapter)
14896 {
14897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14898 "%s: Adapter is NULL",__func__);
14899 return -EINVAL;
14900 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014901 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14902 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
14903 pAdapter->sessionId, action_code));
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014904 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014905 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014906 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014907 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014908 "Invalid arguments");
14909 return -EINVAL;
14910 }
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014911 if (pHddCtx->isLogpInProgress)
14912 {
14913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14914 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053014915 wlan_hdd_tdls_set_link_status(pAdapter,
14916 peer,
14917 eTDLS_LINK_IDLE,
14918 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014919 return -EBUSY;
14920 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014921 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
14922 {
14923 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14924 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14925 return -EAGAIN;
14926 }
Hoonki Lee27511902013-03-14 18:19:06 -070014927 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014928 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014929 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070014930 "%s: TDLS mode is disabled OR not enabled in FW."
14931 MAC_ADDRESS_STR " action %d declined.",
14932 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014933 return -ENOTSUPP;
14934 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014935
Hoonki Lee27511902013-03-14 18:19:06 -070014936 /* other than teardown frame, other mgmt frames are not sent if disabled */
14937 if (SIR_MAC_TDLS_TEARDOWN != action_code)
14938 {
14939 /* if tdls_mode is disabled to respond to peer's request */
14940 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
14941 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014942 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070014943 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014944 " TDLS mode is disabled. action %d declined.",
14945 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070014946
14947 return -ENOTSUPP;
14948 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014949
14950 if (vos_max_concurrent_connections_reached())
14951 {
14952 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14953 return -EINVAL;
14954 }
Hoonki Lee27511902013-03-14 18:19:06 -070014955 }
14956
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014957 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
14958 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053014959 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014960 {
14961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014962 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014963 " TDLS setup is ongoing. action %d declined.",
14964 __func__, MAC_ADDR_ARRAY(peer), action_code);
14965 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014966 }
14967 }
14968
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014969 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
14970 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080014971 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014972 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14973 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014974 {
14975 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
14976 we return error code at 'add_station()'. Hence we have this
14977 check again in addtion to add_station().
14978 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014979 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014980 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014981 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14982 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014983 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
14984 __func__, MAC_ADDR_ARRAY(peer), action_code,
14985 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053014986 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080014987 }
14988 else
14989 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014990 /* maximum reached. tweak to send error code to peer and return
14991 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014992 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014993 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14994 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014995 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
14996 __func__, MAC_ADDR_ARRAY(peer), status_code,
14997 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070014998 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014999 /* fall through to send setup resp with failure status
15000 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015001 }
15002 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015003 else
15004 {
15005 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053015006 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015007 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015008 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015010 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
15011 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015012 return -EPERM;
15013 }
15014 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015015 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015016 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015017
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015018 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015019 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015020 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
15021 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015022
Hoonki Leea34dd892013-02-05 22:56:02 -080015023 /*Except teardown responder will not be used so just make 0*/
15024 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015025 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080015026 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015027
15028 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053015029 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015030
15031 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
15032 responder = pTdlsPeer->is_responder;
15033 else
Hoonki Leea34dd892013-02-05 22:56:02 -080015034 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015036 "%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 -070015037 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
15038 dialog_token, status_code, len);
15039 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080015040 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015041 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015042
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015043 /* For explicit trigger of DIS_REQ come out of BMPS for
15044 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070015045 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015046 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
15047 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070015048 {
15049 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
15050 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015052 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015053 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
15054 if (status != VOS_STATUS_SUCCESS) {
15055 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
15056 }
Hoonki Lee14621352013-04-16 17:51:19 -070015057 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015058 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
15059 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED)) {
15060 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
15061 }
15062 }
Hoonki Lee14621352013-04-16 17:51:19 -070015063 }
15064
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015065 /* make sure doesn't call send_mgmt() while it is pending */
15066 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
15067 {
15068 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015069 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015070 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015071 ret = -EBUSY;
15072 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015073 }
15074
15075 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015076 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
15077
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015078 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053015079 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015080
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015081 if (VOS_STATUS_SUCCESS != status)
15082 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015083 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15084 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015085 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015086 ret = -EINVAL;
15087 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015088 }
15089
Hoonki Leed37cbb32013-04-20 00:31:14 -070015090 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
15091 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
15092
15093 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015094 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070015095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015096 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070015097 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015098 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080015099
15100 if (pHddCtx->isLogpInProgress)
15101 {
15102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15103 "%s: LOGP in Progress. Ignore!!!", __func__);
15104 return -EAGAIN;
15105 }
15106
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015107 ret = -EINVAL;
15108 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015109 }
15110
Gopichand Nakkala05922802013-03-14 12:23:19 -070015111 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070015112 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015113 ret = max_sta_failed;
15114 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070015115 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015116
Hoonki Leea34dd892013-02-05 22:56:02 -080015117 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
15118 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015119 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE)) {
15120 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15121 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015122 }
15123 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
15124 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015125 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE)) {
15126 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15127 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015128 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015129
15130 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015131
15132tx_failed:
15133 /* add_station will be called before sending TDLS_SETUP_REQ and
15134 * TDLS_SETUP_RSP and as part of add_station driver will enable
15135 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
15136 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
15137 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
15138 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
15139 */
15140
15141 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
15142 (SIR_MAC_TDLS_SETUP_RSP == action_code))
15143 wlan_hdd_tdls_check_bmps(pAdapter);
15144 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015145}
15146
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015147#if TDLS_MGMT_VERSION2
15148static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15149 u8 *peer, u8 action_code, u8 dialog_token,
15150 u16 status_code, u32 peer_capability,
15151 const u8 *buf, size_t len)
15152#else
15153static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15154 u8 *peer, u8 action_code, u8 dialog_token,
15155 u16 status_code, const u8 *buf, size_t len)
15156#endif
15157{
15158 int ret;
15159
15160 vos_ssr_protect(__func__);
15161#if TDLS_MGMT_VERSION2
15162 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
15163 status_code, peer_capability, buf, len);
15164#else
15165 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
15166 status_code, buf, len);
15167#endif
15168 vos_ssr_unprotect(__func__);
15169
15170 return ret;
15171}
Atul Mittal115287b2014-07-08 13:26:33 +053015172
15173int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
15174 u8 *peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015175 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053015176 cfg80211_exttdls_callback callback)
15177{
15178
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015179 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053015180 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015181 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053015182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15183 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
15184 __func__, MAC_ADDR_ARRAY(peer));
15185
15186 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15187 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15188
15189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015190 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15191 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15192 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015193 return -ENOTSUPP;
15194 }
15195
15196 /* To cater the requirement of establishing the TDLS link
15197 * irrespective of the data traffic , get an entry of TDLS peer.
15198 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015199 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015200 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
15201 if (pTdlsPeer == NULL) {
15202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15203 "%s: peer " MAC_ADDRESS_STR " not existing",
15204 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015205 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015206 return -EINVAL;
15207 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015208 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015209
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015210 /* check FW TDLS Off Channel capability */
15211 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015212 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015213 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015214 {
15215 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
15216 pTdlsPeer->peerParams.global_operating_class =
15217 tdls_peer_params->global_operating_class;
15218 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
15219 pTdlsPeer->peerParams.min_bandwidth_kbps =
15220 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015221 /* check configured channel is valid, non dfs and
15222 * not current operating channel */
15223 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
15224 tdls_peer_params->channel)) &&
15225 (pHddStaCtx) &&
15226 (tdls_peer_params->channel !=
15227 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015228 {
15229 pTdlsPeer->isOffChannelConfigured = TRUE;
15230 }
15231 else
15232 {
15233 pTdlsPeer->isOffChannelConfigured = FALSE;
15234 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15235 "%s: Configured Tdls Off Channel is not valid", __func__);
15236
15237 }
15238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015239 "%s: tdls_off_channel %d isOffChannelConfigured %d "
15240 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015241 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015242 pTdlsPeer->isOffChannelConfigured,
15243 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015244 }
15245 else
15246 {
15247 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015248 "%s: TDLS off channel FW capability %d, "
15249 "host capab %d or Invalid TDLS Peer Params", __func__,
15250 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
15251 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015252 }
15253
Atul Mittal115287b2014-07-08 13:26:33 +053015254 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
15255
15256 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15257 " %s TDLS Add Force Peer Failed",
15258 __func__);
15259 return -EINVAL;
15260 }
15261 /*EXT TDLS*/
15262
15263 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
15264 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15265 " %s TDLS set callback Failed",
15266 __func__);
15267 return -EINVAL;
15268 }
15269
15270 return(0);
15271
15272}
15273
15274int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
15275{
15276
15277 hddTdlsPeer_t *pTdlsPeer;
15278 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15279 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15280 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
15281 __func__, MAC_ADDR_ARRAY(peer));
15282
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015283 if (0 != wlan_hdd_validate_context(pHddCtx)) {
15284 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
15285 return -EINVAL;
15286 }
15287
Atul Mittal115287b2014-07-08 13:26:33 +053015288 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15289 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15290
15291 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015292 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15293 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15294 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015295 return -ENOTSUPP;
15296 }
15297
15298
15299 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15300
15301 if ( NULL == pTdlsPeer ) {
15302 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015303 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053015304 __func__, MAC_ADDR_ARRAY(peer));
15305 return -EINVAL;
15306 }
15307 else {
15308 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
15309 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015310 /* if channel switch is configured, reset
15311 the channel for this peer */
15312 if (TRUE == pTdlsPeer->isOffChannelConfigured)
15313 {
15314 pTdlsPeer->peerParams.channel = 0;
15315 pTdlsPeer->isOffChannelConfigured = FALSE;
15316 }
Atul Mittal115287b2014-07-08 13:26:33 +053015317 }
15318
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015319 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
15320 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053015321 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015322 }
Atul Mittal115287b2014-07-08 13:26:33 +053015323
15324 /*EXT TDLS*/
15325
15326 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
15327
15328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15329 " %s TDLS set callback Failed",
15330 __func__);
15331 return -EINVAL;
15332 }
15333 return(0);
15334
15335}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015336static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015337 u8 *peer, enum nl80211_tdls_operation oper)
15338{
15339 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15340 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015341 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015342 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015343
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015344 ENTER();
15345
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015346 if (!pAdapter) {
15347 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15348 return -EINVAL;
15349 }
15350
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015351 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15352 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
15353 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015354 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015355 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070015357 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015358 return -EINVAL;
15359 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015360
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015361 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015362 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015363 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015364 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015365 }
15366
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015367
15368 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015369 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015370 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015372 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
15373 "Cannot process TDLS commands",
15374 pHddCtx->cfg_ini->fEnableTDLSSupport,
15375 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015376 return -ENOTSUPP;
15377 }
15378
15379 switch (oper) {
15380 case NL80211_TDLS_ENABLE_LINK:
15381 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015382 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015383 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015384 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053015385 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015386 tANI_U16 numCurrTdlsPeers = 0;
15387 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015388 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015389
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15391 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
15392 __func__, MAC_ADDR_ARRAY(peer));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015393 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015394 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015395 if ( NULL == pTdlsPeer ) {
15396 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15397 " (oper %d) not exsting. ignored",
15398 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15399 return -EINVAL;
15400 }
15401
15402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15403 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15404 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15405 "NL80211_TDLS_ENABLE_LINK");
15406
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070015407 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
15408 {
15409 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
15410 MAC_ADDRESS_STR " failed",
15411 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
15412 return -EINVAL;
15413 }
15414
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053015415 /* before starting tdls connection, set tdls
15416 * off channel established status to default value */
15417 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015418 /* TDLS Off Channel, Disable tdls channel switch,
15419 when there are more than one tdls link */
15420 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053015421 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015422 {
15423 /* get connected peer and send disable tdls off chan */
15424 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015425 if ((connPeer) &&
15426 (connPeer->isOffChannelSupported == TRUE) &&
15427 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015428 {
15429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15430 "%s: More then one peer connected, Disable "
15431 "TDLS channel switch", __func__);
15432
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015433 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015434 ret = sme_SendTdlsChanSwitchReq(
15435 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015436 pAdapter->sessionId,
15437 connPeer->peerMac,
15438 connPeer->peerParams.channel,
15439 TDLS_OFF_CHANNEL_BW_OFFSET,
15440 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015441 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015442 hddLog(VOS_TRACE_LEVEL_ERROR,
15443 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015444 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015445 }
15446 else
15447 {
15448 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15449 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015450 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015451 "isOffChannelConfigured %d",
15452 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015453 (connPeer ? (connPeer->isOffChannelSupported)
15454 : -1),
15455 (connPeer ? (connPeer->isOffChannelConfigured)
15456 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015457 }
15458 }
15459
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015460 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015461 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015462 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053015463
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015464 if (0 != wlan_hdd_tdls_get_link_establish_params(
15465 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015467 return -EINVAL;
15468 }
15469 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015470
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015471 ret = sme_SendTdlsLinkEstablishParams(
15472 WLAN_HDD_GET_HAL_CTX(pAdapter),
15473 pAdapter->sessionId, peer,
15474 &tdlsLinkEstablishParams);
15475 if (ret != VOS_STATUS_SUCCESS) {
15476 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
15477 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015478 /* Send TDLS peer UAPSD capabilities to the firmware and
15479 * register with the TL on after the response for this operation
15480 * is received .
15481 */
15482 ret = wait_for_completion_interruptible_timeout(
15483 &pAdapter->tdls_link_establish_req_comp,
15484 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
15485 if (ret <= 0)
15486 {
15487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015488 FL("Link Establish Request Failed Status %ld"),
15489 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015490 return -EINVAL;
15491 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015492 }
Atul Mittal115287b2014-07-08 13:26:33 +053015493 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15494 eTDLS_LINK_CONNECTED,
15495 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015496 staDesc.ucSTAId = pTdlsPeer->staId;
15497 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015498 ret = WLANTL_UpdateTdlsSTAClient(
15499 pHddCtx->pvosContext,
15500 &staDesc);
15501 if (ret != VOS_STATUS_SUCCESS) {
15502 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
15503 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053015504
Gopichand Nakkala471708b2013-06-04 20:03:01 +053015505 /* Mark TDLS client Authenticated .*/
15506 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
15507 pTdlsPeer->staId,
15508 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015509 if (VOS_STATUS_SUCCESS == status)
15510 {
Hoonki Lee14621352013-04-16 17:51:19 -070015511 if (pTdlsPeer->is_responder == 0)
15512 {
15513 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
15514
15515 wlan_hdd_tdls_timer_restart(pAdapter,
15516 &pTdlsPeer->initiatorWaitTimeoutTimer,
15517 WAIT_TIME_TDLS_INITIATOR);
15518 /* suspend initiator TX until it receives direct packet from the
15519 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015520 ret = WLANTL_SuspendDataTx(
15521 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15522 &staId, NULL);
15523 if (ret != VOS_STATUS_SUCCESS) {
15524 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
15525 }
Hoonki Lee14621352013-04-16 17:51:19 -070015526 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015527
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015528 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015529 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015530 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015531 suppChannelLen =
15532 tdlsLinkEstablishParams.supportedChannelsLen;
15533
15534 if ((suppChannelLen > 0) &&
15535 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
15536 {
15537 tANI_U8 suppPeerChannel = 0;
15538 int i = 0;
15539 for (i = 0U; i < suppChannelLen; i++)
15540 {
15541 suppPeerChannel =
15542 tdlsLinkEstablishParams.supportedChannels[i];
15543
15544 pTdlsPeer->isOffChannelSupported = FALSE;
15545 if (suppPeerChannel ==
15546 pTdlsPeer->peerParams.channel)
15547 {
15548 pTdlsPeer->isOffChannelSupported = TRUE;
15549 break;
15550 }
15551 }
15552 }
15553 else
15554 {
15555 pTdlsPeer->isOffChannelSupported = FALSE;
15556 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015557 }
15558 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15559 "%s: TDLS channel switch request for channel "
15560 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015561 "%d isOffChannelSupported %d", __func__,
15562 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015563 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015564 suppChannelLen,
15565 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015566
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015567 /* TDLS Off Channel, Enable tdls channel switch,
15568 when their is only one tdls link and it supports */
15569 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15570 if ((numCurrTdlsPeers == 1) &&
15571 (TRUE == pTdlsPeer->isOffChannelSupported) &&
15572 (TRUE == pTdlsPeer->isOffChannelConfigured))
15573 {
15574 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15575 "%s: Send TDLS channel switch request for channel %d",
15576 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015577
15578 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015579 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
15580 pAdapter->sessionId,
15581 pTdlsPeer->peerMac,
15582 pTdlsPeer->peerParams.channel,
15583 TDLS_OFF_CHANNEL_BW_OFFSET,
15584 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015585 if (ret != VOS_STATUS_SUCCESS) {
15586 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
15587 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015588 }
15589 else
15590 {
15591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15592 "%s: TDLS channel switch request not sent"
15593 " numCurrTdlsPeers %d "
15594 "isOffChannelSupported %d "
15595 "isOffChannelConfigured %d",
15596 __func__, numCurrTdlsPeers,
15597 pTdlsPeer->isOffChannelSupported,
15598 pTdlsPeer->isOffChannelConfigured);
15599 }
15600
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015601 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015602 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015603
15604 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015605 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
15606 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015607 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015608 int ac;
15609 uint8 ucAc[4] = { WLANTL_AC_VO,
15610 WLANTL_AC_VI,
15611 WLANTL_AC_BK,
15612 WLANTL_AC_BE };
15613 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
15614 for(ac=0; ac < 4; ac++)
15615 {
15616 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15617 pTdlsPeer->staId, ucAc[ac],
15618 tlTid[ac], tlTid[ac], 0, 0,
15619 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015620 if (status != VOS_STATUS_SUCCESS) {
15621 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
15622 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015623 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015624 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015625 }
15626
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015627 }
15628 break;
15629 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080015630 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015631 tANI_U16 numCurrTdlsPeers = 0;
15632 hddTdlsPeer_t *connPeer = NULL;
15633
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15635 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
15636 __func__, MAC_ADDR_ARRAY(peer));
15637
Sunil Dutt41de4e22013-11-14 18:09:02 +053015638 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15639
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015640
Sunil Dutt41de4e22013-11-14 18:09:02 +053015641 if ( NULL == pTdlsPeer ) {
15642 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15643 " (oper %d) not exsting. ignored",
15644 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15645 return -EINVAL;
15646 }
15647
15648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15649 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15650 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15651 "NL80211_TDLS_DISABLE_LINK");
15652
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015653 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080015654 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015655 long status;
15656
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053015657 /* set tdls off channel status to false for this peer */
15658 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053015659 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15660 eTDLS_LINK_TEARING,
15661 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
15662 eTDLS_LINK_UNSPECIFIED:
15663 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015664 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
15665
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015666 status = sme_DeleteTdlsPeerSta(
15667 WLAN_HDD_GET_HAL_CTX(pAdapter),
15668 pAdapter->sessionId, peer );
15669 if (status != VOS_STATUS_SUCCESS) {
15670 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15671 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015672
15673 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
15674 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053015675 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053015676 eTDLS_LINK_IDLE,
15677 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015678 if (status <= 0)
15679 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15681 "%s: Del station failed status %ld",
15682 __func__, status);
15683 return -EPERM;
15684 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015685
15686 /* TDLS Off Channel, Enable tdls channel switch,
15687 when their is only one tdls link and it supports */
15688 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15689 if (numCurrTdlsPeers == 1)
15690 {
15691 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
15692 if ((connPeer) &&
15693 (connPeer->isOffChannelSupported == TRUE) &&
15694 (connPeer->isOffChannelConfigured == TRUE))
15695 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015696 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015697 status = sme_SendTdlsChanSwitchReq(
15698 WLAN_HDD_GET_HAL_CTX(pAdapter),
15699 pAdapter->sessionId,
15700 connPeer->peerMac,
15701 connPeer->peerParams.channel,
15702 TDLS_OFF_CHANNEL_BW_OFFSET,
15703 TDLS_CHANNEL_SWITCH_ENABLE);
15704 if (status != VOS_STATUS_SUCCESS) {
15705 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
15706 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015707 }
15708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15709 "%s: TDLS channel switch "
15710 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015711 "isOffChannelConfigured %d "
15712 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015713 __func__,
15714 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015715 (connPeer ? connPeer->isOffChannelConfigured : -1),
15716 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015717 }
15718 else
15719 {
15720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15721 "%s: TDLS channel switch request not sent "
15722 "numCurrTdlsPeers %d ",
15723 __func__, numCurrTdlsPeers);
15724 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015725 }
15726 else
15727 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015728 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15729 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080015730 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015731 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015732 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015733 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015734 {
Atul Mittal115287b2014-07-08 13:26:33 +053015735 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015736
Atul Mittal115287b2014-07-08 13:26:33 +053015737 if (0 != status)
15738 {
15739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015740 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053015741 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015742 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053015743 break;
15744 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015745 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015746 {
Atul Mittal115287b2014-07-08 13:26:33 +053015747 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
15748 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015749 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053015750 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015751
Atul Mittal115287b2014-07-08 13:26:33 +053015752 if (0 != status)
15753 {
15754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015755 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053015756 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053015757 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053015758 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015759 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015760 case NL80211_TDLS_DISCOVERY_REQ:
15761 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015763 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015764 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015765 return -ENOTSUPP;
15766 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015767 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15768 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015769 return -ENOTSUPP;
15770 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015771
15772 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015773 return 0;
15774}
Chilam NG571c65a2013-01-19 12:27:36 +053015775
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015776static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
15777 u8 *peer, enum nl80211_tdls_operation oper)
15778{
15779 int ret;
15780
15781 vos_ssr_protect(__func__);
15782 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
15783 vos_ssr_unprotect(__func__);
15784
15785 return ret;
15786}
15787
Chilam NG571c65a2013-01-19 12:27:36 +053015788int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
15789 struct net_device *dev, u8 *peer)
15790{
Arif Hussaina7c8e412013-11-20 11:06:42 -080015791 hddLog(VOS_TRACE_LEVEL_INFO,
15792 "tdls send discover req: "MAC_ADDRESS_STR,
15793 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053015794
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015795#if TDLS_MGMT_VERSION2
15796 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15797 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15798#else
Chilam NG571c65a2013-01-19 12:27:36 +053015799 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15800 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015801#endif
Chilam NG571c65a2013-01-19 12:27:36 +053015802}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015803#endif
15804
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015805#ifdef WLAN_FEATURE_GTK_OFFLOAD
15806/*
15807 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
15808 * Callback rountine called upon receiving response for
15809 * get offload info
15810 */
15811void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
15812 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
15813{
15814
15815 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015816 tANI_U8 tempReplayCounter[8];
15817 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015818
15819 ENTER();
15820
15821 if (NULL == pAdapter)
15822 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053015823 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015824 "%s: HDD adapter is Null", __func__);
15825 return ;
15826 }
15827
15828 if (NULL == pGtkOffloadGetInfoRsp)
15829 {
15830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15831 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
15832 return ;
15833 }
15834
15835 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
15836 {
15837 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15838 "%s: wlan Failed to get replay counter value",
15839 __func__);
15840 return ;
15841 }
15842
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015843 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15844 /* Update replay counter */
15845 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
15846 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15847
15848 {
15849 /* changing from little to big endian since supplicant
15850 * works on big endian format
15851 */
15852 int i;
15853 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15854
15855 for (i = 0; i < 8; i++)
15856 {
15857 tempReplayCounter[7-i] = (tANI_U8)p[i];
15858 }
15859 }
15860
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015861 /* Update replay counter to NL */
15862 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015863 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015864}
15865
15866/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015867 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015868 * This function is used to offload GTK rekeying job to the firmware.
15869 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015870int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015871 struct cfg80211_gtk_rekey_data *data)
15872{
15873 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15874 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15875 hdd_station_ctx_t *pHddStaCtx;
15876 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015877 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015878 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015879 eHalStatus status = eHAL_STATUS_FAILURE;
15880
15881 ENTER();
15882
15883 if (NULL == pAdapter)
15884 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015886 "%s: HDD adapter is Null", __func__);
15887 return -ENODEV;
15888 }
15889
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015890 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15891 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
15892 pAdapter->sessionId, pAdapter->device_mode));
15893
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015894 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015895 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015896 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015897 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015898 }
15899
15900 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15901 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15902 if (NULL == hHal)
15903 {
15904 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15905 "%s: HAL context is Null!!!", __func__);
15906 return -EAGAIN;
15907 }
15908
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015909 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
15910 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
15911 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
15912 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015913 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015914 {
15915 /* changing from big to little endian since driver
15916 * works on little endian format
15917 */
15918 tANI_U8 *p =
15919 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
15920 int i;
15921
15922 for (i = 0; i < 8; i++)
15923 {
15924 p[7-i] = data->replay_ctr[i];
15925 }
15926 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015927
15928 if (TRUE == pHddCtx->hdd_wlan_suspended)
15929 {
15930 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015931 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
15932 sizeof (tSirGtkOffloadParams));
15933 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015934 pAdapter->sessionId);
15935
15936 if (eHAL_STATUS_SUCCESS != status)
15937 {
15938 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15939 "%s: sme_SetGTKOffload failed, returned %d",
15940 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053015941
15942 /* Need to clear any trace of key value in the memory.
15943 * Thus zero out the memory even though it is local
15944 * variable.
15945 */
15946 vos_mem_zero(&hddGtkOffloadReqParams,
15947 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015948 return status;
15949 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015950 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15951 "%s: sme_SetGTKOffload successfull", __func__);
15952 }
15953 else
15954 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015955 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15956 "%s: wlan not suspended GTKOffload request is stored",
15957 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015958 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015959
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053015960 /* Need to clear any trace of key value in the memory.
15961 * Thus zero out the memory even though it is local
15962 * variable.
15963 */
15964 vos_mem_zero(&hddGtkOffloadReqParams,
15965 sizeof(hddGtkOffloadReqParams));
15966
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015967 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015968 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015969}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015970
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015971int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
15972 struct cfg80211_gtk_rekey_data *data)
15973{
15974 int ret;
15975
15976 vos_ssr_protect(__func__);
15977 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
15978 vos_ssr_unprotect(__func__);
15979
15980 return ret;
15981}
15982#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015983/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015984 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015985 * This function is used to set access control policy
15986 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015987static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
15988 struct net_device *dev,
15989 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015990{
15991 int i;
15992 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15993 hdd_hostapd_state_t *pHostapdState;
15994 tsap_Config_t *pConfig;
15995 v_CONTEXT_t pVosContext = NULL;
15996 hdd_context_t *pHddCtx;
15997 int status;
15998
15999 ENTER();
16000
16001 if (NULL == pAdapter)
16002 {
16003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16004 "%s: HDD adapter is Null", __func__);
16005 return -ENODEV;
16006 }
16007
16008 if (NULL == params)
16009 {
16010 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16011 "%s: params is Null", __func__);
16012 return -EINVAL;
16013 }
16014
16015 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16016 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016017 if (0 != status)
16018 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016019 return status;
16020 }
16021
16022 pVosContext = pHddCtx->pvosContext;
16023 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
16024
16025 if (NULL == pHostapdState)
16026 {
16027 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16028 "%s: pHostapdState is Null", __func__);
16029 return -EINVAL;
16030 }
16031
16032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
16033 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016034 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16035 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
16036 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016037
16038 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
16039 {
16040 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
16041
16042 /* default value */
16043 pConfig->num_accept_mac = 0;
16044 pConfig->num_deny_mac = 0;
16045
16046 /**
16047 * access control policy
16048 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
16049 * listed in hostapd.deny file.
16050 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
16051 * listed in hostapd.accept file.
16052 */
16053 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
16054 {
16055 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
16056 }
16057 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
16058 {
16059 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
16060 }
16061 else
16062 {
16063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16064 "%s:Acl Policy : %d is not supported",
16065 __func__, params->acl_policy);
16066 return -ENOTSUPP;
16067 }
16068
16069 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
16070 {
16071 pConfig->num_accept_mac = params->n_acl_entries;
16072 for (i = 0; i < params->n_acl_entries; i++)
16073 {
16074 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16075 "** Add ACL MAC entry %i in WhiletList :"
16076 MAC_ADDRESS_STR, i,
16077 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16078
16079 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
16080 sizeof(qcmacaddr));
16081 }
16082 }
16083 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
16084 {
16085 pConfig->num_deny_mac = params->n_acl_entries;
16086 for (i = 0; i < params->n_acl_entries; i++)
16087 {
16088 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16089 "** Add ACL MAC entry %i in BlackList :"
16090 MAC_ADDRESS_STR, i,
16091 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16092
16093 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
16094 sizeof(qcmacaddr));
16095 }
16096 }
16097
16098 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
16099 {
16100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16101 "%s: SAP Set Mac Acl fail", __func__);
16102 return -EINVAL;
16103 }
16104 }
16105 else
16106 {
16107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016108 "%s: Invalid device_mode = %s (%d)",
16109 __func__, hdd_device_modetoString(pAdapter->device_mode),
16110 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016111 return -EINVAL;
16112 }
16113
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016114 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016115 return 0;
16116}
16117
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016118static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16119 struct net_device *dev,
16120 const struct cfg80211_acl_data *params)
16121{
16122 int ret;
16123 vos_ssr_protect(__func__);
16124 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
16125 vos_ssr_unprotect(__func__);
16126
16127 return ret;
16128}
16129
Leo Chang9056f462013-08-01 19:21:11 -070016130#ifdef WLAN_NL80211_TESTMODE
16131#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070016132void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070016133(
16134 void *pAdapter,
16135 void *indCont
16136)
16137{
Leo Changd9df8aa2013-09-26 13:32:26 -070016138 tSirLPHBInd *lphbInd;
16139 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053016140 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070016141
16142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016143 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070016144
c_hpothu73f35e62014-04-18 13:40:08 +053016145 if (pAdapter == NULL)
16146 {
16147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16148 "%s: pAdapter is NULL\n",__func__);
16149 return;
16150 }
16151
Leo Chang9056f462013-08-01 19:21:11 -070016152 if (NULL == indCont)
16153 {
16154 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016155 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070016156 return;
16157 }
16158
c_hpothu73f35e62014-04-18 13:40:08 +053016159 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070016160 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070016161 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053016162 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070016163 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070016164 GFP_ATOMIC);
16165 if (!skb)
16166 {
16167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16168 "LPHB timeout, NL buffer alloc fail");
16169 return;
16170 }
16171
Leo Changac3ba772013-10-07 09:47:04 -070016172 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070016173 {
16174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16175 "WLAN_HDD_TM_ATTR_CMD put fail");
16176 goto nla_put_failure;
16177 }
Leo Changac3ba772013-10-07 09:47:04 -070016178 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070016179 {
16180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16181 "WLAN_HDD_TM_ATTR_TYPE put fail");
16182 goto nla_put_failure;
16183 }
Leo Changac3ba772013-10-07 09:47:04 -070016184 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070016185 sizeof(tSirLPHBInd), lphbInd))
16186 {
16187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16188 "WLAN_HDD_TM_ATTR_DATA put fail");
16189 goto nla_put_failure;
16190 }
Leo Chang9056f462013-08-01 19:21:11 -070016191 cfg80211_testmode_event(skb, GFP_ATOMIC);
16192 return;
16193
16194nla_put_failure:
16195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16196 "NLA Put fail");
16197 kfree_skb(skb);
16198
16199 return;
16200}
16201#endif /* FEATURE_WLAN_LPHB */
16202
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016203static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070016204{
16205 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
16206 int err = 0;
16207#ifdef FEATURE_WLAN_LPHB
16208 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070016209 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016210
16211 ENTER();
16212
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016213 err = wlan_hdd_validate_context(pHddCtx);
16214 if (0 != err)
16215 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016216 return err;
16217 }
Leo Chang9056f462013-08-01 19:21:11 -070016218#endif /* FEATURE_WLAN_LPHB */
16219
16220 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
16221 if (err)
16222 {
16223 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16224 "%s Testmode INV ATTR", __func__);
16225 return err;
16226 }
16227
16228 if (!tb[WLAN_HDD_TM_ATTR_CMD])
16229 {
16230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16231 "%s Testmode INV CMD", __func__);
16232 return -EINVAL;
16233 }
16234
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016235 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16236 TRACE_CODE_HDD_CFG80211_TESTMODE,
16237 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070016238 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
16239 {
16240#ifdef FEATURE_WLAN_LPHB
16241 /* Low Power Heartbeat configuration request */
16242 case WLAN_HDD_TM_CMD_WLAN_HB:
16243 {
16244 int buf_len;
16245 void *buf;
16246 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080016247 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070016248
16249 if (!tb[WLAN_HDD_TM_ATTR_DATA])
16250 {
16251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16252 "%s Testmode INV DATA", __func__);
16253 return -EINVAL;
16254 }
16255
16256 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
16257 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080016258
16259 hb_params_temp =(tSirLPHBReq *)buf;
16260 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
16261 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
16262 return -EINVAL;
16263
Leo Chang9056f462013-08-01 19:21:11 -070016264 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
16265 if (NULL == hb_params)
16266 {
16267 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16268 "%s Request Buffer Alloc Fail", __func__);
16269 return -EINVAL;
16270 }
16271
16272 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070016273 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
16274 hb_params,
16275 wlan_hdd_cfg80211_lphb_ind_handler);
16276 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070016277 {
Leo Changd9df8aa2013-09-26 13:32:26 -070016278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16279 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070016280 vos_mem_free(hb_params);
16281 }
Leo Chang9056f462013-08-01 19:21:11 -070016282 return 0;
16283 }
16284#endif /* FEATURE_WLAN_LPHB */
16285 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16287 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070016288 return -EOPNOTSUPP;
16289 }
16290
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016291 EXIT();
16292 return err;
Leo Chang9056f462013-08-01 19:21:11 -070016293}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016294
16295static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
16296{
16297 int ret;
16298
16299 vos_ssr_protect(__func__);
16300 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
16301 vos_ssr_unprotect(__func__);
16302
16303 return ret;
16304}
Leo Chang9056f462013-08-01 19:21:11 -070016305#endif /* CONFIG_NL80211_TESTMODE */
16306
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016307static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016308 struct net_device *dev,
16309 int idx, struct survey_info *survey)
16310{
16311 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16312 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053016313 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016314 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053016315 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016316 v_S7_t snr,rssi;
16317 int status, i, j, filled = 0;
16318
16319 ENTER();
16320
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016321 if (NULL == pAdapter)
16322 {
16323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16324 "%s: HDD adapter is Null", __func__);
16325 return -ENODEV;
16326 }
16327
16328 if (NULL == wiphy)
16329 {
16330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16331 "%s: wiphy is Null", __func__);
16332 return -ENODEV;
16333 }
16334
16335 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16336 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016337 if (0 != status)
16338 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016339 return status;
16340 }
16341
Mihir Sheted9072e02013-08-21 17:02:29 +053016342 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16343
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016344 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053016345 0 != pAdapter->survey_idx ||
16346 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016347 {
16348 /* The survey dump ops when implemented completely is expected to
16349 * return a survey of all channels and the ops is called by the
16350 * kernel with incremental values of the argument 'idx' till it
16351 * returns -ENONET. But we can only support the survey for the
16352 * operating channel for now. survey_idx is used to track
16353 * that the ops is called only once and then return -ENONET for
16354 * the next iteration
16355 */
16356 pAdapter->survey_idx = 0;
16357 return -ENONET;
16358 }
16359
Mukul Sharma9d5233b2015-06-11 20:28:20 +053016360 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16361 {
16362 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16363 "%s: Roaming in progress, hence return ", __func__);
16364 return -ENONET;
16365 }
16366
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016367 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16368
16369 wlan_hdd_get_snr(pAdapter, &snr);
16370 wlan_hdd_get_rssi(pAdapter, &rssi);
16371
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016372 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16373 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
16374 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016375 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
16376 hdd_wlan_get_freq(channel, &freq);
16377
16378
16379 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
16380 {
16381 if (NULL == wiphy->bands[i])
16382 {
16383 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
16384 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
16385 continue;
16386 }
16387
16388 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
16389 {
16390 struct ieee80211_supported_band *band = wiphy->bands[i];
16391
16392 if (band->channels[j].center_freq == (v_U16_t)freq)
16393 {
16394 survey->channel = &band->channels[j];
16395 /* The Rx BDs contain SNR values in dB for the received frames
16396 * while the supplicant expects noise. So we calculate and
16397 * return the value of noise (dBm)
16398 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
16399 */
16400 survey->noise = rssi - snr;
16401 survey->filled = SURVEY_INFO_NOISE_DBM;
16402 filled = 1;
16403 }
16404 }
16405 }
16406
16407 if (filled)
16408 pAdapter->survey_idx = 1;
16409 else
16410 {
16411 pAdapter->survey_idx = 0;
16412 return -ENONET;
16413 }
16414
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016415 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016416 return 0;
16417}
16418
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016419static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
16420 struct net_device *dev,
16421 int idx, struct survey_info *survey)
16422{
16423 int ret;
16424
16425 vos_ssr_protect(__func__);
16426 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
16427 vos_ssr_unprotect(__func__);
16428
16429 return ret;
16430}
16431
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016432/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016433 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016434 * this is called when cfg80211 driver resume
16435 * driver updates latest sched_scan scan result(if any) to cfg80211 database
16436 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016437int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016438{
16439 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16440 hdd_adapter_t *pAdapter;
16441 hdd_adapter_list_node_t *pAdapterNode, *pNext;
16442 VOS_STATUS status = VOS_STATUS_SUCCESS;
16443
16444 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016445
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016446 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016447 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016448 return 0;
16449 }
16450
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016451 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
16452 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016453 spin_lock(&pHddCtx->schedScan_lock);
16454 pHddCtx->isWiphySuspended = FALSE;
16455 if (TRUE != pHddCtx->isSchedScanUpdatePending)
16456 {
16457 spin_unlock(&pHddCtx->schedScan_lock);
16458 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16459 "%s: Return resume is not due to PNO indication", __func__);
16460 return 0;
16461 }
16462 // Reset flag to avoid updatating cfg80211 data old results again
16463 pHddCtx->isSchedScanUpdatePending = FALSE;
16464 spin_unlock(&pHddCtx->schedScan_lock);
16465
16466 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
16467
16468 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
16469 {
16470 pAdapter = pAdapterNode->pAdapter;
16471 if ( (NULL != pAdapter) &&
16472 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
16473 {
16474 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016475 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16477 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016478 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016479 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016480 {
16481 /* Acquire wakelock to handle the case where APP's tries to
16482 * suspend immediately after updating the scan results. Whis
16483 * results in app's is in suspended state and not able to
16484 * process the connect request to AP
16485 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053016486 hdd_prevent_suspend_timeout(2000,
16487 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016488 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016489 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016490
16491 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16492 "%s : cfg80211 scan result database updated", __func__);
16493
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016494 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016495 return 0;
16496
16497 }
16498 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16499 pAdapterNode = pNext;
16500 }
16501
16502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16503 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016504 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016505 return 0;
16506}
16507
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016508int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
16509{
16510 int ret;
16511
16512 vos_ssr_protect(__func__);
16513 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
16514 vos_ssr_unprotect(__func__);
16515
16516 return ret;
16517}
16518
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016519/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016520 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016521 * this is called when cfg80211 driver suspends
16522 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016523int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016524 struct cfg80211_wowlan *wow)
16525{
16526 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016527 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016528
16529 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016530
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016531 ret = wlan_hdd_validate_context(pHddCtx);
16532 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016533 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016534 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016535 }
16536
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016537
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016538 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16539 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
16540 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016541 pHddCtx->isWiphySuspended = TRUE;
16542
16543 EXIT();
16544
16545 return 0;
16546}
16547
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016548int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
16549 struct cfg80211_wowlan *wow)
16550{
16551 int ret;
16552
16553 vos_ssr_protect(__func__);
16554 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
16555 vos_ssr_unprotect(__func__);
16556
16557 return ret;
16558}
Jeff Johnson295189b2012-06-20 16:38:30 -070016559/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016560static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070016561{
16562 .add_virtual_intf = wlan_hdd_add_virtual_intf,
16563 .del_virtual_intf = wlan_hdd_del_virtual_intf,
16564 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
16565 .change_station = wlan_hdd_change_station,
16566#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
16567 .add_beacon = wlan_hdd_cfg80211_add_beacon,
16568 .del_beacon = wlan_hdd_cfg80211_del_beacon,
16569 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016570#else
16571 .start_ap = wlan_hdd_cfg80211_start_ap,
16572 .change_beacon = wlan_hdd_cfg80211_change_beacon,
16573 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070016574#endif
16575 .change_bss = wlan_hdd_cfg80211_change_bss,
16576 .add_key = wlan_hdd_cfg80211_add_key,
16577 .get_key = wlan_hdd_cfg80211_get_key,
16578 .del_key = wlan_hdd_cfg80211_del_key,
16579 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016580#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070016581 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016582#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016583 .scan = wlan_hdd_cfg80211_scan,
16584 .connect = wlan_hdd_cfg80211_connect,
16585 .disconnect = wlan_hdd_cfg80211_disconnect,
16586 .join_ibss = wlan_hdd_cfg80211_join_ibss,
16587 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
16588 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
16589 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
16590 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070016591 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
16592 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053016593 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070016594#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16595 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
16596 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
16597 .set_txq_params = wlan_hdd_set_txq_params,
16598#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016599 .get_station = wlan_hdd_cfg80211_get_station,
16600 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
16601 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016602 .add_station = wlan_hdd_cfg80211_add_station,
16603#ifdef FEATURE_WLAN_LFR
16604 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
16605 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
16606 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
16607#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016608#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
16609 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
16610#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016611#ifdef FEATURE_WLAN_TDLS
16612 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
16613 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
16614#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016615#ifdef WLAN_FEATURE_GTK_OFFLOAD
16616 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
16617#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016618#ifdef FEATURE_WLAN_SCAN_PNO
16619 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
16620 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
16621#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016622 .resume = wlan_hdd_cfg80211_resume_wlan,
16623 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016624 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070016625#ifdef WLAN_NL80211_TESTMODE
16626 .testmode_cmd = wlan_hdd_cfg80211_testmode,
16627#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016628 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070016629};
16630