blob: 9123028c2a75cb56531a8e8c1615c26b3f8387ef [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. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05305832#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
5833 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
5834#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07005835 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05305836#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07005837
Amar Singhala49cbc52013-10-08 18:37:44 -07005838
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005839#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005840 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5841 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5842 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005843 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05305844#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
5845 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
5846#else
5847 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
5848#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005849#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005850
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005851#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005852 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005853#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005854 || pCfg->isFastRoamIniFeatureEnabled
5855#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005856#ifdef FEATURE_WLAN_ESE
5857 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005858#endif
5859 )
5860 {
5861 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5862 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005863#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005864#ifdef FEATURE_WLAN_TDLS
5865 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5866 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5867#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305868#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305869 if (pCfg->configPNOScanSupport)
5870 {
5871 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5872 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5873 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5874 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5875 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305876#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005877
Abhishek Singh10d85972015-04-17 10:27:23 +05305878#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5879 wiphy->features |= NL80211_FEATURE_HT_IBSS;
5880#endif
5881
Amar Singhalfddc28c2013-09-05 13:03:40 -07005882#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005883 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5884 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005885 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005886 driver need to determine what to do with both
5887 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005888
5889 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005890#else
5891 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005892#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005893
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305894 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5895
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05305896 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005897
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305898 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5899
Jeff Johnson295189b2012-06-20 16:38:30 -07005900 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05305901 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
5902 | BIT(NL80211_IFTYPE_ADHOC)
5903 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5904 | BIT(NL80211_IFTYPE_P2P_GO)
5905 | BIT(NL80211_IFTYPE_AP);
5906
5907 if (VOS_MONITOR_MODE == hdd_get_conparam())
5908 {
5909 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
5910 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005911
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305912 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005913 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305914#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5915 if( pCfg->enableMCC )
5916 {
5917 /* Currently, supports up to two channels */
5918 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005919
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305920 if( !pCfg->allowMCCGODiffBI )
5921 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005922
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305923 }
5924 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5925 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005926#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305927 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005928
Jeff Johnson295189b2012-06-20 16:38:30 -07005929 /* Before registering we need to update the ht capabilitied based
5930 * on ini values*/
5931 if( !pCfg->ShortGI20MhzEnable )
5932 {
5933 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5934 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5935 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5936 }
5937
5938 if( !pCfg->ShortGI40MhzEnable )
5939 {
5940 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5941 }
5942
5943 if( !pCfg->nChannelBondingMode5GHz )
5944 {
5945 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5946 }
5947
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305948 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305949 if (true == hdd_is_5g_supported(pHddCtx))
5950 {
5951 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5952 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305953
5954 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5955 {
5956
5957 if (NULL == wiphy->bands[i])
5958 {
5959 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5960 __func__, i);
5961 continue;
5962 }
5963
5964 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5965 {
5966 struct ieee80211_supported_band *band = wiphy->bands[i];
5967
5968 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5969 {
5970 // Enable social channels for P2P
5971 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5972 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5973 else
5974 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5975 continue;
5976 }
5977 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5978 {
5979 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5980 continue;
5981 }
5982 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005983 }
5984 /*Initialise the supported cipher suite details*/
5985 wiphy->cipher_suites = hdd_cipher_suites;
5986 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5987
5988 /*signal strength in mBm (100*dBm) */
5989 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5990
5991#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305992 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005993#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005994
Sunil Duttc69bccb2014-05-26 21:30:20 +05305995 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
5996 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005997 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
5998 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
5999
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306000 EXIT();
6001 return 0;
6002}
6003
6004/* In this function we are registering wiphy. */
6005int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
6006{
6007 ENTER();
6008 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006009 if (0 > wiphy_register(wiphy))
6010 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306011 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07006012 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
6013 return -EIO;
6014 }
6015
6016 EXIT();
6017 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306018}
Jeff Johnson295189b2012-06-20 16:38:30 -07006019
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306020/* In this function we are updating channel list when,
6021 regulatory domain is FCC and country code is US.
6022 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
6023 As per FCC smart phone is not a indoor device.
6024 GO should not opeate on indoor channels */
6025void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
6026{
6027 int j;
6028 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6029 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
6030 //Default counrtycode from NV at the time of wiphy initialization.
6031 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
6032 &defaultCountryCode[0]))
6033 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006034 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306035 }
6036 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
6037 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306038 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
6039 {
6040 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
6041 return;
6042 }
6043 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
6044 {
6045 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
6046 // Mark UNII -1 band channel as passive
6047 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
6048 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
6049 }
6050 }
6051}
6052
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306053/* This function registers for all frame which supplicant is interested in */
6054void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006055{
Jeff Johnson295189b2012-06-20 16:38:30 -07006056 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6057 /* Register for all P2P action, public action etc frames */
6058 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6059
Jeff Johnsone7245742012-09-05 17:12:55 -07006060 ENTER();
6061
Jeff Johnson295189b2012-06-20 16:38:30 -07006062 /* Right now we are registering these frame when driver is getting
6063 initialized. Once we will move to 2.6.37 kernel, in which we have
6064 frame register ops, we will move this code as a part of that */
6065 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306066 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006067 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6068
6069 /* GAS Initial Response */
6070 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6071 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306072
Jeff Johnson295189b2012-06-20 16:38:30 -07006073 /* GAS Comeback Request */
6074 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6075 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6076
6077 /* GAS Comeback Response */
6078 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6079 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6080
6081 /* P2P Public Action */
6082 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306083 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006084 P2P_PUBLIC_ACTION_FRAME_SIZE );
6085
6086 /* P2P Action */
6087 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6088 (v_U8_t*)P2P_ACTION_FRAME,
6089 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07006090
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05306091 /* WNM BSS Transition Request frame */
6092 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6093 (v_U8_t*)WNM_BSS_ACTION_FRAME,
6094 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006095
6096 /* WNM-Notification */
6097 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6098 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6099 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006100}
6101
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306102void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006103{
Jeff Johnson295189b2012-06-20 16:38:30 -07006104 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6105 /* Register for all P2P action, public action etc frames */
6106 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6107
Jeff Johnsone7245742012-09-05 17:12:55 -07006108 ENTER();
6109
Jeff Johnson295189b2012-06-20 16:38:30 -07006110 /* Right now we are registering these frame when driver is getting
6111 initialized. Once we will move to 2.6.37 kernel, in which we have
6112 frame register ops, we will move this code as a part of that */
6113 /* GAS Initial Request */
6114
6115 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6116 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6117
6118 /* GAS Initial Response */
6119 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6120 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306121
Jeff Johnson295189b2012-06-20 16:38:30 -07006122 /* GAS Comeback Request */
6123 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6124 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6125
6126 /* GAS Comeback Response */
6127 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6128 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6129
6130 /* P2P Public Action */
6131 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306132 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006133 P2P_PUBLIC_ACTION_FRAME_SIZE );
6134
6135 /* P2P Action */
6136 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6137 (v_U8_t*)P2P_ACTION_FRAME,
6138 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006139 /* WNM-Notification */
6140 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6141 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6142 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006143}
6144
6145#ifdef FEATURE_WLAN_WAPI
6146void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
6147 const u8 *mac_addr, u8 *key , int key_Len)
6148{
6149 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6150 tCsrRoamSetKey setKey;
6151 v_BOOL_t isConnected = TRUE;
6152 int status = 0;
6153 v_U32_t roamId= 0xFF;
6154 tANI_U8 *pKeyPtr = NULL;
6155 int n = 0;
6156
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306157 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6158 __func__, hdd_device_modetoString(pAdapter->device_mode),
6159 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006160
Gopichand Nakkalae7480202013-02-11 15:24:22 +05306161 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006162 setKey.keyId = key_index; // Store Key ID
6163 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
6164 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
6165 setKey.paeRole = 0 ; // the PAE role
6166 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
6167 {
6168 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
6169 }
6170 else
6171 {
6172 isConnected = hdd_connIsConnected(pHddStaCtx);
6173 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
6174 }
6175 setKey.keyLength = key_Len;
6176 pKeyPtr = setKey.Key;
6177 memcpy( pKeyPtr, key, key_Len);
6178
Arif Hussain6d2a3322013-11-17 19:50:10 -08006179 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07006180 __func__, key_Len);
6181 for (n = 0 ; n < key_Len; n++)
6182 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
6183 __func__,n,setKey.Key[n]);
6184
6185 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
6186 if ( isConnected )
6187 {
6188 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
6189 pAdapter->sessionId, &setKey, &roamId );
6190 }
6191 if ( status != 0 )
6192 {
6193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6194 "[%4d] sme_RoamSetKey returned ERROR status= %d",
6195 __LINE__, status );
6196 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
6197 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05306198 /* Need to clear any trace of key value in the memory.
6199 * Thus zero out the memory even though it is local
6200 * variable.
6201 */
6202 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006203}
6204#endif /* FEATURE_WLAN_WAPI*/
6205
6206#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306207int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006208 beacon_data_t **ppBeacon,
6209 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006210#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306211int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006212 beacon_data_t **ppBeacon,
6213 struct cfg80211_beacon_data *params,
6214 int dtim_period)
6215#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306216{
Jeff Johnson295189b2012-06-20 16:38:30 -07006217 int size;
6218 beacon_data_t *beacon = NULL;
6219 beacon_data_t *old = NULL;
6220 int head_len,tail_len;
6221
Jeff Johnsone7245742012-09-05 17:12:55 -07006222 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006223 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306224 {
6225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6226 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006227 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306228 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006229
6230 old = pAdapter->sessionCtx.ap.beacon;
6231
6232 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306233 {
6234 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6235 FL("session(%d) old and new heads points to NULL"),
6236 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006237 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306238 }
6239
6240 if (params->tail && !params->tail_len)
6241 {
6242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6243 FL("tail_len is zero but tail is not NULL"));
6244 return -EINVAL;
6245 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006246
Jeff Johnson295189b2012-06-20 16:38:30 -07006247#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
6248 /* Kernel 3.0 is not updating dtim_period for set beacon */
6249 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306250 {
6251 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6252 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006253 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306254 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006255#endif
6256
6257 if(params->head)
6258 head_len = params->head_len;
6259 else
6260 head_len = old->head_len;
6261
6262 if(params->tail || !old)
6263 tail_len = params->tail_len;
6264 else
6265 tail_len = old->tail_len;
6266
6267 size = sizeof(beacon_data_t) + head_len + tail_len;
6268
6269 beacon = kzalloc(size, GFP_KERNEL);
6270
6271 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306272 {
6273 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6274 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006275 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306276 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006277
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006278#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006279 if(params->dtim_period || !old )
6280 beacon->dtim_period = params->dtim_period;
6281 else
6282 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006283#else
6284 if(dtim_period || !old )
6285 beacon->dtim_period = dtim_period;
6286 else
6287 beacon->dtim_period = old->dtim_period;
6288#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306289
Jeff Johnson295189b2012-06-20 16:38:30 -07006290 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6291 beacon->tail = beacon->head + head_len;
6292 beacon->head_len = head_len;
6293 beacon->tail_len = tail_len;
6294
6295 if(params->head) {
6296 memcpy (beacon->head,params->head,beacon->head_len);
6297 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306298 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07006299 if(old)
6300 memcpy (beacon->head,old->head,beacon->head_len);
6301 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306302
Jeff Johnson295189b2012-06-20 16:38:30 -07006303 if(params->tail) {
6304 memcpy (beacon->tail,params->tail,beacon->tail_len);
6305 }
6306 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306307 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07006308 memcpy (beacon->tail,old->tail,beacon->tail_len);
6309 }
6310
6311 *ppBeacon = beacon;
6312
6313 kfree(old);
6314
6315 return 0;
6316
6317}
Jeff Johnson295189b2012-06-20 16:38:30 -07006318
6319v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
6320{
6321 int left = length;
6322 v_U8_t *ptr = pIes;
6323 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306324
Jeff Johnson295189b2012-06-20 16:38:30 -07006325 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306326 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006327 elem_id = ptr[0];
6328 elem_len = ptr[1];
6329 left -= 2;
6330 if(elem_len > left)
6331 {
6332 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006333 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006334 eid,elem_len,left);
6335 return NULL;
6336 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306337 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006338 {
6339 return ptr;
6340 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306341
Jeff Johnson295189b2012-06-20 16:38:30 -07006342 left -= elem_len;
6343 ptr += (elem_len + 2);
6344 }
6345 return NULL;
6346}
6347
Jeff Johnson295189b2012-06-20 16:38:30 -07006348/* Check if rate is 11g rate or not */
6349static int wlan_hdd_rate_is_11g(u8 rate)
6350{
Sanjay Devnani28322e22013-06-21 16:13:40 -07006351 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006352 u8 i;
6353 for (i = 0; i < 8; i++)
6354 {
6355 if(rate == gRateArray[i])
6356 return TRUE;
6357 }
6358 return FALSE;
6359}
6360
6361/* Check for 11g rate and set proper 11g only mode */
6362static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
6363 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
6364{
6365 u8 i, num_rates = pIe[0];
6366
6367 pIe += 1;
6368 for ( i = 0; i < num_rates; i++)
6369 {
6370 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
6371 {
6372 /* If rate set have 11g rate than change the mode to 11G */
6373 *pSapHw_mode = eSAP_DOT11_MODE_11g;
6374 if (pIe[i] & BASIC_RATE_MASK)
6375 {
6376 /* If we have 11g rate as basic rate, it means mode
6377 is 11g only mode.
6378 */
6379 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
6380 *pCheckRatesfor11g = FALSE;
6381 }
6382 }
6383 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6384 {
6385 *require_ht = TRUE;
6386 }
6387 }
6388 return;
6389}
6390
6391static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
6392{
6393 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6394 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6395 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6396 u8 checkRatesfor11g = TRUE;
6397 u8 require_ht = FALSE;
6398 u8 *pIe=NULL;
6399
6400 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
6401
6402 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6403 pBeacon->head_len, WLAN_EID_SUPP_RATES);
6404 if (pIe != NULL)
6405 {
6406 pIe += 1;
6407 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6408 &pConfig->SapHw_mode);
6409 }
6410
6411 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6412 WLAN_EID_EXT_SUPP_RATES);
6413 if (pIe != NULL)
6414 {
6415
6416 pIe += 1;
6417 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6418 &pConfig->SapHw_mode);
6419 }
6420
6421 if( pConfig->channel > 14 )
6422 {
6423 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
6424 }
6425
6426 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6427 WLAN_EID_HT_CAPABILITY);
6428
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306429 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006430 {
6431 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
6432 if(require_ht)
6433 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
6434 }
6435}
6436
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306437static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
6438 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
6439{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006440 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306441 v_U8_t *pIe = NULL;
6442 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6443
6444 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6445 pBeacon->tail, pBeacon->tail_len);
6446
6447 if (pIe)
6448 {
6449 ielen = pIe[1] + 2;
6450 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6451 {
6452 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
6453 }
6454 else
6455 {
6456 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
6457 return -EINVAL;
6458 }
6459 *total_ielen += ielen;
6460 }
6461 return 0;
6462}
6463
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006464static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
6465 v_U8_t *genie, v_U8_t *total_ielen)
6466{
6467 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6468 int left = pBeacon->tail_len;
6469 v_U8_t *ptr = pBeacon->tail;
6470 v_U8_t elem_id, elem_len;
6471 v_U16_t ielen = 0;
6472
6473 if ( NULL == ptr || 0 == left )
6474 return;
6475
6476 while (left >= 2)
6477 {
6478 elem_id = ptr[0];
6479 elem_len = ptr[1];
6480 left -= 2;
6481 if (elem_len > left)
6482 {
6483 hddLog( VOS_TRACE_LEVEL_ERROR,
6484 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
6485 elem_id, elem_len, left);
6486 return;
6487 }
6488 if (IE_EID_VENDOR == elem_id)
6489 {
6490 /* skipping the VSIE's which we don't want to include or
6491 * it will be included by existing code
6492 */
6493 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
6494#ifdef WLAN_FEATURE_WFD
6495 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
6496#endif
6497 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6498 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6499 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
6500 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6501 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
6502 {
6503 ielen = ptr[1] + 2;
6504 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6505 {
6506 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
6507 *total_ielen += ielen;
6508 }
6509 else
6510 {
6511 hddLog( VOS_TRACE_LEVEL_ERROR,
6512 "IE Length is too big "
6513 "IEs eid=%d elem_len=%d total_ie_lent=%d",
6514 elem_id, elem_len, *total_ielen);
6515 }
6516 }
6517 }
6518
6519 left -= elem_len;
6520 ptr += (elem_len + 2);
6521 }
6522 return;
6523}
6524
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006525#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006526static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6527 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006528#else
6529static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6530 struct cfg80211_beacon_data *params)
6531#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006532{
6533 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306534 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006535 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07006536 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006537
6538 genie = vos_mem_malloc(MAX_GENIE_LEN);
6539
6540 if(genie == NULL) {
6541
6542 return -ENOMEM;
6543 }
6544
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306545 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6546 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006547 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306548 hddLog(LOGE,
6549 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306550 ret = -EINVAL;
6551 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006552 }
6553
6554#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306555 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6556 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
6557 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306558 hddLog(LOGE,
6559 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306560 ret = -EINVAL;
6561 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006562 }
6563#endif
6564
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306565 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6566 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006567 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306568 hddLog(LOGE,
6569 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306570 ret = -EINVAL;
6571 goto done;
6572 }
6573
6574 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
6575 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006576 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07006577 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006578
6579 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6580 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
6581 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6582 {
6583 hddLog(LOGE,
6584 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006585 ret = -EINVAL;
6586 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006587 }
6588
6589 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6590 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6591 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6592 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6593 ==eHAL_STATUS_FAILURE)
6594 {
6595 hddLog(LOGE,
6596 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006597 ret = -EINVAL;
6598 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006599 }
6600
6601 // Added for ProResp IE
6602 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
6603 {
6604 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
6605 u8 probe_rsp_ie_len[3] = {0};
6606 u8 counter = 0;
6607 /* Check Probe Resp Length if it is greater then 255 then Store
6608 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
6609 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
6610 Store More then 255 bytes into One Variable.
6611 */
6612 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6613 {
6614 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6615 {
6616 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6617 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6618 }
6619 else
6620 {
6621 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6622 rem_probe_resp_ie_len = 0;
6623 }
6624 }
6625
6626 rem_probe_resp_ie_len = 0;
6627
6628 if (probe_rsp_ie_len[0] > 0)
6629 {
6630 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6631 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6632 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6633 probe_rsp_ie_len[0], NULL,
6634 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6635 {
6636 hddLog(LOGE,
6637 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006638 ret = -EINVAL;
6639 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006640 }
6641 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6642 }
6643
6644 if (probe_rsp_ie_len[1] > 0)
6645 {
6646 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6647 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6648 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6649 probe_rsp_ie_len[1], NULL,
6650 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6651 {
6652 hddLog(LOGE,
6653 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006654 ret = -EINVAL;
6655 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006656 }
6657 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6658 }
6659
6660 if (probe_rsp_ie_len[2] > 0)
6661 {
6662 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6663 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6664 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6665 probe_rsp_ie_len[2], NULL,
6666 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6667 {
6668 hddLog(LOGE,
6669 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006670 ret = -EINVAL;
6671 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006672 }
6673 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6674 }
6675
6676 if (probe_rsp_ie_len[1] == 0 )
6677 {
6678 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6679 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6680 eANI_BOOLEAN_FALSE) )
6681 {
6682 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006683 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006684 }
6685 }
6686
6687 if (probe_rsp_ie_len[2] == 0 )
6688 {
6689 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6690 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6691 eANI_BOOLEAN_FALSE) )
6692 {
6693 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006694 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006695 }
6696 }
6697
6698 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6699 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6700 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6701 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6702 == eHAL_STATUS_FAILURE)
6703 {
6704 hddLog(LOGE,
6705 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006706 ret = -EINVAL;
6707 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006708 }
6709 }
6710 else
6711 {
6712 // Reset WNI_CFG_PROBE_RSP Flags
6713 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
6714
6715 hddLog(VOS_TRACE_LEVEL_INFO,
6716 "%s: No Probe Response IE received in set beacon",
6717 __func__);
6718 }
6719
6720 // Added for AssocResp IE
6721 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
6722 {
6723 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6724 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
6725 params->assocresp_ies_len, NULL,
6726 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6727 {
6728 hddLog(LOGE,
6729 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006730 ret = -EINVAL;
6731 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006732 }
6733
6734 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6735 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
6736 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6737 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6738 == eHAL_STATUS_FAILURE)
6739 {
6740 hddLog(LOGE,
6741 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006742 ret = -EINVAL;
6743 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006744 }
6745 }
6746 else
6747 {
6748 hddLog(VOS_TRACE_LEVEL_INFO,
6749 "%s: No Assoc Response IE received in set beacon",
6750 __func__);
6751
6752 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6753 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6754 eANI_BOOLEAN_FALSE) )
6755 {
6756 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006757 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006758 }
6759 }
6760
Jeff Johnsone7245742012-09-05 17:12:55 -07006761done:
Jeff Johnson295189b2012-06-20 16:38:30 -07006762 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306763 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006764}
Jeff Johnson295189b2012-06-20 16:38:30 -07006765
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306766/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006767 * FUNCTION: wlan_hdd_validate_operation_channel
6768 * called by wlan_hdd_cfg80211_start_bss() and
6769 * wlan_hdd_cfg80211_set_channel()
6770 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306771 * channel list.
6772 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006773VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006774{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306775
Jeff Johnson295189b2012-06-20 16:38:30 -07006776 v_U32_t num_ch = 0;
6777 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6778 u32 indx = 0;
6779 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306780 v_U8_t fValidChannel = FALSE, count = 0;
6781 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306782
Jeff Johnson295189b2012-06-20 16:38:30 -07006783 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6784
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306785 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006786 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306787 /* Validate the channel */
6788 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006789 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306790 if ( channel == rfChannels[count].channelNum )
6791 {
6792 fValidChannel = TRUE;
6793 break;
6794 }
6795 }
6796 if (fValidChannel != TRUE)
6797 {
6798 hddLog(VOS_TRACE_LEVEL_ERROR,
6799 "%s: Invalid Channel [%d]", __func__, channel);
6800 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006801 }
6802 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306803 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006804 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306805 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6806 valid_ch, &num_ch))
6807 {
6808 hddLog(VOS_TRACE_LEVEL_ERROR,
6809 "%s: failed to get valid channel list", __func__);
6810 return VOS_STATUS_E_FAILURE;
6811 }
6812 for (indx = 0; indx < num_ch; indx++)
6813 {
6814 if (channel == valid_ch[indx])
6815 {
6816 break;
6817 }
6818 }
6819
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306820 if (indx >= num_ch)
6821 {
6822 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6823 {
6824 eCsrBand band;
6825 unsigned int freq;
6826
6827 sme_GetFreqBand(hHal, &band);
6828
6829 if (eCSR_BAND_5G == band)
6830 {
6831#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6832 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6833 {
6834 freq = ieee80211_channel_to_frequency(channel,
6835 IEEE80211_BAND_2GHZ);
6836 }
6837 else
6838 {
6839 freq = ieee80211_channel_to_frequency(channel,
6840 IEEE80211_BAND_5GHZ);
6841 }
6842#else
6843 freq = ieee80211_channel_to_frequency(channel);
6844#endif
6845 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6846 return VOS_STATUS_SUCCESS;
6847 }
6848 }
6849
6850 hddLog(VOS_TRACE_LEVEL_ERROR,
6851 "%s: Invalid Channel [%d]", __func__, channel);
6852 return VOS_STATUS_E_FAILURE;
6853 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006854 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306855
Jeff Johnson295189b2012-06-20 16:38:30 -07006856 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306857
Jeff Johnson295189b2012-06-20 16:38:30 -07006858}
6859
Viral Modi3a32cc52013-02-08 11:14:52 -08006860/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306861 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08006862 * This function is used to set the channel number
6863 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306864static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08006865 struct ieee80211_channel *chan,
6866 enum nl80211_channel_type channel_type
6867 )
6868{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306869 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006870 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006871 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006872 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306873 hdd_context_t *pHddCtx;
6874 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006875
6876 ENTER();
6877
6878 if( NULL == dev )
6879 {
6880 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006881 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006882 return -ENODEV;
6883 }
6884 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306885
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306886 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6887 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6888 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006889 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306890 "%s: device_mode = %s (%d) freq = %d", __func__,
6891 hdd_device_modetoString(pAdapter->device_mode),
6892 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306893
6894 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6895 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306896 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006897 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306898 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006899 }
6900
6901 /*
6902 * Do freq to chan conversion
6903 * TODO: for 11a
6904 */
6905
6906 channel = ieee80211_frequency_to_channel(freq);
6907
6908 /* Check freq range */
6909 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6910 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6911 {
6912 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006913 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006914 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6915 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6916 return -EINVAL;
6917 }
6918
6919 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6920
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306921 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6922 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006923 {
6924 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6925 {
6926 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006927 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006928 return -EINVAL;
6929 }
6930 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6931 "%s: set channel to [%d] for device mode =%d",
6932 __func__, channel,pAdapter->device_mode);
6933 }
6934 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006935 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006936 )
6937 {
6938 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6939 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6940 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6941
6942 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6943 {
6944 /* Link is up then return cant set channel*/
6945 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006946 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006947 return -EINVAL;
6948 }
6949
6950 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6951 pHddStaCtx->conn_info.operationChannel = channel;
6952 pRoamProfile->ChannelInfo.ChannelList =
6953 &pHddStaCtx->conn_info.operationChannel;
6954 }
6955 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006956 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006957 )
6958 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306959 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6960 {
6961 if(VOS_STATUS_SUCCESS !=
6962 wlan_hdd_validate_operation_channel(pAdapter,channel))
6963 {
6964 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006965 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306966 return -EINVAL;
6967 }
6968 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6969 }
6970 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006971 {
6972 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6973
6974 /* If auto channel selection is configured as enable/ 1 then ignore
6975 channel set by supplicant
6976 */
6977 if ( cfg_param->apAutoChannelSelection )
6978 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306979 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6980 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006981 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306982 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6983 __func__, hdd_device_modetoString(pAdapter->device_mode),
6984 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006985 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306986 else
6987 {
6988 if(VOS_STATUS_SUCCESS !=
6989 wlan_hdd_validate_operation_channel(pAdapter,channel))
6990 {
6991 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006992 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306993 return -EINVAL;
6994 }
6995 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6996 }
Viral Modi3a32cc52013-02-08 11:14:52 -08006997 }
6998 }
6999 else
7000 {
7001 hddLog(VOS_TRACE_LEVEL_FATAL,
7002 "%s: Invalid device mode failed to set valid channel", __func__);
7003 return -EINVAL;
7004 }
7005 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307006 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007007}
7008
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307009static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
7010 struct net_device *dev,
7011 struct ieee80211_channel *chan,
7012 enum nl80211_channel_type channel_type
7013 )
7014{
7015 int ret;
7016
7017 vos_ssr_protect(__func__);
7018 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
7019 vos_ssr_unprotect(__func__);
7020
7021 return ret;
7022}
7023
Jeff Johnson295189b2012-06-20 16:38:30 -07007024#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7025static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7026 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007027#else
7028static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7029 struct cfg80211_beacon_data *params,
7030 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307031 enum nl80211_hidden_ssid hidden_ssid,
7032 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007033#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007034{
7035 tsap_Config_t *pConfig;
7036 beacon_data_t *pBeacon = NULL;
7037 struct ieee80211_mgmt *pMgmt_frame;
7038 v_U8_t *pIe=NULL;
7039 v_U16_t capab_info;
7040 eCsrAuthType RSNAuthType;
7041 eCsrEncryptionType RSNEncryptType;
7042 eCsrEncryptionType mcRSNEncryptType;
7043 int status = VOS_STATUS_SUCCESS;
7044 tpWLAN_SAPEventCB pSapEventCallback;
7045 hdd_hostapd_state_t *pHostapdState;
7046 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
7047 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307048 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007049 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307050 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07007051 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08007052 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05307053 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07007054 v_BOOL_t MFPCapable = VOS_FALSE;
7055 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307056 v_BOOL_t sapEnable11AC =
7057 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07007058 ENTER();
7059
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307060 iniConfig = pHddCtx->cfg_ini;
7061
Jeff Johnson295189b2012-06-20 16:38:30 -07007062 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7063
7064 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7065
7066 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7067
7068 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7069
7070 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7071
7072 //channel is already set in the set_channel Call back
7073 //pConfig->channel = pCommitConfig->channel;
7074
7075 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307076 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07007077 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
7078
7079 pConfig->dtim_period = pBeacon->dtim_period;
7080
Arif Hussain6d2a3322013-11-17 19:50:10 -08007081 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07007082 pConfig->dtim_period);
7083
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08007084 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07007085 {
7086 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007087 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05307088 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
7089 {
7090 tANI_BOOLEAN restartNeeded;
7091 pConfig->ieee80211d = 1;
7092 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
7093 sme_setRegInfo(hHal, pConfig->countryCode);
7094 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
7095 }
7096 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007097 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07007098 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07007099 pConfig->ieee80211d = 1;
7100 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
7101 sme_setRegInfo(hHal, pConfig->countryCode);
7102 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07007103 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007104 else
7105 {
7106 pConfig->ieee80211d = 0;
7107 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307108 /*
7109 * If auto channel is configured i.e. channel is 0,
7110 * so skip channel validation.
7111 */
7112 if( AUTO_CHANNEL_SELECT != pConfig->channel )
7113 {
7114 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
7115 {
7116 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007117 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307118 return -EINVAL;
7119 }
7120 }
7121 else
7122 {
7123 if(1 != pHddCtx->is_dynamic_channel_range_set)
7124 {
7125 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
7126 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
7127 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
7128 }
7129 pHddCtx->is_dynamic_channel_range_set = 0;
7130 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007131 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007132 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007133 {
7134 pConfig->ieee80211d = 0;
7135 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307136
7137#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7138 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7139 pConfig->authType = eSAP_OPEN_SYSTEM;
7140 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7141 pConfig->authType = eSAP_SHARED_KEY;
7142 else
7143 pConfig->authType = eSAP_AUTO_SWITCH;
7144#else
7145 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7146 pConfig->authType = eSAP_OPEN_SYSTEM;
7147 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7148 pConfig->authType = eSAP_SHARED_KEY;
7149 else
7150 pConfig->authType = eSAP_AUTO_SWITCH;
7151#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007152
7153 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307154
7155 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07007156 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
7157
7158 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7159
7160 /*Set wps station to configured*/
7161 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7162
7163 if(pIe)
7164 {
7165 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
7166 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007167 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07007168 return -EINVAL;
7169 }
7170 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
7171 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007172 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07007173 /* Check 15 bit of WPS IE as it contain information for wps state
7174 * WPS state
7175 */
7176 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
7177 {
7178 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
7179 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
7180 {
7181 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7182 }
7183 }
7184 }
7185 else
7186 {
7187 pConfig->wps_state = SAP_WPS_DISABLED;
7188 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307189 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07007190
c_hpothufe599e92014-06-16 11:38:55 +05307191 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7192 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7193 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7194 eCSR_ENCRYPT_TYPE_NONE;
7195
Jeff Johnson295189b2012-06-20 16:38:30 -07007196 pConfig->RSNWPAReqIELength = 0;
7197 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307198 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007199 WLAN_EID_RSN);
7200 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307201 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007202 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7203 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7204 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307205 /* The actual processing may eventually be more extensive than
7206 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07007207 * by the app.
7208 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307209 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007210 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7211 &RSNEncryptType,
7212 &mcRSNEncryptType,
7213 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007214 &MFPCapable,
7215 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007216 pConfig->pRSNWPAReqIE[1]+2,
7217 pConfig->pRSNWPAReqIE );
7218
7219 if( VOS_STATUS_SUCCESS == status )
7220 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307221 /* Now copy over all the security attributes you have
7222 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007223 * */
7224 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7225 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7226 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7227 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307228 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007229 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007230 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7231 }
7232 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307233
Jeff Johnson295189b2012-06-20 16:38:30 -07007234 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7235 pBeacon->tail, pBeacon->tail_len);
7236
7237 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
7238 {
7239 if (pConfig->pRSNWPAReqIE)
7240 {
7241 /*Mixed mode WPA/WPA2*/
7242 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
7243 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7244 }
7245 else
7246 {
7247 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7248 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7249 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307250 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007251 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7252 &RSNEncryptType,
7253 &mcRSNEncryptType,
7254 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007255 &MFPCapable,
7256 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007257 pConfig->pRSNWPAReqIE[1]+2,
7258 pConfig->pRSNWPAReqIE );
7259
7260 if( VOS_STATUS_SUCCESS == status )
7261 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307262 /* Now copy over all the security attributes you have
7263 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007264 * */
7265 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7266 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7267 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7268 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307269 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007270 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007271 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7272 }
7273 }
7274 }
7275
Jeff Johnson4416a782013-03-25 14:17:50 -07007276 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
7277 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
7278 return -EINVAL;
7279 }
7280
Jeff Johnson295189b2012-06-20 16:38:30 -07007281 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
7282
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007283#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007284 if (params->ssid != NULL)
7285 {
7286 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
7287 pConfig->SSIDinfo.ssid.length = params->ssid_len;
7288 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7289 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7290 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007291#else
7292 if (ssid != NULL)
7293 {
7294 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
7295 pConfig->SSIDinfo.ssid.length = ssid_len;
7296 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7297 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7298 }
7299#endif
7300
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307301 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07007302 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307303
Jeff Johnson295189b2012-06-20 16:38:30 -07007304 /* default value */
7305 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7306 pConfig->num_accept_mac = 0;
7307 pConfig->num_deny_mac = 0;
7308
7309 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7310 pBeacon->tail, pBeacon->tail_len);
7311
7312 /* pIe for black list is following form:
7313 type : 1 byte
7314 length : 1 byte
7315 OUI : 4 bytes
7316 acl type : 1 byte
7317 no of mac addr in black list: 1 byte
7318 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307319 */
7320 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007321 {
7322 pConfig->SapMacaddr_acl = pIe[6];
7323 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007324 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007325 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307326 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7327 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007328 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7329 for (i = 0; i < pConfig->num_deny_mac; i++)
7330 {
7331 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7332 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307333 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007334 }
7335 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7336 pBeacon->tail, pBeacon->tail_len);
7337
7338 /* pIe for white list is following form:
7339 type : 1 byte
7340 length : 1 byte
7341 OUI : 4 bytes
7342 acl type : 1 byte
7343 no of mac addr in white list: 1 byte
7344 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307345 */
7346 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007347 {
7348 pConfig->SapMacaddr_acl = pIe[6];
7349 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007350 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007351 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307352 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7353 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007354 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7355 for (i = 0; i < pConfig->num_accept_mac; i++)
7356 {
7357 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7358 acl_entry++;
7359 }
7360 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307361
Jeff Johnson295189b2012-06-20 16:38:30 -07007362 wlan_hdd_set_sapHwmode(pHostapdAdapter);
7363
Jeff Johnsone7245742012-09-05 17:12:55 -07007364#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007365 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307366 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
7367 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05307368 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
7369 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007370 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
7371 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307372 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
7373 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07007374 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307375 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07007376 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307377 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007378
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307379 /* If ACS disable and selected channel <= 14
7380 * OR
7381 * ACS enabled and ACS operating band is choosen as 2.4
7382 * AND
7383 * VHT in 2.4G Disabled
7384 * THEN
7385 * Fallback to 11N mode
7386 */
7387 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
7388 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05307389 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307390 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007391 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307392 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
7393 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007394 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
7395 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007396 }
7397#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307398
Jeff Johnson295189b2012-06-20 16:38:30 -07007399 // ht_capab is not what the name conveys,this is used for protection bitmap
7400 pConfig->ht_capab =
7401 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
7402
7403 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
7404 {
7405 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7406 return -EINVAL;
7407 }
7408
7409 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307410 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07007411 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
7412 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307413 pConfig->obssProtEnabled =
7414 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07007415
Chet Lanctot8cecea22014-02-11 19:09:36 -08007416#ifdef WLAN_FEATURE_11W
7417 pConfig->mfpCapable = MFPCapable;
7418 pConfig->mfpRequired = MFPRequired;
7419 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
7420 pConfig->mfpCapable, pConfig->mfpRequired);
7421#endif
7422
Arif Hussain6d2a3322013-11-17 19:50:10 -08007423 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07007424 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007425 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
7426 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7427 (int)pConfig->channel);
7428 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
7429 pConfig->SapHw_mode, pConfig->privacy,
7430 pConfig->authType);
7431 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
7432 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7433 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7434 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07007435
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307436 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007437 {
7438 //Bss already started. just return.
7439 //TODO Probably it should update some beacon params.
7440 hddLog( LOGE, "Bss Already started...Ignore the request");
7441 EXIT();
7442 return 0;
7443 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307444
Agarwal Ashish51325b52014-06-16 16:50:49 +05307445 if (vos_max_concurrent_connections_reached()) {
7446 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7447 return -EINVAL;
7448 }
7449
Jeff Johnson295189b2012-06-20 16:38:30 -07007450 pConfig->persona = pHostapdAdapter->device_mode;
7451
Peng Xu2446a892014-09-05 17:21:18 +05307452 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
7453 if ( NULL != psmeConfig)
7454 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307455 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05307456 sme_GetConfigParam(hHal, psmeConfig);
7457 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307458#ifdef WLAN_FEATURE_AP_HT40_24G
7459 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7460 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
7461 && pHddCtx->cfg_ini->apHT40_24GEnabled)
7462 {
7463 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
7464 sme_UpdateConfig (hHal, psmeConfig);
7465 }
7466#endif
Peng Xu2446a892014-09-05 17:21:18 +05307467 vos_mem_free(psmeConfig);
7468 }
Peng Xuafc34e32014-09-25 13:23:55 +05307469 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05307470
Jeff Johnson295189b2012-06-20 16:38:30 -07007471 pSapEventCallback = hdd_hostapd_SAPEventCB;
7472 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
7473 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
7474 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007475 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007476 return -EINVAL;
7477 }
7478
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307479 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07007480 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7481
7482 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307483
Jeff Johnson295189b2012-06-20 16:38:30 -07007484 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307485 {
7486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007487 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07007488 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07007489 VOS_ASSERT(0);
7490 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307491
Jeff Johnson295189b2012-06-20 16:38:30 -07007492 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05307493 /* Initialize WMM configuation */
7494 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307495 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007496
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007497#ifdef WLAN_FEATURE_P2P_DEBUG
7498 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
7499 {
7500 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
7501 {
7502 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7503 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007504 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007505 }
7506 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
7507 {
7508 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7509 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007510 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007511 }
7512 }
7513#endif
7514
Jeff Johnson295189b2012-06-20 16:38:30 -07007515 pHostapdState->bCommit = TRUE;
7516 EXIT();
7517
7518 return 0;
7519}
7520
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007521#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307522static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307523 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007524 struct beacon_parameters *params)
7525{
7526 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307527 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307528 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007529
7530 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307531
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307532 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7533 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
7534 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307535 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
7536 hdd_device_modetoString(pAdapter->device_mode),
7537 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007538
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307539 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7540 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307541 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007542 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307543 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007544 }
7545
Agarwal Ashish51325b52014-06-16 16:50:49 +05307546 if (vos_max_concurrent_connections_reached()) {
7547 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7548 return -EINVAL;
7549 }
7550
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307551 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007552 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007553 )
7554 {
7555 beacon_data_t *old,*new;
7556
7557 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307558
Jeff Johnson295189b2012-06-20 16:38:30 -07007559 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307560 {
7561 hddLog(VOS_TRACE_LEVEL_WARN,
7562 FL("already beacon info added to session(%d)"),
7563 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007564 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307565 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007566
7567 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7568
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307569 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07007570 {
7571 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007572 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007573 return -EINVAL;
7574 }
7575
7576 pAdapter->sessionCtx.ap.beacon = new;
7577
7578 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7579 }
7580
7581 EXIT();
7582 return status;
7583}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307584
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307585static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
7586 struct net_device *dev,
7587 struct beacon_parameters *params)
7588{
7589 int ret;
7590
7591 vos_ssr_protect(__func__);
7592 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
7593 vos_ssr_unprotect(__func__);
7594
7595 return ret;
7596}
7597
7598static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007599 struct net_device *dev,
7600 struct beacon_parameters *params)
7601{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307602 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307603 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7604 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307605 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007606
7607 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307608
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307609 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7610 TRACE_CODE_HDD_CFG80211_SET_BEACON,
7611 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
7612 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7613 __func__, hdd_device_modetoString(pAdapter->device_mode),
7614 pAdapter->device_mode);
7615
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307616 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7617 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307618 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007619 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307620 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007621 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307622
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307623 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007624 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307625 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007626 {
7627 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307628
Jeff Johnson295189b2012-06-20 16:38:30 -07007629 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307630
Jeff Johnson295189b2012-06-20 16:38:30 -07007631 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307632 {
7633 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7634 FL("session(%d) old and new heads points to NULL"),
7635 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007636 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307637 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007638
7639 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7640
7641 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307642 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007643 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007644 return -EINVAL;
7645 }
7646
7647 pAdapter->sessionCtx.ap.beacon = new;
7648
7649 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7650 }
7651
7652 EXIT();
7653 return status;
7654}
7655
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307656static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
7657 struct net_device *dev,
7658 struct beacon_parameters *params)
7659{
7660 int ret;
7661
7662 vos_ssr_protect(__func__);
7663 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
7664 vos_ssr_unprotect(__func__);
7665
7666 return ret;
7667}
7668
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007669#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7670
7671#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307672static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007673 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007674#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307675static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007676 struct net_device *dev)
7677#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007678{
7679 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07007680 hdd_context_t *pHddCtx = NULL;
7681 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307682 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307683 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007684
7685 ENTER();
7686
7687 if (NULL == pAdapter)
7688 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307689 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007690 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007691 return -ENODEV;
7692 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007693
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307694 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7695 TRACE_CODE_HDD_CFG80211_STOP_AP,
7696 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307697 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7698 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307699 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007700 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307701 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07007702 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007703
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007704 pScanInfo = &pHddCtx->scan_info;
7705
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307706 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7707 __func__, hdd_device_modetoString(pAdapter->device_mode),
7708 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007709
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307710 ret = wlan_hdd_scan_abort(pAdapter);
7711
Girish Gowli4bf7a632014-06-12 13:42:11 +05307712 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07007713 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7715 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307716
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307717 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07007718 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307719 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7720 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08007721
Jeff Johnsone7245742012-09-05 17:12:55 -07007722 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307723 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07007724 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307725 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07007726 }
7727
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05307728 /* Delete all associated STAs before stopping AP/P2P GO */
7729 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05307730 hdd_hostapd_stop(dev);
7731
Jeff Johnson295189b2012-06-20 16:38:30 -07007732 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007733 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007734 )
7735 {
7736 beacon_data_t *old;
7737
7738 old = pAdapter->sessionCtx.ap.beacon;
7739
7740 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307741 {
7742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7743 FL("session(%d) beacon data points to NULL"),
7744 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007745 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307746 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007747
Jeff Johnson295189b2012-06-20 16:38:30 -07007748 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007749
7750 mutex_lock(&pHddCtx->sap_lock);
7751 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7752 {
Jeff Johnson4416a782013-03-25 14:17:50 -07007753 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007754 {
7755 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7756
7757 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7758
7759 if (!VOS_IS_STATUS_SUCCESS(status))
7760 {
7761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007762 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007763 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307764 }
7765 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007766 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307767 /* BSS stopped, clear the active sessions for this device mode */
7768 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007769 }
7770 mutex_unlock(&pHddCtx->sap_lock);
7771
7772 if(status != VOS_STATUS_SUCCESS)
7773 {
7774 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007775 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007776 return -EINVAL;
7777 }
7778
Jeff Johnson4416a782013-03-25 14:17:50 -07007779 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007780 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
7781 ==eHAL_STATUS_FAILURE)
7782 {
7783 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007784 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007785 }
7786
Jeff Johnson4416a782013-03-25 14:17:50 -07007787 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007788 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7789 eANI_BOOLEAN_FALSE) )
7790 {
7791 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007792 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007793 }
7794
7795 // Reset WNI_CFG_PROBE_RSP Flags
7796 wlan_hdd_reset_prob_rspies(pAdapter);
7797
7798 pAdapter->sessionCtx.ap.beacon = NULL;
7799 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007800#ifdef WLAN_FEATURE_P2P_DEBUG
7801 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7802 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
7803 {
7804 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
7805 "GO got removed");
7806 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
7807 }
7808#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007809 }
7810 EXIT();
7811 return status;
7812}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007813
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307814#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7815static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
7816 struct net_device *dev)
7817{
7818 int ret;
7819
7820 vos_ssr_protect(__func__);
7821 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
7822 vos_ssr_unprotect(__func__);
7823
7824 return ret;
7825}
7826#else
7827static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7828 struct net_device *dev)
7829{
7830 int ret;
7831
7832 vos_ssr_protect(__func__);
7833 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7834 vos_ssr_unprotect(__func__);
7835
7836 return ret;
7837}
7838#endif
7839
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007840#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7841
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307842static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307843 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007844 struct cfg80211_ap_settings *params)
7845{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307846 hdd_adapter_t *pAdapter;
7847 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307848 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007849
7850 ENTER();
7851
Girish Gowlib143d7a2015-02-18 19:39:55 +05307852 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007853 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05307855 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307856 return -ENODEV;
7857 }
7858
7859 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7860 if (NULL == pAdapter)
7861 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307862 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307863 "%s: HDD adapter is Null", __func__);
7864 return -ENODEV;
7865 }
7866
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307867 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7868 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
7869 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307870 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7871 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307873 "%s: HDD adapter magic is invalid", __func__);
7874 return -ENODEV;
7875 }
7876
7877 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307878 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307879 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307880 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307881 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307882 }
7883
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307884 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7885 __func__, hdd_device_modetoString(pAdapter->device_mode),
7886 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307887
7888 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007889 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007890 )
7891 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307892 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007893
7894 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307895
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007896 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307897 {
7898 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7899 FL("already beacon info added to session(%d)"),
7900 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007901 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307902 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007903
Girish Gowlib143d7a2015-02-18 19:39:55 +05307904#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7905 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7906 &new,
7907 &params->beacon);
7908#else
7909 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7910 &new,
7911 &params->beacon,
7912 params->dtim_period);
7913#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007914
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307915 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007916 {
7917 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307918 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007919 return -EINVAL;
7920 }
7921 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007922#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007923 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7924#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7925 params->channel, params->channel_type);
7926#else
7927 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7928#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007929#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007930 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307931 params->ssid_len, params->hidden_ssid,
7932 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007933 }
7934
7935 EXIT();
7936 return status;
7937}
7938
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307939static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7940 struct net_device *dev,
7941 struct cfg80211_ap_settings *params)
7942{
7943 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007944
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307945 vos_ssr_protect(__func__);
7946 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
7947 vos_ssr_unprotect(__func__);
7948
7949 return ret;
7950}
7951
7952static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007953 struct net_device *dev,
7954 struct cfg80211_beacon_data *params)
7955{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307956 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307957 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307958 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007959
7960 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307961
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307962 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7963 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7964 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007965 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007966 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307967
7968 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7969 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307970 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007971 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307972 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007973 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007974
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307975 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007976 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307977 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007978 {
7979 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307980
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007981 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307982
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007983 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307984 {
7985 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7986 FL("session(%d) beacon data points to NULL"),
7987 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007988 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307989 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007990
7991 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
7992
7993 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307994 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007995 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007996 return -EINVAL;
7997 }
7998
7999 pAdapter->sessionCtx.ap.beacon = new;
8000
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308001 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
8002 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008003 }
8004
8005 EXIT();
8006 return status;
8007}
8008
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308009static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8010 struct net_device *dev,
8011 struct cfg80211_beacon_data *params)
8012{
8013 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008014
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308015 vos_ssr_protect(__func__);
8016 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8017 vos_ssr_unprotect(__func__);
8018
8019 return ret;
8020}
8021
8022#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008023
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308024static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008025 struct net_device *dev,
8026 struct bss_parameters *params)
8027{
8028 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308029 hdd_context_t *pHddCtx;
8030 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008031
8032 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308033
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308034 if (NULL == pAdapter)
8035 {
8036 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8037 "%s: HDD adapter is Null", __func__);
8038 return -ENODEV;
8039 }
8040 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308041 ret = wlan_hdd_validate_context(pHddCtx);
8042 if (0 != ret)
8043 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308044 return ret;
8045 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308046 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8047 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
8048 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308049 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8050 __func__, hdd_device_modetoString(pAdapter->device_mode),
8051 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008052
8053 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008054 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308055 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008056 {
8057 /* ap_isolate == -1 means that in change bss, upper layer doesn't
8058 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308059 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07008060 {
8061 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308062 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008063 }
8064
8065 EXIT();
8066 return 0;
8067}
8068
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308069static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
8070 struct net_device *dev,
8071 struct bss_parameters *params)
8072{
8073 int ret;
8074
8075 vos_ssr_protect(__func__);
8076 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
8077 vos_ssr_unprotect(__func__);
8078
8079 return ret;
8080}
Kiet Lam10841362013-11-01 11:36:50 +05308081/* FUNCTION: wlan_hdd_change_country_code_cd
8082* to wait for contry code completion
8083*/
8084void* wlan_hdd_change_country_code_cb(void *pAdapter)
8085{
8086 hdd_adapter_t *call_back_pAdapter = pAdapter;
8087 complete(&call_back_pAdapter->change_country_code);
8088 return NULL;
8089}
8090
Jeff Johnson295189b2012-06-20 16:38:30 -07008091/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308092 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07008093 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
8094 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308095int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008096 struct net_device *ndev,
8097 enum nl80211_iftype type,
8098 u32 *flags,
8099 struct vif_params *params
8100 )
8101{
8102 struct wireless_dev *wdev;
8103 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008104 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07008105 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008106 tCsrRoamProfile *pRoamProfile = NULL;
8107 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308108 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008109 eMib_dot11DesiredBssType connectedBssType;
8110 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308111 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008112
8113 ENTER();
8114
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308115 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008116 {
8117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8118 "%s: Adapter context is null", __func__);
8119 return VOS_STATUS_E_FAILURE;
8120 }
8121
8122 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8123 if (!pHddCtx)
8124 {
8125 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8126 "%s: HDD context is null", __func__);
8127 return VOS_STATUS_E_FAILURE;
8128 }
8129
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308130 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8131 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
8132 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308133 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308134 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07008135 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308136 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008137 }
8138
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308139 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8140 __func__, hdd_device_modetoString(pAdapter->device_mode),
8141 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008142
Agarwal Ashish51325b52014-06-16 16:50:49 +05308143 if (vos_max_concurrent_connections_reached()) {
8144 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8145 return -EINVAL;
8146 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308147 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07008148 wdev = ndev->ieee80211_ptr;
8149
8150#ifdef WLAN_BTAMP_FEATURE
8151 if((NL80211_IFTYPE_P2P_CLIENT == type)||
8152 (NL80211_IFTYPE_ADHOC == type)||
8153 (NL80211_IFTYPE_AP == type)||
8154 (NL80211_IFTYPE_P2P_GO == type))
8155 {
8156 pHddCtx->isAmpAllowed = VOS_FALSE;
8157 // stop AMP traffic
8158 status = WLANBAP_StopAmp();
8159 if(VOS_STATUS_SUCCESS != status )
8160 {
8161 pHddCtx->isAmpAllowed = VOS_TRUE;
8162 hddLog(VOS_TRACE_LEVEL_FATAL,
8163 "%s: Failed to stop AMP", __func__);
8164 return -EINVAL;
8165 }
8166 }
8167#endif //WLAN_BTAMP_FEATURE
8168 /* Reset the current device mode bit mask*/
8169 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8170
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +05308171 /* Notify Mode change in case of concurrency.
8172 * Below function invokes TDLS teardown Functionality Since TDLS is
8173 * not Supported in case of concurrency i.e Once P2P session
8174 * is detected disable offchannel and teardown TDLS links
8175 */
8176 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
8177
Jeff Johnson295189b2012-06-20 16:38:30 -07008178 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008179 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07008180 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008181 )
8182 {
8183 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008184 if (!pWextState)
8185 {
8186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8187 "%s: pWextState is null", __func__);
8188 return VOS_STATUS_E_FAILURE;
8189 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008190 pRoamProfile = &pWextState->roamProfile;
8191 LastBSSType = pRoamProfile->BSSType;
8192
8193 switch (type)
8194 {
8195 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008196 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008197 hddLog(VOS_TRACE_LEVEL_INFO,
8198 "%s: setting interface Type to INFRASTRUCTURE", __func__);
8199 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008200#ifdef WLAN_FEATURE_11AC
8201 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
8202 {
8203 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
8204 }
8205#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308206 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07008207 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008208 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008209 //Check for sub-string p2p to confirm its a p2p interface
8210 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308211 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008212 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8213 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8214 }
8215 else
8216 {
8217 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008218 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008219 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008220 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05308221
Jeff Johnson295189b2012-06-20 16:38:30 -07008222 case NL80211_IFTYPE_ADHOC:
8223 hddLog(VOS_TRACE_LEVEL_INFO,
8224 "%s: setting interface Type to ADHOC", __func__);
8225 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
8226 pRoamProfile->phyMode =
8227 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07008228 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008229 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05308230 hdd_set_ibss_ops( pAdapter );
8231 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +05308232
8233 status = hdd_sta_id_hash_attach(pAdapter);
8234 if (VOS_STATUS_SUCCESS != status) {
8235 hddLog(VOS_TRACE_LEVEL_ERROR,
8236 FL("Failed to initialize hash for IBSS"));
8237 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008238 break;
8239
8240 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008241 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008242 {
8243 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8244 "%s: setting interface Type to %s", __func__,
8245 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
8246
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008247 //Cancel any remain on channel for GO mode
8248 if (NL80211_IFTYPE_P2P_GO == type)
8249 {
8250 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
8251 }
Mohit Khanna0f232092012-09-11 14:46:08 -07008252 if (NL80211_IFTYPE_AP == type)
8253 {
8254 /* As Loading WLAN Driver one interface being created for p2p device
8255 * address. This will take one HW STA and the max number of clients
8256 * that can connect to softAP will be reduced by one. so while changing
8257 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
8258 * interface as it is not required in SoftAP mode.
8259 */
8260
8261 // Get P2P Adapter
8262 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
8263
8264 if (pP2pAdapter)
8265 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308266 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05308267 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07008268 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
8269 }
8270 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05308271 //Disable IMPS & BMPS for SAP/GO
8272 if(VOS_STATUS_E_FAILURE ==
8273 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
8274 {
8275 //Fail to Exit BMPS
8276 VOS_ASSERT(0);
8277 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05308278
8279 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
8280
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308281#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07008282
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308283 /* A Mutex Lock is introduced while changing the mode to
8284 * protect the concurrent access for the Adapters by TDLS
8285 * module.
8286 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308287 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308288#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008289 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05308290 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008291 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07008292 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8293 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308294#ifdef FEATURE_WLAN_TDLS
8295 mutex_unlock(&pHddCtx->tdls_lock);
8296#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008297 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
8298 (pConfig->apRandomBssidEnabled))
8299 {
8300 /* To meet Android requirements create a randomized
8301 MAC address of the form 02:1A:11:Fx:xx:xx */
8302 get_random_bytes(&ndev->dev_addr[3], 3);
8303 ndev->dev_addr[0] = 0x02;
8304 ndev->dev_addr[1] = 0x1A;
8305 ndev->dev_addr[2] = 0x11;
8306 ndev->dev_addr[3] |= 0xF0;
8307 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
8308 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08008309 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
8310 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008311 }
8312
Jeff Johnson295189b2012-06-20 16:38:30 -07008313 hdd_set_ap_ops( pAdapter->dev );
8314
Kiet Lam10841362013-11-01 11:36:50 +05308315 /* This is for only SAP mode where users can
8316 * control country through ini.
8317 * P2P GO follows station country code
8318 * acquired during the STA scanning. */
8319 if((NL80211_IFTYPE_AP == type) &&
8320 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
8321 {
8322 int status = 0;
8323 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
8324 "%s: setting country code from INI ", __func__);
8325 init_completion(&pAdapter->change_country_code);
8326 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
8327 (void *)(tSmeChangeCountryCallback)
8328 wlan_hdd_change_country_code_cb,
8329 pConfig->apCntryCode, pAdapter,
8330 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308331 eSIR_FALSE,
8332 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05308333 if (eHAL_STATUS_SUCCESS == status)
8334 {
8335 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308336 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05308337 &pAdapter->change_country_code,
8338 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308339 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05308340 {
8341 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308342 FL("SME Timed out while setting country code %ld"),
8343 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08008344
8345 if (pHddCtx->isLogpInProgress)
8346 {
8347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8348 "%s: LOGP in Progress. Ignore!!!", __func__);
8349 return -EAGAIN;
8350 }
Kiet Lam10841362013-11-01 11:36:50 +05308351 }
8352 }
8353 else
8354 {
8355 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008356 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05308357 return -EINVAL;
8358 }
8359 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008360 status = hdd_init_ap_mode(pAdapter);
8361 if(status != VOS_STATUS_SUCCESS)
8362 {
8363 hddLog(VOS_TRACE_LEVEL_FATAL,
8364 "%s: Error initializing the ap mode", __func__);
8365 return -EINVAL;
8366 }
8367 hdd_set_conparam(1);
8368
Nirav Shah7e3c8132015-06-22 23:51:42 +05308369 status = hdd_sta_id_hash_attach(pAdapter);
8370 if (VOS_STATUS_SUCCESS != status)
8371 {
8372 hddLog(VOS_TRACE_LEVEL_ERROR,
8373 FL("Failed to initialize hash for AP"));
8374 return -EINVAL;
8375 }
8376
Jeff Johnson295189b2012-06-20 16:38:30 -07008377 /*interface type changed update in wiphy structure*/
8378 if(wdev)
8379 {
8380 wdev->iftype = type;
8381 pHddCtx->change_iface = type;
8382 }
8383 else
8384 {
8385 hddLog(VOS_TRACE_LEVEL_ERROR,
8386 "%s: ERROR !!!! Wireless dev is NULL", __func__);
8387 return -EINVAL;
8388 }
8389 goto done;
8390 }
8391
8392 default:
8393 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8394 __func__);
8395 return -EOPNOTSUPP;
8396 }
8397 }
8398 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008399 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008400 )
8401 {
8402 switch(type)
8403 {
8404 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008405 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008406 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05308407
8408 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308409#ifdef FEATURE_WLAN_TDLS
8410
8411 /* A Mutex Lock is introduced while changing the mode to
8412 * protect the concurrent access for the Adapters by TDLS
8413 * module.
8414 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308415 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308416#endif
c_hpothu002231a2015-02-05 14:58:51 +05308417 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008418 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008419 //Check for sub-string p2p to confirm its a p2p interface
8420 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008421 {
8422 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8423 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8424 }
8425 else
8426 {
8427 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008428 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008429 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008430 hdd_set_conparam(0);
8431 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008432 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
8433 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308434#ifdef FEATURE_WLAN_TDLS
8435 mutex_unlock(&pHddCtx->tdls_lock);
8436#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308437 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008438 if( VOS_STATUS_SUCCESS != status )
8439 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07008440 /* In case of JB, for P2P-GO, only change interface will be called,
8441 * This is the right place to enable back bmps_imps()
8442 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308443 if (pHddCtx->hdd_wlan_suspended)
8444 {
8445 hdd_set_pwrparams(pHddCtx);
8446 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008447 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008448 goto done;
8449 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008450 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008451 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008452 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8453 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008454 goto done;
8455 default:
8456 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8457 __func__);
8458 return -EOPNOTSUPP;
8459
8460 }
8461
8462 }
8463 else
8464 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308465 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
8466 __func__, hdd_device_modetoString(pAdapter->device_mode),
8467 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008468 return -EOPNOTSUPP;
8469 }
8470
8471
8472 if(pRoamProfile)
8473 {
8474 if ( LastBSSType != pRoamProfile->BSSType )
8475 {
8476 /*interface type changed update in wiphy structure*/
8477 wdev->iftype = type;
8478
8479 /*the BSS mode changed, We need to issue disconnect
8480 if connected or in IBSS disconnect state*/
8481 if ( hdd_connGetConnectedBssType(
8482 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
8483 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
8484 {
8485 /*need to issue a disconnect to CSR.*/
8486 INIT_COMPLETION(pAdapter->disconnect_comp_var);
8487 if( eHAL_STATUS_SUCCESS ==
8488 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
8489 pAdapter->sessionId,
8490 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
8491 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308492 ret = wait_for_completion_interruptible_timeout(
8493 &pAdapter->disconnect_comp_var,
8494 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
8495 if (ret <= 0)
8496 {
8497 hddLog(VOS_TRACE_LEVEL_ERROR,
8498 FL("wait on disconnect_comp_var failed %ld"), ret);
8499 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008500 }
8501 }
8502 }
8503 }
8504
8505done:
8506 /*set bitmask based on updated value*/
8507 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07008508
8509 /* Only STA mode support TM now
8510 * all other mode, TM feature should be disabled */
8511 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
8512 (~VOS_STA & pHddCtx->concurrency_mode) )
8513 {
8514 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
8515 }
8516
Jeff Johnson295189b2012-06-20 16:38:30 -07008517#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308518 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05308519 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07008520 {
8521 //we are ok to do AMP
8522 pHddCtx->isAmpAllowed = VOS_TRUE;
8523 }
8524#endif //WLAN_BTAMP_FEATURE
8525 EXIT();
8526 return 0;
8527}
8528
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308529/*
8530 * FUNCTION: wlan_hdd_cfg80211_change_iface
8531 * wrapper function to protect the actual implementation from SSR.
8532 */
8533int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
8534 struct net_device *ndev,
8535 enum nl80211_iftype type,
8536 u32 *flags,
8537 struct vif_params *params
8538 )
8539{
8540 int ret;
8541
8542 vos_ssr_protect(__func__);
8543 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
8544 vos_ssr_unprotect(__func__);
8545
8546 return ret;
8547}
8548
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008549#ifdef FEATURE_WLAN_TDLS
8550static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
8551 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
8552{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008553 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008554 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308555 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308556 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308557 hdd_adapter_t *pAdapter;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008558
8559 ENTER();
8560
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308561 if (!dev) {
8562 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
8563 return -EINVAL;
8564 }
8565
8566 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8567 if (!pAdapter) {
8568 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
8569 return -EINVAL;
8570 }
8571
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308572 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008573 {
8574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8575 "Invalid arguments");
8576 return -EINVAL;
8577 }
Hoonki Lee27511902013-03-14 18:19:06 -07008578
8579 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
8580 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
8581 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07008583 "%s: TDLS mode is disabled OR not enabled in FW."
8584 MAC_ADDRESS_STR " Request declined.",
8585 __func__, MAC_ADDR_ARRAY(mac));
8586 return -ENOTSUPP;
8587 }
8588
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008589 if (pHddCtx->isLogpInProgress)
8590 {
8591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8592 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05308593 wlan_hdd_tdls_set_link_status(pAdapter,
8594 mac,
8595 eTDLS_LINK_IDLE,
8596 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008597 return -EBUSY;
8598 }
8599
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308600 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05308601 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008602
8603 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308604 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008605 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
8606 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308607 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008608 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008609 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308610 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008611
8612 /* in add station, we accept existing valid staId if there is */
8613 if ((0 == update) &&
8614 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
8615 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008616 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008618 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008619 " link_status %d. staId %d. add station ignored.",
8620 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
8621 return 0;
8622 }
8623 /* in change station, we accept only when staId is valid */
8624 if ((1 == update) &&
8625 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
8626 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
8627 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008629 "%s: " MAC_ADDRESS_STR
8630 " link status %d. staId %d. change station %s.",
8631 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
8632 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
8633 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008634 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008635
8636 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05308637 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008638 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008639 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8640 "%s: " MAC_ADDRESS_STR
8641 " TDLS setup is ongoing. Request declined.",
8642 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07008643 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008644 }
8645
8646 /* first to check if we reached to maximum supported TDLS peer.
8647 TODO: for now, return -EPERM looks working fine,
8648 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308649 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8650 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008651 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8653 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308654 " TDLS Max peer already connected. Request declined."
8655 " Num of peers (%d), Max allowed (%d).",
8656 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
8657 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008658 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008659 }
8660 else
8661 {
8662 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308663 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008664 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008665 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008666 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8667 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
8668 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008669 return -EPERM;
8670 }
8671 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008672 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05308673 wlan_hdd_tdls_set_link_status(pAdapter,
8674 mac,
8675 eTDLS_LINK_CONNECTING,
8676 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008677
Jeff Johnsond75fe012013-04-06 10:53:06 -07008678 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308679 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008680 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008682 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008683 if(StaParams->htcap_present)
8684 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008686 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008688 "ht_capa->extended_capabilities: %0x",
8689 StaParams->HTCap.extendedHtCapInfo);
8690 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008692 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008694 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008695 if(StaParams->vhtcap_present)
8696 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008698 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
8699 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
8700 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
8701 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008702 {
8703 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008705 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008707 "[%d]: %x ", i, StaParams->supported_rates[i]);
8708 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07008709 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308710 else if ((1 == update) && (NULL == StaParams))
8711 {
8712 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8713 "%s : update is true, but staParams is NULL. Error!", __func__);
8714 return -EPERM;
8715 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008716
8717 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
8718
8719 if (!update)
8720 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308721 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008722 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308723 if (ret != eHAL_STATUS_SUCCESS) {
8724 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to add TDLS peer STA"));
8725 return -EPERM;
8726 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008727 }
8728 else
8729 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308730 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008731 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308732 if (ret != eHAL_STATUS_SUCCESS) {
8733 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
8734 return -EPERM;
8735 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008736 }
8737
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308738 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008739 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
8740
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308741 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008742 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308744 "%s: timeout waiting for tdls add station indication %ld",
8745 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008746 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008747 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308748
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008749 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
8750 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008752 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008753 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008754 }
8755
8756 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008757
8758error:
Atul Mittal115287b2014-07-08 13:26:33 +05308759 wlan_hdd_tdls_set_link_status(pAdapter,
8760 mac,
8761 eTDLS_LINK_IDLE,
8762 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008763 return -EPERM;
8764
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008765}
8766#endif
8767
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308768static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008769 struct net_device *dev,
8770 u8 *mac,
8771 struct station_parameters *params)
8772{
8773 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308774 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308775 hdd_context_t *pHddCtx;
8776 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008777 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308778 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008779#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008780 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008781 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308782 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008783#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008784
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308785 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308786
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308787 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308788 if ((NULL == pAdapter))
8789 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308791 "invalid adapter ");
8792 return -EINVAL;
8793 }
8794
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308795 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8796 TRACE_CODE_HDD_CHANGE_STATION,
8797 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05308798 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308799
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308800 ret = wlan_hdd_validate_context(pHddCtx);
8801 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05308802 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308803 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308804 }
8805
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308806 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8807
8808 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008809 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8811 "invalid HDD station context");
8812 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008813 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008814 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
8815
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008816 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8817 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07008818 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008819 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07008820 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308821 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07008822 WLANTL_STA_AUTHENTICATED);
8823
Gopichand Nakkala29149562013-05-10 21:43:41 +05308824 if (status != VOS_STATUS_SUCCESS)
8825 {
8826 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8827 "%s: Not able to change TL state to AUTHENTICATED", __func__);
8828 return -EINVAL;
8829 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008830 }
8831 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07008832 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8833 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308834#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008835 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8836 StaParams.capability = params->capability;
8837 StaParams.uapsd_queues = params->uapsd_queues;
8838 StaParams.max_sp = params->max_sp;
8839
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308840 /* Convert (first channel , number of channels) tuple to
8841 * the total list of channels. This goes with the assumption
8842 * that if the first channel is < 14, then the next channels
8843 * are an incremental of 1 else an incremental of 4 till the number
8844 * of channels.
8845 */
8846 if (0 != params->supported_channels_len) {
8847 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
8848 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
8849 {
8850 int wifi_chan_index;
8851 StaParams.supported_channels[j] = params->supported_channels[i];
8852 wifi_chan_index =
8853 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
8854 no_of_channels = params->supported_channels[i+1];
8855 for(k=1; k <= no_of_channels; k++)
8856 {
8857 StaParams.supported_channels[j+1] =
8858 StaParams.supported_channels[j] + wifi_chan_index;
8859 j+=1;
8860 }
8861 }
8862 StaParams.supported_channels_len = j;
8863 }
8864 vos_mem_copy(StaParams.supported_oper_classes,
8865 params->supported_oper_classes,
8866 params->supported_oper_classes_len);
8867 StaParams.supported_oper_classes_len =
8868 params->supported_oper_classes_len;
8869
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008870 if (0 != params->ext_capab_len)
8871 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
8872 sizeof(StaParams.extn_capability));
8873
8874 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008875 {
8876 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008877 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008878 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008879
8880 StaParams.supported_rates_len = params->supported_rates_len;
8881
8882 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
8883 * The supported_rates array , for all the structures propogating till Add Sta
8884 * to the firmware has to be modified , if the supplicant (ieee80211) is
8885 * modified to send more rates.
8886 */
8887
8888 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
8889 */
8890 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
8891 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
8892
8893 if (0 != StaParams.supported_rates_len) {
8894 int i = 0;
8895 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
8896 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008897 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008898 "Supported Rates with Length %d", StaParams.supported_rates_len);
8899 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008900 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008901 "[%d]: %0x", i, StaParams.supported_rates[i]);
8902 }
8903
8904 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008905 {
8906 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008907 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008908 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008909
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008910 if (0 != params->ext_capab_len ) {
8911 /*Define A Macro : TODO Sunil*/
8912 if ((1<<4) & StaParams.extn_capability[3]) {
8913 isBufSta = 1;
8914 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308915 /* TDLS Channel Switching Support */
8916 if ((1<<6) & StaParams.extn_capability[3]) {
8917 isOffChannelSupported = 1;
8918 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008919 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308920 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
8921 &StaParams, isBufSta,
8922 isOffChannelSupported);
8923
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308924 if (VOS_STATUS_SUCCESS != status) {
8925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8926 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
8927 return -EINVAL;
8928 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008929 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
8930
8931 if (VOS_STATUS_SUCCESS != status) {
8932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8933 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
8934 return -EINVAL;
8935 }
8936 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008937#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05308938 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008939 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008940 return status;
8941}
8942
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308943static int wlan_hdd_change_station(struct wiphy *wiphy,
8944 struct net_device *dev,
8945 u8 *mac,
8946 struct station_parameters *params)
8947{
8948 int ret;
8949
8950 vos_ssr_protect(__func__);
8951 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
8952 vos_ssr_unprotect(__func__);
8953
8954 return ret;
8955}
8956
Jeff Johnson295189b2012-06-20 16:38:30 -07008957/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308958 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008959 * This function is used to initialize the key information
8960 */
8961#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
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, bool pairwise,
8965 const u8 *mac_addr,
8966 struct key_params *params
8967 )
8968#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308969static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008970 struct net_device *ndev,
8971 u8 key_index, const u8 *mac_addr,
8972 struct key_params *params
8973 )
8974#endif
8975{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008976 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07008977 tCsrRoamSetKey setKey;
8978 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308979 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008980 v_U32_t roamId= 0xFF;
8981 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008982 hdd_hostapd_state_t *pHostapdState;
8983 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008984 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308985 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008986
8987 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308988
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308989 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8990 TRACE_CODE_HDD_CFG80211_ADD_KEY,
8991 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308992 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8993 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308994 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008995 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308996 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008997 }
8998
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308999 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9000 __func__, hdd_device_modetoString(pAdapter->device_mode),
9001 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009002
9003 if (CSR_MAX_NUM_KEY <= key_index)
9004 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009005 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009006 key_index);
9007
9008 return -EINVAL;
9009 }
9010
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009011 if (CSR_MAX_KEY_LEN < params->key_len)
9012 {
9013 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
9014 params->key_len);
9015
9016 return -EINVAL;
9017 }
9018
9019 hddLog(VOS_TRACE_LEVEL_INFO,
9020 "%s: called with key index = %d & key length %d",
9021 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009022
9023 /*extract key idx, key len and key*/
9024 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9025 setKey.keyId = key_index;
9026 setKey.keyLength = params->key_len;
9027 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
9028
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009029 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009030 {
9031 case WLAN_CIPHER_SUITE_WEP40:
9032 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
9033 break;
9034
9035 case WLAN_CIPHER_SUITE_WEP104:
9036 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
9037 break;
9038
9039 case WLAN_CIPHER_SUITE_TKIP:
9040 {
9041 u8 *pKey = &setKey.Key[0];
9042 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
9043
9044 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
9045
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009046 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07009047
9048 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009049 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009050 |--------------|----------|----------|
9051 <---16bytes---><--8bytes--><--8bytes-->
9052
9053 */
9054 /*Sme expects the 32 bytes key to be in the below order
9055
9056 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009057 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009058 |--------------|----------|----------|
9059 <---16bytes---><--8bytes--><--8bytes-->
9060 */
9061 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009062 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07009063
9064 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009065 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009066
9067 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009068 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009069
9070
9071 break;
9072 }
9073
9074 case WLAN_CIPHER_SUITE_CCMP:
9075 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
9076 break;
9077
9078#ifdef FEATURE_WLAN_WAPI
9079 case WLAN_CIPHER_SUITE_SMS4:
9080 {
9081 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9082 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
9083 params->key, params->key_len);
9084 return 0;
9085 }
9086#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009087
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009088#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009089 case WLAN_CIPHER_SUITE_KRK:
9090 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
9091 break;
9092#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009093
9094#ifdef WLAN_FEATURE_11W
9095 case WLAN_CIPHER_SUITE_AES_CMAC:
9096 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07009097 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07009098#endif
9099
Jeff Johnson295189b2012-06-20 16:38:30 -07009100 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009101 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009102 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309103 status = -EOPNOTSUPP;
9104 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009105 }
9106
9107 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
9108 __func__, setKey.encType);
9109
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009110 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07009111#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9112 (!pairwise)
9113#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009114 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07009115#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009116 )
9117 {
9118 /* set group key*/
9119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9120 "%s- %d: setting Broadcast key",
9121 __func__, __LINE__);
9122 setKey.keyDirection = eSIR_RX_ONLY;
9123 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9124 }
9125 else
9126 {
9127 /* set pairwise key*/
9128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9129 "%s- %d: setting pairwise key",
9130 __func__, __LINE__);
9131 setKey.keyDirection = eSIR_TX_RX;
9132 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9133 }
9134 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
9135 {
9136 setKey.keyDirection = eSIR_TX_RX;
9137 /*Set the group key*/
9138 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9139 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07009140
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009141 if ( 0 != status )
9142 {
9143 hddLog(VOS_TRACE_LEVEL_ERROR,
9144 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309145 status = -EINVAL;
9146 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009147 }
9148 /*Save the keys here and call sme_RoamSetKey for setting
9149 the PTK after peer joins the IBSS network*/
9150 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
9151 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309152 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009153 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05309154 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
9155 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
9156 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009157 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009158 if( pHostapdState->bssState == BSS_START )
9159 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009160 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9161 vos_status = wlan_hdd_check_ula_done(pAdapter);
9162
9163 if ( vos_status != VOS_STATUS_SUCCESS )
9164 {
9165 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9166 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9167 __LINE__, vos_status );
9168
9169 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9170
9171 status = -EINVAL;
9172 goto end;
9173 }
9174
Jeff Johnson295189b2012-06-20 16:38:30 -07009175 status = WLANSAP_SetKeySta( pVosContext, &setKey);
9176
9177 if ( status != eHAL_STATUS_SUCCESS )
9178 {
9179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9180 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9181 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309182 status = -EINVAL;
9183 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009184 }
9185 }
9186
9187 /* Saving WEP keys */
9188 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
9189 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
9190 {
9191 //Save the wep key in ap context. Issue setkey after the BSS is started.
9192 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9193 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
9194 }
9195 else
9196 {
9197 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009198 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009199 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
9200 }
9201 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009202 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
9203 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009204 {
9205 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9206 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9207
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309208#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9209 if (!pairwise)
9210#else
9211 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9212#endif
9213 {
9214 /* set group key*/
9215 if (pHddStaCtx->roam_info.deferKeyComplete)
9216 {
9217 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9218 "%s- %d: Perform Set key Complete",
9219 __func__, __LINE__);
9220 hdd_PerformRoamSetKeyComplete(pAdapter);
9221 }
9222 }
9223
Jeff Johnson295189b2012-06-20 16:38:30 -07009224 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
9225
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08009226 pWextState->roamProfile.Keys.defaultIndex = key_index;
9227
9228
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009229 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009230 params->key, params->key_len);
9231
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309232
Jeff Johnson295189b2012-06-20 16:38:30 -07009233 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9234
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309235 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009236 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309237 __func__, setKey.peerMac[0], setKey.peerMac[1],
9238 setKey.peerMac[2], setKey.peerMac[3],
9239 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009240 setKey.keyDirection);
9241
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009242 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +05309243
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009244 if ( vos_status != VOS_STATUS_SUCCESS )
9245 {
9246 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009247 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9248 __LINE__, vos_status );
9249
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009250 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009251
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009252 status = -EINVAL;
9253 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009254
9255 }
9256
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009257#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309258 /* The supplicant may attempt to set the PTK once pre-authentication
9259 is done. Save the key in the UMAC and include it in the ADD BSS
9260 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009261 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309262 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009263 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309264 hddLog(VOS_TRACE_LEVEL_INFO_MED,
9265 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309266 status = 0;
9267 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309268 }
9269 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
9270 {
9271 hddLog(VOS_TRACE_LEVEL_ERROR,
9272 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309273 status = -EINVAL;
9274 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009275 }
9276#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07009277
9278 /* issue set key request to SME*/
9279 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9280 pAdapter->sessionId, &setKey, &roamId );
9281
9282 if ( 0 != status )
9283 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309284 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009285 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
9286 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309287 status = -EINVAL;
9288 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009289 }
9290
9291
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309292 /* in case of IBSS as there was no information available about WEP keys during
9293 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07009294 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309295 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
9296 !( ( IW_AUTH_KEY_MGMT_802_1X
9297 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07009298 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
9299 )
9300 &&
9301 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
9302 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
9303 )
9304 )
9305 {
9306 setKey.keyDirection = eSIR_RX_ONLY;
9307 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9308
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309309 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009310 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309311 __func__, setKey.peerMac[0], setKey.peerMac[1],
9312 setKey.peerMac[2], setKey.peerMac[3],
9313 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009314 setKey.keyDirection);
9315
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309316 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009317 pAdapter->sessionId, &setKey, &roamId );
9318
9319 if ( 0 != status )
9320 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309321 hddLog(VOS_TRACE_LEVEL_ERROR,
9322 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009323 __func__, status);
9324 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309325 status = -EINVAL;
9326 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009327 }
9328 }
9329 }
9330
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309331end:
9332 /* Need to clear any trace of key value in the memory.
9333 * Thus zero out the memory even though it is local
9334 * variable.
9335 */
9336 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309337 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309338 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009339}
9340
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309341#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9342static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9343 struct net_device *ndev,
9344 u8 key_index, bool pairwise,
9345 const u8 *mac_addr,
9346 struct key_params *params
9347 )
9348#else
9349static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9350 struct net_device *ndev,
9351 u8 key_index, const u8 *mac_addr,
9352 struct key_params *params
9353 )
9354#endif
9355{
9356 int ret;
9357 vos_ssr_protect(__func__);
9358#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9359 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
9360 mac_addr, params);
9361#else
9362 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
9363 params);
9364#endif
9365 vos_ssr_unprotect(__func__);
9366
9367 return ret;
9368}
9369
Jeff Johnson295189b2012-06-20 16:38:30 -07009370/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309371 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009372 * This function is used to get the key information
9373 */
9374#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309375static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309376 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009377 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309378 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009379 const u8 *mac_addr, void *cookie,
9380 void (*callback)(void *cookie, struct key_params*)
9381 )
9382#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309383static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309384 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009385 struct net_device *ndev,
9386 u8 key_index, const u8 *mac_addr, void *cookie,
9387 void (*callback)(void *cookie, struct key_params*)
9388 )
9389#endif
9390{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309391 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309392 hdd_wext_state_t *pWextState = NULL;
9393 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009394 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309395 hdd_context_t *pHddCtx;
9396 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009397
9398 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309399
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309400 if (NULL == pAdapter)
9401 {
9402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9403 "%s: HDD adapter is Null", __func__);
9404 return -ENODEV;
9405 }
9406
9407 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9408 ret = wlan_hdd_validate_context(pHddCtx);
9409 if (0 != ret)
9410 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309411 return ret;
9412 }
9413
9414 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9415 pRoamProfile = &(pWextState->roamProfile);
9416
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309417 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9418 __func__, hdd_device_modetoString(pAdapter->device_mode),
9419 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309420
Jeff Johnson295189b2012-06-20 16:38:30 -07009421 memset(&params, 0, sizeof(params));
9422
9423 if (CSR_MAX_NUM_KEY <= key_index)
9424 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309425 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07009426 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309427 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009428
9429 switch(pRoamProfile->EncryptionType.encryptionType[0])
9430 {
9431 case eCSR_ENCRYPT_TYPE_NONE:
9432 params.cipher = IW_AUTH_CIPHER_NONE;
9433 break;
9434
9435 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
9436 case eCSR_ENCRYPT_TYPE_WEP40:
9437 params.cipher = WLAN_CIPHER_SUITE_WEP40;
9438 break;
9439
9440 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
9441 case eCSR_ENCRYPT_TYPE_WEP104:
9442 params.cipher = WLAN_CIPHER_SUITE_WEP104;
9443 break;
9444
9445 case eCSR_ENCRYPT_TYPE_TKIP:
9446 params.cipher = WLAN_CIPHER_SUITE_TKIP;
9447 break;
9448
9449 case eCSR_ENCRYPT_TYPE_AES:
9450 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
9451 break;
9452
9453 default:
9454 params.cipher = IW_AUTH_CIPHER_NONE;
9455 break;
9456 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309457
c_hpothuaaf19692014-05-17 17:01:48 +05309458 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9459 TRACE_CODE_HDD_CFG80211_GET_KEY,
9460 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309461
Jeff Johnson295189b2012-06-20 16:38:30 -07009462 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
9463 params.seq_len = 0;
9464 params.seq = NULL;
9465 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
9466 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309467 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009468 return 0;
9469}
9470
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309471#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9472static int wlan_hdd_cfg80211_get_key(
9473 struct wiphy *wiphy,
9474 struct net_device *ndev,
9475 u8 key_index, bool pairwise,
9476 const u8 *mac_addr, void *cookie,
9477 void (*callback)(void *cookie, struct key_params*)
9478 )
9479#else
9480static int wlan_hdd_cfg80211_get_key(
9481 struct wiphy *wiphy,
9482 struct net_device *ndev,
9483 u8 key_index, const u8 *mac_addr, void *cookie,
9484 void (*callback)(void *cookie, struct key_params*)
9485 )
9486#endif
9487{
9488 int ret;
9489
9490 vos_ssr_protect(__func__);
9491#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9492 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
9493 mac_addr, cookie, callback);
9494#else
9495 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
9496 callback);
9497#endif
9498 vos_ssr_unprotect(__func__);
9499
9500 return ret;
9501}
9502
Jeff Johnson295189b2012-06-20 16:38:30 -07009503/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309504 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009505 * This function is used to delete the key information
9506 */
9507#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
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,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309510 u8 key_index,
9511 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009512 const u8 *mac_addr
9513 )
9514#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309515static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009516 struct net_device *ndev,
9517 u8 key_index,
9518 const u8 *mac_addr
9519 )
9520#endif
9521{
9522 int status = 0;
9523
9524 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309525 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009526 //it is observed that this is invalidating peer
9527 //key index whenever re-key is done. This is affecting data link.
9528 //It should be ok to ignore del_key.
9529#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309530 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
9531 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009532 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
9533 tCsrRoamSetKey setKey;
9534 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309535
Jeff Johnson295189b2012-06-20 16:38:30 -07009536 ENTER();
9537
9538 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
9539 __func__,pAdapter->device_mode);
9540
9541 if (CSR_MAX_NUM_KEY <= key_index)
9542 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309543 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009544 key_index);
9545
9546 return -EINVAL;
9547 }
9548
9549 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9550 setKey.keyId = key_index;
9551
9552 if (mac_addr)
9553 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9554 else
9555 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
9556
9557 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
9558
9559 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009560 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309561 )
9562 {
9563
9564 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07009565 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9566 if( pHostapdState->bssState == BSS_START)
9567 {
9568 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309569
Jeff Johnson295189b2012-06-20 16:38:30 -07009570 if ( status != eHAL_STATUS_SUCCESS )
9571 {
9572 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9573 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9574 __LINE__, status );
9575 }
9576 }
9577 }
9578 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309579 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07009580 )
9581 {
9582 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9583
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309584 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9585
9586 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009587 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309588 __func__, setKey.peerMac[0], setKey.peerMac[1],
9589 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07009590 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309591 if(pAdapter->sessionCtx.station.conn_info.connState ==
9592 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07009593 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309594 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009595 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309596
Jeff Johnson295189b2012-06-20 16:38:30 -07009597 if ( 0 != status )
9598 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309599 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009600 "%s: sme_RoamSetKey failure, returned %d",
9601 __func__, status);
9602 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9603 return -EINVAL;
9604 }
9605 }
9606 }
9607#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009608 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009609 return status;
9610}
9611
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309612#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9613static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9614 struct net_device *ndev,
9615 u8 key_index,
9616 bool pairwise,
9617 const u8 *mac_addr
9618 )
9619#else
9620static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9621 struct net_device *ndev,
9622 u8 key_index,
9623 const u8 *mac_addr
9624 )
9625#endif
9626{
9627 int ret;
9628
9629 vos_ssr_protect(__func__);
9630#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9631 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
9632 mac_addr);
9633#else
9634 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
9635#endif
9636 vos_ssr_unprotect(__func__);
9637
9638 return ret;
9639}
9640
Jeff Johnson295189b2012-06-20 16:38:30 -07009641/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309642 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009643 * This function is used to set the default tx key index
9644 */
9645#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309646static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009647 struct net_device *ndev,
9648 u8 key_index,
9649 bool unicast, bool multicast)
9650#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309651static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009652 struct net_device *ndev,
9653 u8 key_index)
9654#endif
9655{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309656 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309657 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309658 hdd_wext_state_t *pWextState;
9659 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309660 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009661
9662 ENTER();
9663
Gopichand Nakkala29149562013-05-10 21:43:41 +05309664 if ((NULL == pAdapter))
9665 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309667 "invalid adapter");
9668 return -EINVAL;
9669 }
9670
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309671 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9672 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
9673 pAdapter->sessionId, key_index));
9674
Gopichand Nakkala29149562013-05-10 21:43:41 +05309675 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9676 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9677
9678 if ((NULL == pWextState) || (NULL == pHddStaCtx))
9679 {
9680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9681 "invalid Wext state or HDD context");
9682 return -EINVAL;
9683 }
9684
Arif Hussain6d2a3322013-11-17 19:50:10 -08009685 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009686 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309687
Jeff Johnson295189b2012-06-20 16:38:30 -07009688 if (CSR_MAX_NUM_KEY <= key_index)
9689 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309690 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009691 key_index);
9692
9693 return -EINVAL;
9694 }
9695
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309696 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9697 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309698 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009699 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309700 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009701 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309702
Jeff Johnson295189b2012-06-20 16:38:30 -07009703 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07009704 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309705 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009706 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309707 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08009708 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309709 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08009710 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07009711 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309712 {
9713 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07009714 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309715
Jeff Johnson295189b2012-06-20 16:38:30 -07009716 tCsrRoamSetKey setKey;
9717 v_U32_t roamId= 0xFF;
9718 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309719
9720 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009721 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309722
Jeff Johnson295189b2012-06-20 16:38:30 -07009723 Keys->defaultIndex = (u8)key_index;
9724 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9725 setKey.keyId = key_index;
9726 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309727
9728 vos_mem_copy(&setKey.Key[0],
9729 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009730 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309731
Gopichand Nakkala29149562013-05-10 21:43:41 +05309732 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309733
9734 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07009735 &pHddStaCtx->conn_info.bssId[0],
9736 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309737
Gopichand Nakkala29149562013-05-10 21:43:41 +05309738 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
9739 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
9740 eCSR_ENCRYPT_TYPE_WEP104)
9741 {
9742 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
9743 even though ap is configured for WEP-40 encryption. In this canse the key length
9744 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
9745 type(104) and switching encryption type to 40*/
9746 pWextState->roamProfile.EncryptionType.encryptionType[0] =
9747 eCSR_ENCRYPT_TYPE_WEP40;
9748 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
9749 eCSR_ENCRYPT_TYPE_WEP40;
9750 }
9751
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309752 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07009753 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309754
Jeff Johnson295189b2012-06-20 16:38:30 -07009755 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309756 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009757 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309758
Jeff Johnson295189b2012-06-20 16:38:30 -07009759 if ( 0 != status )
9760 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309761 hddLog(VOS_TRACE_LEVEL_ERROR,
9762 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009763 status);
9764 return -EINVAL;
9765 }
9766 }
9767 }
9768
9769 /* In SoftAp mode setting key direction for default mode */
9770 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
9771 {
9772 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
9773 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
9774 (eCSR_ENCRYPT_TYPE_AES !=
9775 pWextState->roamProfile.EncryptionType.encryptionType[0])
9776 )
9777 {
9778 /* Saving key direction for default key index to TX default */
9779 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9780 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
9781 }
9782 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309783 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009784 return status;
9785}
9786
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309787#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9788static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9789 struct net_device *ndev,
9790 u8 key_index,
9791 bool unicast, bool multicast)
9792#else
9793static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9794 struct net_device *ndev,
9795 u8 key_index)
9796#endif
9797{
9798 int ret;
9799 vos_ssr_protect(__func__);
9800#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9801 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
9802 multicast);
9803#else
9804 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
9805#endif
9806 vos_ssr_unprotect(__func__);
9807
9808 return ret;
9809}
9810
Jeff Johnson295189b2012-06-20 16:38:30 -07009811/*
9812 * FUNCTION: wlan_hdd_cfg80211_inform_bss
9813 * This function is used to inform the BSS details to nl80211 interface.
9814 */
9815static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
9816 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
9817{
9818 struct net_device *dev = pAdapter->dev;
9819 struct wireless_dev *wdev = dev->ieee80211_ptr;
9820 struct wiphy *wiphy = wdev->wiphy;
9821 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
9822 int chan_no;
9823 int ie_length;
9824 const char *ie;
9825 unsigned int freq;
9826 struct ieee80211_channel *chan;
9827 int rssi = 0;
9828 struct cfg80211_bss *bss = NULL;
9829
Jeff Johnson295189b2012-06-20 16:38:30 -07009830 if( NULL == pBssDesc )
9831 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009832 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009833 return bss;
9834 }
9835
9836 chan_no = pBssDesc->channelId;
9837 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
9838 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
9839
9840 if( NULL == ie )
9841 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009842 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009843 return bss;
9844 }
9845
9846#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9847 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9848 {
9849 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9850 }
9851 else
9852 {
9853 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9854 }
9855#else
9856 freq = ieee80211_channel_to_frequency(chan_no);
9857#endif
9858
9859 chan = __ieee80211_get_channel(wiphy, freq);
9860
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05309861 if (!chan) {
9862 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
9863 return NULL;
9864 }
9865
Abhishek Singhaee43942014-06-16 18:55:47 +05309866 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07009867
Abhishek Singhaee43942014-06-16 18:55:47 +05309868 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309869 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07009870 pBssDesc->capabilityInfo,
9871 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05309872 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07009873}
9874
9875
9876
9877/*
9878 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
9879 * This function is used to inform the BSS details to nl80211 interface.
9880 */
9881struct cfg80211_bss*
9882wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
9883 tSirBssDescription *bss_desc
9884 )
9885{
9886 /*
9887 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
9888 already exists in bss data base of cfg80211 for that particular BSS ID.
9889 Using cfg80211_inform_bss_frame to update the bss entry instead of
9890 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
9891 now there is no possibility to get the mgmt(probe response) frame from PE,
9892 converting bss_desc to ieee80211_mgmt(probe response) and passing to
9893 cfg80211_inform_bss_frame.
9894 */
9895 struct net_device *dev = pAdapter->dev;
9896 struct wireless_dev *wdev = dev->ieee80211_ptr;
9897 struct wiphy *wiphy = wdev->wiphy;
9898 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009899#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9900 qcom_ie_age *qie_age = NULL;
9901 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
9902#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009903 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009904#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009905 const char *ie =
9906 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
9907 unsigned int freq;
9908 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309909 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009910 struct cfg80211_bss *bss_status = NULL;
9911 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
9912 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07009913 hdd_context_t *pHddCtx;
9914 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07009915#ifdef WLAN_OPEN_SOURCE
9916 struct timespec ts;
9917#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009918
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309919
Wilson Yangf80a0542013-10-07 13:02:37 -07009920 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9921 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -07009922 if (0 != status)
9923 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009924 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009925 }
9926
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309927 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07009928 if (!mgmt)
9929 {
9930 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9931 "%s: memory allocation failed ", __func__);
9932 return NULL;
9933 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009934
Jeff Johnson295189b2012-06-20 16:38:30 -07009935 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07009936
9937#ifdef WLAN_OPEN_SOURCE
9938 /* Android does not want the timestamp from the frame.
9939 Instead it wants a monotonic increasing value */
9940 get_monotonic_boottime(&ts);
9941 mgmt->u.probe_resp.timestamp =
9942 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
9943#else
9944 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009945 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
9946 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07009947
9948#endif
9949
Jeff Johnson295189b2012-06-20 16:38:30 -07009950 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
9951 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009952
9953#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9954 /* GPS Requirement: need age ie per entry. Using vendor specific. */
9955 /* Assuming this is the last IE, copy at the end */
9956 ie_length -=sizeof(qcom_ie_age);
9957 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
9958 qie_age->element_id = QCOM_VENDOR_IE_ID;
9959 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
9960 qie_age->oui_1 = QCOM_OUI1;
9961 qie_age->oui_2 = QCOM_OUI2;
9962 qie_age->oui_3 = QCOM_OUI3;
9963 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
9964 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
9965#endif
9966
Jeff Johnson295189b2012-06-20 16:38:30 -07009967 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05309968 if (bss_desc->fProbeRsp)
9969 {
9970 mgmt->frame_control |=
9971 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
9972 }
9973 else
9974 {
9975 mgmt->frame_control |=
9976 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
9977 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009978
9979#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309980 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009981 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
9982 {
9983 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9984 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309985 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009986 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
9987
9988 {
9989 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9990 }
9991 else
9992 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309993 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
9994 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07009995 kfree(mgmt);
9996 return NULL;
9997 }
9998#else
9999 freq = ieee80211_channel_to_frequency(chan_no);
10000#endif
10001 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010002 /*when the band is changed on the fly using the GUI, three things are done
10003 * 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)
10004 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
10005 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
10006 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
10007 * and discards the channels correponding to previous band and calls back with zero bss results.
10008 * 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
10009 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
10010 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
10011 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
10012 * So drop the bss and continue to next bss.
10013 */
10014 if(chan == NULL)
10015 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010016 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070010017 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010018 return NULL;
10019 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053010020 /*To keep the rssi icon of the connected AP in the scan window
10021 *and the rssi icon of the wireless networks in sync
10022 * */
10023 if (( eConnectionState_Associated ==
10024 pAdapter->sessionCtx.station.conn_info.connState ) &&
10025 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
10026 pAdapter->sessionCtx.station.conn_info.bssId,
10027 WNI_CFG_BSSID_LEN)) &&
10028 (pHddCtx->hdd_wlan_suspended == FALSE))
10029 {
10030 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
10031 rssi = (pAdapter->rssi * 100);
10032 }
10033 else
10034 {
10035 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
10036 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010037
Nirav Shah20ac06f2013-12-12 18:14:06 +053010038 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053010039 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
10040 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053010041
Jeff Johnson295189b2012-06-20 16:38:30 -070010042 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
10043 frame_len, rssi, GFP_KERNEL);
10044 kfree(mgmt);
10045 return bss_status;
10046}
10047
10048/*
10049 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
10050 * This function is used to update the BSS data base of CFG8011
10051 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010052struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010053 tCsrRoamInfo *pRoamInfo
10054 )
10055{
10056 tCsrRoamConnectedProfile roamProfile;
10057 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10058 struct cfg80211_bss *bss = NULL;
10059
10060 ENTER();
10061
10062 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
10063 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
10064
10065 if (NULL != roamProfile.pBssDesc)
10066 {
Girish Gowlif4b68022014-08-28 23:18:57 +053010067 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10068 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070010069
10070 if (NULL == bss)
10071 {
10072 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
10073 __func__);
10074 }
10075
10076 sme_RoamFreeConnectProfile(hHal, &roamProfile);
10077 }
10078 else
10079 {
10080 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
10081 __func__);
10082 }
10083 return bss;
10084}
10085
10086/*
10087 * FUNCTION: wlan_hdd_cfg80211_update_bss
10088 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010089static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
10090 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070010091 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010092{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010093 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010094 tCsrScanResultInfo *pScanResult;
10095 eHalStatus status = 0;
10096 tScanResultHandle pResult;
10097 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010098 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010099 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070010100 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010101
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010102 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10103 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
10104 NO_SESSION, pAdapter->sessionId));
10105
Wilson Yangf80a0542013-10-07 13:02:37 -070010106 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10107
10108 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070010109 {
Wilson Yangf80a0542013-10-07 13:02:37 -070010110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10111 "%s:LOGP in Progress. Ignore!!!",__func__);
10112 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010113 }
10114
Wilson Yangf80a0542013-10-07 13:02:37 -070010115
10116 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053010117 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070010118 {
10119 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10120 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
10121 return VOS_STATUS_E_PERM;
10122 }
10123
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010124 if (pAdapter->request != NULL)
10125 {
10126 if ((pAdapter->request->n_ssids == 1)
10127 && (pAdapter->request->ssids != NULL)
10128 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
10129 is_p2p_scan = true;
10130 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010131 /*
10132 * start getting scan results and populate cgf80211 BSS database
10133 */
10134 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
10135
10136 /* no scan results */
10137 if (NULL == pResult)
10138 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010139 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
10140 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053010141 wlan_hdd_get_frame_logs(pAdapter,
10142 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070010143 return status;
10144 }
10145
10146 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
10147
10148 while (pScanResult)
10149 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010150 /*
10151 * cfg80211_inform_bss() is not updating ie field of bss entry, if
10152 * entry already exists in bss data base of cfg80211 for that
10153 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
10154 * bss entry instead of cfg80211_inform_bss, But this call expects
10155 * mgmt packet as input. As of now there is no possibility to get
10156 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070010157 * ieee80211_mgmt(probe response) and passing to c
10158 * fg80211_inform_bss_frame.
10159 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010160 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
10161 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
10162 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010163 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10164 continue; //Skip the non p2p bss entries
10165 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010166 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10167 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010168
Jeff Johnson295189b2012-06-20 16:38:30 -070010169
10170 if (NULL == bss_status)
10171 {
10172 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010173 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010174 }
10175 else
10176 {
Yue Maf49ba872013-08-19 12:04:25 -070010177 cfg80211_put_bss(
10178#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
10179 wiphy,
10180#endif
10181 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010182 }
10183
10184 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10185 }
10186
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010187 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010188 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010189 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010190}
10191
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010192void
10193hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
10194{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010195 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080010196 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010197} /****** end hddPrintMacAddr() ******/
10198
10199void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010200hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010201{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010202 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010203 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010204 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
10205 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
10206 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010207} /****** end hddPrintPmkId() ******/
10208
10209//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
10210//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
10211
10212//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
10213//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
10214
10215#define dump_bssid(bssid) \
10216 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010217 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
10218 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010219 }
10220
10221#define dump_pmkid(pMac, pmkid) \
10222 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010223 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
10224 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010225 }
10226
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070010227#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010228/*
10229 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
10230 * This function is used to notify the supplicant of a new PMKSA candidate.
10231 */
10232int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010233 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010234 int index, bool preauth )
10235{
Jeff Johnsone7245742012-09-05 17:12:55 -070010236#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010237 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010238 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010239
10240 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070010241 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010242
10243 if( NULL == pRoamInfo )
10244 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010245 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010246 return -EINVAL;
10247 }
10248
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010249 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
10250 {
10251 dump_bssid(pRoamInfo->bssid);
10252 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010253 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010254 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010255#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010256 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010257}
10258#endif //FEATURE_WLAN_LFR
10259
Yue Maef608272013-04-08 23:09:17 -070010260#ifdef FEATURE_WLAN_LFR_METRICS
10261/*
10262 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
10263 * 802.11r/LFR metrics reporting function to report preauth initiation
10264 *
10265 */
10266#define MAX_LFR_METRICS_EVENT_LENGTH 100
10267VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
10268 tCsrRoamInfo *pRoamInfo)
10269{
10270 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10271 union iwreq_data wrqu;
10272
10273 ENTER();
10274
10275 if (NULL == pAdapter)
10276 {
10277 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10278 return VOS_STATUS_E_FAILURE;
10279 }
10280
10281 /* create the event */
10282 memset(&wrqu, 0, sizeof(wrqu));
10283 memset(metrics_notification, 0, sizeof(metrics_notification));
10284
10285 wrqu.data.pointer = metrics_notification;
10286 wrqu.data.length = scnprintf(metrics_notification,
10287 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
10288 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10289
10290 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10291
10292 EXIT();
10293
10294 return VOS_STATUS_SUCCESS;
10295}
10296
10297/*
10298 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
10299 * 802.11r/LFR metrics reporting function to report preauth completion
10300 * or failure
10301 */
10302VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
10303 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
10304{
10305 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10306 union iwreq_data wrqu;
10307
10308 ENTER();
10309
10310 if (NULL == pAdapter)
10311 {
10312 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10313 return VOS_STATUS_E_FAILURE;
10314 }
10315
10316 /* create the event */
10317 memset(&wrqu, 0, sizeof(wrqu));
10318 memset(metrics_notification, 0, sizeof(metrics_notification));
10319
10320 scnprintf(metrics_notification, sizeof(metrics_notification),
10321 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
10322 MAC_ADDR_ARRAY(pRoamInfo->bssid));
10323
10324 if (1 == preauth_status)
10325 strncat(metrics_notification, " TRUE", 5);
10326 else
10327 strncat(metrics_notification, " FALSE", 6);
10328
10329 wrqu.data.pointer = metrics_notification;
10330 wrqu.data.length = strlen(metrics_notification);
10331
10332 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10333
10334 EXIT();
10335
10336 return VOS_STATUS_SUCCESS;
10337}
10338
10339/*
10340 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
10341 * 802.11r/LFR metrics reporting function to report handover initiation
10342 *
10343 */
10344VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
10345 tCsrRoamInfo *pRoamInfo)
10346{
10347 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10348 union iwreq_data wrqu;
10349
10350 ENTER();
10351
10352 if (NULL == pAdapter)
10353 {
10354 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10355 return VOS_STATUS_E_FAILURE;
10356 }
10357
10358 /* create the event */
10359 memset(&wrqu, 0, sizeof(wrqu));
10360 memset(metrics_notification, 0, sizeof(metrics_notification));
10361
10362 wrqu.data.pointer = metrics_notification;
10363 wrqu.data.length = scnprintf(metrics_notification,
10364 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
10365 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10366
10367 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10368
10369 EXIT();
10370
10371 return VOS_STATUS_SUCCESS;
10372}
10373#endif
10374
Jeff Johnson295189b2012-06-20 16:38:30 -070010375/*
10376 * FUNCTION: hdd_cfg80211_scan_done_callback
10377 * scanning callback function, called after finishing scan
10378 *
10379 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010380static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070010381 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
10382{
10383 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010384 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070010385 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010386 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010387 struct cfg80211_scan_request *req = NULL;
10388 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010389 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010390 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010391 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010392 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010393
10394 ENTER();
10395
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010396 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053010397 if (NULL == pHddCtx) {
10398 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010399 goto allow_suspend;
10400 }
10401
10402 pScanInfo = &pHddCtx->scan_info;
10403
Jeff Johnson295189b2012-06-20 16:38:30 -070010404 hddLog(VOS_TRACE_LEVEL_INFO,
10405 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080010406 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010407 __func__, halHandle, pContext, (int) scanId, (int) status);
10408
Kiet Lamac06e2c2013-10-23 16:25:07 +053010409 pScanInfo->mScanPendingCounter = 0;
10410
Jeff Johnson295189b2012-06-20 16:38:30 -070010411 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010412 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070010413 &pScanInfo->scan_req_completion_event,
10414 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010415 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070010416 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010417 hddLog(VOS_TRACE_LEVEL_ERROR,
10418 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070010419 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010420 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010421 }
10422
Yue Maef608272013-04-08 23:09:17 -070010423 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010424 {
10425 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010426 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010427 }
10428
10429 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010430 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070010431 {
10432 hddLog(VOS_TRACE_LEVEL_INFO,
10433 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010434 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070010435 (int) scanId);
10436 }
10437
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010438 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010439 pAdapter);
10440
10441 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010442 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010443
10444
10445 /* If any client wait scan result through WEXT
10446 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010447 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070010448 {
10449 /* The other scan request waiting for current scan finish
10450 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010451 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010452 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010453 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070010454 }
10455 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010456 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010457 {
10458 struct net_device *dev = pAdapter->dev;
10459 union iwreq_data wrqu;
10460 int we_event;
10461 char *msg;
10462
10463 memset(&wrqu, '\0', sizeof(wrqu));
10464 we_event = SIOCGIWSCAN;
10465 msg = NULL;
10466 wireless_send_event(dev, we_event, &wrqu, msg);
10467 }
10468 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010469 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010470
10471 /* Get the Scan Req */
10472 req = pAdapter->request;
10473
10474 if (!req)
10475 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010476 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010477 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010478 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010479 }
10480
Jeff Johnson295189b2012-06-20 16:38:30 -070010481 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070010482 /* Scan is no longer pending */
10483 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010484
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010485 /* last_scan_timestamp is used to decide if new scan
10486 * is needed or not on station interface. If last station
10487 * scan time and new station scan time is less then
10488 * last_scan_timestamp ; driver will return cached scan.
10489 */
10490 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
10491 {
10492 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
10493
10494 if ( req->n_channels )
10495 {
10496 for (i = 0; i < req->n_channels ; i++ )
10497 {
10498 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
10499 }
10500 /* store no of channel scanned */
10501 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
10502 }
10503
10504 }
10505
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070010506 /*
10507 * cfg80211_scan_done informing NL80211 about completion
10508 * of scanning
10509 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010510 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
10511 {
10512 aborted = true;
10513 }
10514 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080010515 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010516
Siddharth Bhal76972212014-10-15 16:22:51 +053010517 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
10518 /* Generate new random mac addr for next scan */
10519 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
10520 hdd_processSpoofMacAddrRequest(pHddCtx);
10521 }
10522
Jeff Johnsone7245742012-09-05 17:12:55 -070010523allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010524 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010525 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010526
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010527 /* Acquire wakelock to handle the case where APP's tries to suspend
10528 * immediatly after the driver gets connect request(i.e after scan)
10529 * from supplicant, this result in app's is suspending and not able
10530 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010531 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010532
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010533#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010534 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010535#endif
10536
Jeff Johnson295189b2012-06-20 16:38:30 -070010537 EXIT();
10538 return 0;
10539}
10540
10541/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053010542 * FUNCTION: hdd_isConnectionInProgress
10543 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010544 *
10545 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010546v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010547{
10548 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10549 hdd_station_ctx_t *pHddStaCtx = NULL;
10550 hdd_adapter_t *pAdapter = NULL;
10551 VOS_STATUS status = 0;
10552 v_U8_t staId = 0;
10553 v_U8_t *staMac = NULL;
10554
c_hpothu9b781ba2013-12-30 20:57:45 +053010555 if (TRUE == pHddCtx->btCoexModeSet)
10556 {
10557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053010558 FL("BTCoex Mode operation in progress"));
10559 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053010560 }
10561
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010562 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10563
10564 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10565 {
10566 pAdapter = pAdapterNode->pAdapter;
10567
10568 if( pAdapter )
10569 {
10570 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010571 "%s: Adapter with device mode %s (%d) exists",
10572 __func__, hdd_device_modetoString(pAdapter->device_mode),
10573 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010574 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053010575 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10576 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
10577 (eConnectionState_Connecting ==
10578 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
10579 {
10580 hddLog(VOS_TRACE_LEVEL_ERROR,
10581 "%s: %p(%d) Connection is in progress", __func__,
10582 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10583 return VOS_TRUE;
10584 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010585 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053010586 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010587 {
10588 hddLog(VOS_TRACE_LEVEL_ERROR,
10589 "%s: %p(%d) Reassociation is in progress", __func__,
10590 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10591 return VOS_TRUE;
10592 }
10593 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010594 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10595 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010596 {
10597 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10598 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010599 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010600 {
10601 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
10602 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010603 "%s: client " MAC_ADDRESS_STR
10604 " is in the middle of WPS/EAPOL exchange.", __func__,
10605 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010606 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010607 }
10608 }
10609 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
10610 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
10611 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010612 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10613 ptSapContext pSapCtx = NULL;
10614 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10615 if(pSapCtx == NULL){
10616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10617 FL("psapCtx is NULL"));
10618 return VOS_FALSE;
10619 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010620 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
10621 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010622 if ((pSapCtx->aStaInfo[staId].isUsed) &&
10623 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010624 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010625 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010626
10627 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010628 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
10629 "middle of WPS/EAPOL exchange.", __func__,
10630 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010631 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010632 }
10633 }
10634 }
10635 }
10636 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10637 pAdapterNode = pNext;
10638 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053010639 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010640}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010641
10642/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010643 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070010644 * this scan respond to scan trigger and update cfg80211 scan database
10645 * later, scan dump command can be used to recieve scan results
10646 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010647int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010648#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10649 struct net_device *dev,
10650#endif
10651 struct cfg80211_scan_request *request)
10652{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010653 hdd_adapter_t *pAdapter = NULL;
10654 hdd_context_t *pHddCtx = NULL;
10655 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010656 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010657 tCsrScanRequest scanRequest;
10658 tANI_U8 *channelList = NULL, i;
10659 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010660 int status;
10661 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010662 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010663 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053010664 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010665 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053010666 v_S7_t rssi=0;
10667 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010668
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010669#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
10670 struct net_device *dev = NULL;
10671 if (NULL == request)
10672 {
10673 hddLog(VOS_TRACE_LEVEL_ERROR,
10674 "%s: scan req param null", __func__);
10675 return -EINVAL;
10676 }
10677 dev = request->wdev->netdev;
10678#endif
10679
10680 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
10681 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
10682 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10683
Jeff Johnson295189b2012-06-20 16:38:30 -070010684 ENTER();
10685
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010686 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10687 __func__, hdd_device_modetoString(pAdapter->device_mode),
10688 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010689
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010690 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010691 if (0 != status)
10692 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010693 return status;
10694 }
10695
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010696 if (NULL == pwextBuf)
10697 {
10698 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
10699 __func__);
10700 return -EIO;
10701 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010702 cfg_param = pHddCtx->cfg_ini;
10703 pScanInfo = &pHddCtx->scan_info;
10704
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053010705 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10706 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
10707 {
10708 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
10709 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
10710 }
10711
Jeff Johnson295189b2012-06-20 16:38:30 -070010712#ifdef WLAN_BTAMP_FEATURE
10713 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010714 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070010715 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010716 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010717 "%s: No scanning when AMP is on", __func__);
10718 return -EOPNOTSUPP;
10719 }
10720#endif
10721 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010722 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010723 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010724 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010725 "%s: Not scanning on device_mode = %s (%d)",
10726 __func__, hdd_device_modetoString(pAdapter->device_mode),
10727 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010728 return -EOPNOTSUPP;
10729 }
10730
10731 if (TRUE == pScanInfo->mScanPending)
10732 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010733 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
10734 {
10735 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
10736 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010737 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010738 }
10739
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010740 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070010741 //Channel and action frame is pending
10742 //Otherwise Cancel Remain On Channel and allow Scan
10743 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010744 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070010745 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010746 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010747 return -EBUSY;
10748 }
10749
Jeff Johnson295189b2012-06-20 16:38:30 -070010750 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
10751 {
10752 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080010753 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010754 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010755 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010756 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
10757 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010758 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010759 "%s: MAX TM Level Scan not allowed", __func__);
10760 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010761 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010762 }
10763 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
10764
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010765 /* Check if scan is allowed at this point of time.
10766 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010767 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010768 {
10769 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
10770 return -EBUSY;
10771 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010772
Jeff Johnson295189b2012-06-20 16:38:30 -070010773 vos_mem_zero( &scanRequest, sizeof(scanRequest));
10774
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010775 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
10776 * Becasue of this, driver is assuming that this is not wildcard scan and so
10777 * is not aging out the scan results.
10778 */
10779 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010780 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010781 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010782 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010783
10784 if ((request->ssids) && (0 < request->n_ssids))
10785 {
10786 tCsrSSIDInfo *SsidInfo;
10787 int j;
10788 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
10789 /* Allocate num_ssid tCsrSSIDInfo structure */
10790 SsidInfo = scanRequest.SSIDs.SSIDList =
10791 ( tCsrSSIDInfo *)vos_mem_malloc(
10792 request->n_ssids*sizeof(tCsrSSIDInfo));
10793
10794 if(NULL == scanRequest.SSIDs.SSIDList)
10795 {
10796 hddLog(VOS_TRACE_LEVEL_ERROR,
10797 "%s: memory alloc failed SSIDInfo buffer", __func__);
10798 return -ENOMEM;
10799 }
10800
10801 /* copy all the ssid's and their length */
10802 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
10803 {
10804 /* get the ssid length */
10805 SsidInfo->SSID.length = request->ssids[j].ssid_len;
10806 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
10807 SsidInfo->SSID.length);
10808 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
10809 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
10810 j, SsidInfo->SSID.ssId);
10811 }
10812 /* set the scan type to active */
10813 scanRequest.scanType = eSIR_ACTIVE_SCAN;
10814 }
10815 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070010816 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010817 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10818 TRACE_CODE_HDD_CFG80211_SCAN,
10819 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070010820 /* set the scan type to active */
10821 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010822 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010823 else
10824 {
10825 /*Set the scan type to default type, in this case it is ACTIVE*/
10826 scanRequest.scanType = pScanInfo->scan_mode;
10827 }
10828 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
10829 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070010830
10831 /* set BSSType to default type */
10832 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
10833
10834 /*TODO: scan the requested channels only*/
10835
10836 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010837 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070010838 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010839 hddLog(VOS_TRACE_LEVEL_WARN,
10840 "No of Scan Channels exceeded limit: %d", request->n_channels);
10841 request->n_channels = MAX_CHANNEL;
10842 }
10843
10844 hddLog(VOS_TRACE_LEVEL_INFO,
10845 "No of Scan Channels: %d", request->n_channels);
10846
10847
10848 if( request->n_channels )
10849 {
10850 char chList [(request->n_channels*5)+1];
10851 int len;
10852 channelList = vos_mem_malloc( request->n_channels );
10853 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053010854 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010855 hddLog(VOS_TRACE_LEVEL_ERROR,
10856 "%s: memory alloc failed channelList", __func__);
10857 status = -ENOMEM;
10858 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053010859 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010860
10861 for( i = 0, len = 0; i < request->n_channels ; i++ )
10862 {
10863 channelList[i] = request->channels[i]->hw_value;
10864 len += snprintf(chList+len, 5, "%d ", channelList[i]);
10865 }
10866
Nirav Shah20ac06f2013-12-12 18:14:06 +053010867 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010868 "Channel-List: %s ", chList);
10869 }
c_hpothu53512302014-04-15 18:49:53 +053010870
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010871 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
10872 scanRequest.ChannelInfo.ChannelList = channelList;
10873
10874 /* set requestType to full scan */
10875 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10876
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010877 /* if there is back to back scan happening in driver with in
10878 * nDeferScanTimeInterval interval driver should defer new scan request
10879 * and should provide last cached scan results instead of new channel list.
10880 * This rule is not applicable if scan is p2p scan.
10881 * This condition will work only in case when last request no of channels
10882 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053010883 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053010884 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010885 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010886
Sushant Kaushik86592172015-04-27 16:35:03 +053010887 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
10888 /* if wps ie is NULL , then only defer scan */
10889 if ( pWpsIe == NULL &&
10890 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053010891 {
10892 if ( pScanInfo->last_scan_timestamp !=0 &&
10893 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
10894 {
10895 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
10896 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
10897 vos_mem_compare(pScanInfo->last_scan_channelList,
10898 channelList, pScanInfo->last_scan_numChannels))
10899 {
10900 hddLog(VOS_TRACE_LEVEL_WARN,
10901 " New and old station scan time differ is less then %u",
10902 pHddCtx->cfg_ini->nDeferScanTimeInterval);
10903
10904 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010905 pAdapter);
10906
Agarwal Ashish57e84372014-12-05 18:26:53 +053010907 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010908 "Return old cached scan as all channels and no of channels are same");
10909
Agarwal Ashish57e84372014-12-05 18:26:53 +053010910 if (0 > ret)
10911 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010912
Agarwal Ashish57e84372014-12-05 18:26:53 +053010913 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010914
10915 status = eHAL_STATUS_SUCCESS;
10916 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053010917 }
10918 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010919 }
10920
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010921 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10922 * search (Flush on both full scan and social scan but not on single
10923 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10924 */
10925
10926 /* Supplicant does single channel scan after 8-way handshake
10927 * and in that case driver shoudnt flush scan results. If
10928 * driver flushes the scan results here and unfortunately if
10929 * the AP doesnt respond to our probe req then association
10930 * fails which is not desired
10931 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010932 if ((request->n_ssids == 1)
10933 && (request->ssids != NULL)
10934 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
10935 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010936
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010937 if( is_p2p_scan ||
10938 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010939 {
10940 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
10941 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
10942 pAdapter->sessionId );
10943 }
10944
10945 if( request->ie_len )
10946 {
10947 /* save this for future association (join requires this) */
10948 /*TODO: Array needs to be converted to dynamic allocation,
10949 * as multiple ie.s can be sent in cfg80211_scan_request structure
10950 * CR 597966
10951 */
10952 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
10953 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
10954 pScanInfo->scanAddIE.length = request->ie_len;
10955
10956 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10957 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10958 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010959 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053010960 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070010961 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010962 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
10963 memcpy( pwextBuf->roamProfile.addIEScan,
10964 request->ie, request->ie_len);
10965 }
10966 else
10967 {
10968 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
10969 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070010970 }
10971
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010972 }
10973 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
10974 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
10975
10976 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
10977 request->ie_len);
10978 if (pP2pIe != NULL)
10979 {
10980#ifdef WLAN_FEATURE_P2P_DEBUG
10981 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
10982 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
10983 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053010984 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010985 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
10986 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10987 "Go nego completed to Connection is started");
10988 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10989 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053010990 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010991 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
10992 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010993 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010994 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
10995 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10996 "Disconnected state to Connection is started");
10997 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10998 "for 4way Handshake");
10999 }
11000#endif
11001
11002 /* no_cck will be set during p2p find to disable 11b rates */
11003 if(TRUE == request->no_cck)
11004 {
11005 hddLog(VOS_TRACE_LEVEL_INFO,
11006 "%s: This is a P2P Search", __func__);
11007 scanRequest.p2pSearch = 1;
11008
11009 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053011010 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011011 /* set requestType to P2P Discovery */
11012 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
11013 }
11014
11015 /*
11016 Skip Dfs Channel in case of P2P Search
11017 if it is set in ini file
11018 */
11019 if(cfg_param->skipDfsChnlInP2pSearch)
11020 {
11021 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011022 }
11023 else
11024 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011025 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011026 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011027
Agarwal Ashish4f616132013-12-30 23:32:50 +053011028 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011029 }
11030 }
11031
11032 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
11033
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011034#ifdef FEATURE_WLAN_TDLS
11035 /* if tdls disagree scan right now, return immediately.
11036 tdls will schedule the scan when scan is allowed. (return SUCCESS)
11037 or will reject the scan if any TDLS is in progress. (return -EBUSY)
11038 */
11039 status = wlan_hdd_tdls_scan_callback (pAdapter,
11040 wiphy,
11041#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11042 dev,
11043#endif
11044 request);
11045 if(status <= 0)
11046 {
11047 if(!status)
11048 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
11049 "scan rejected %d", __func__, status);
11050 else
11051 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
11052 __func__, status);
11053
11054 return status;
11055 }
11056#endif
11057
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011058 /* acquire the wakelock to avoid the apps suspend during the scan. To
11059 * address the following issues.
11060 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
11061 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
11062 * for long time, this result in apps running at full power for long time.
11063 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
11064 * be stuck in full power because of resume BMPS
11065 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011066 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011067
Nirav Shah20ac06f2013-12-12 18:14:06 +053011068 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11069 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011070 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
11071 scanRequest.requestType, scanRequest.scanType,
11072 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053011073 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
11074
Siddharth Bhal76972212014-10-15 16:22:51 +053011075 if (pHddCtx->spoofMacAddr.isEnabled)
11076 {
11077 hddLog(VOS_TRACE_LEVEL_INFO,
11078 "%s: MAC Spoofing enabled for current scan", __func__);
11079 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
11080 * to fill TxBds for probe request during current scan
11081 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011082 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053011083 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011084
11085 if(status != VOS_STATUS_SUCCESS)
11086 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011087 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011088 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053011089#ifdef FEATURE_WLAN_TDLS
11090 wlan_hdd_tdls_scan_done_callback(pAdapter);
11091#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011092 goto free_mem;
11093 }
Siddharth Bhal76972212014-10-15 16:22:51 +053011094 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053011095 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070011096 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011097 pAdapter->sessionId, &scanRequest, &scanId,
11098 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070011099
Jeff Johnson295189b2012-06-20 16:38:30 -070011100 if (eHAL_STATUS_SUCCESS != status)
11101 {
11102 hddLog(VOS_TRACE_LEVEL_ERROR,
11103 "%s: sme_ScanRequest returned error %d", __func__, status);
11104 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011105 if(eHAL_STATUS_RESOURCES == status)
11106 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011107 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
11108 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011109 status = -EBUSY;
11110 } else {
11111 status = -EIO;
11112 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011113 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011114
11115#ifdef FEATURE_WLAN_TDLS
11116 wlan_hdd_tdls_scan_done_callback(pAdapter);
11117#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011118 goto free_mem;
11119 }
11120
11121 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011122 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011123 pAdapter->request = request;
11124 pScanInfo->scanId = scanId;
11125
11126 complete(&pScanInfo->scan_req_completion_event);
11127
11128free_mem:
11129 if( scanRequest.SSIDs.SSIDList )
11130 {
11131 vos_mem_free(scanRequest.SSIDs.SSIDList);
11132 }
11133
11134 if( channelList )
11135 vos_mem_free( channelList );
11136
11137 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011138 return status;
11139}
11140
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011141int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
11142#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11143 struct net_device *dev,
11144#endif
11145 struct cfg80211_scan_request *request)
11146{
11147 int ret;
11148
11149 vos_ssr_protect(__func__);
11150 ret = __wlan_hdd_cfg80211_scan(wiphy,
11151#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11152 dev,
11153#endif
11154 request);
11155 vos_ssr_unprotect(__func__);
11156
11157 return ret;
11158}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011159
11160void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
11161{
11162 v_U8_t iniDot11Mode =
11163 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
11164 eHddDot11Mode hddDot11Mode = iniDot11Mode;
11165
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011166 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
11167 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011168 switch ( iniDot11Mode )
11169 {
11170 case eHDD_DOT11_MODE_AUTO:
11171 case eHDD_DOT11_MODE_11ac:
11172 case eHDD_DOT11_MODE_11ac_ONLY:
11173#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053011174 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
11175 sme_IsFeatureSupportedByFW(DOT11AC) )
11176 hddDot11Mode = eHDD_DOT11_MODE_11ac;
11177 else
11178 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011179#else
11180 hddDot11Mode = eHDD_DOT11_MODE_11n;
11181#endif
11182 break;
11183 case eHDD_DOT11_MODE_11n:
11184 case eHDD_DOT11_MODE_11n_ONLY:
11185 hddDot11Mode = eHDD_DOT11_MODE_11n;
11186 break;
11187 default:
11188 hddDot11Mode = iniDot11Mode;
11189 break;
11190 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011191#ifdef WLAN_FEATURE_AP_HT40_24G
11192 if (operationChannel > SIR_11B_CHANNEL_END)
11193#endif
11194 {
11195 /* This call decides required channel bonding mode */
11196 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011197 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
11198 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011199 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011200}
11201
Jeff Johnson295189b2012-06-20 16:38:30 -070011202/*
11203 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011204 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011205 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011206int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011207 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070011208{
11209 int status = 0;
11210 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080011211 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011212 v_U32_t roamId;
11213 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070011214 eCsrAuthType RSNAuthType;
11215
11216 ENTER();
11217
11218 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080011219 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11220
11221 status = wlan_hdd_validate_context(pHddCtx);
11222 if (status)
11223 {
Yue Mae36e3552014-03-05 17:06:20 -080011224 return status;
11225 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011226
Jeff Johnson295189b2012-06-20 16:38:30 -070011227 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
11228 {
11229 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
11230 return -EINVAL;
11231 }
11232
11233 pRoamProfile = &pWextState->roamProfile;
11234
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011235 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070011236 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011237 hdd_station_ctx_t *pHddStaCtx;
11238 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011239
Siddharth Bhalda0d1622015-04-24 15:47:49 +053011240 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
11241
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011242 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070011243 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
11244 {
11245 /*QoS not enabled in cfg file*/
11246 pRoamProfile->uapsd_mask = 0;
11247 }
11248 else
11249 {
11250 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011251 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070011252 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
11253 }
11254
11255 pRoamProfile->SSIDs.numOfSSIDs = 1;
11256 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
11257 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011258 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070011259 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
11260 ssid, ssid_len);
11261
11262 if (bssid)
11263 {
11264 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
11265 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
11266 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011267 /* Save BSSID in seperate variable as well, as RoamProfile
11268 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070011269 case of join failure we should send valid BSSID to supplicant
11270 */
11271 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
11272 WNI_CFG_BSSID_LEN);
11273 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070011274 else
11275 {
11276 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
11277 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011278
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011279 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
11280 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011281 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
11282 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011283 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011284 /*set gen ie*/
11285 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
11286 /*set auth*/
11287 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
11288 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011289#ifdef FEATURE_WLAN_WAPI
11290 if (pAdapter->wapi_info.nWapiMode)
11291 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011292 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011293 switch (pAdapter->wapi_info.wapiAuthMode)
11294 {
11295 case WAPI_AUTH_MODE_PSK:
11296 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011297 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011298 pAdapter->wapi_info.wapiAuthMode);
11299 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
11300 break;
11301 }
11302 case WAPI_AUTH_MODE_CERT:
11303 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011304 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011305 pAdapter->wapi_info.wapiAuthMode);
11306 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
11307 break;
11308 }
11309 } // End of switch
11310 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
11311 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
11312 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011313 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011314 pRoamProfile->AuthType.numEntries = 1;
11315 pRoamProfile->EncryptionType.numEntries = 1;
11316 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11317 pRoamProfile->mcEncryptionType.numEntries = 1;
11318 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11319 }
11320 }
11321#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011322#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011323 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011324 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11325 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
11326 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011327 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
11328 sizeof (tSirGtkOffloadParams));
11329 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011330 }
11331#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011332 pRoamProfile->csrPersona = pAdapter->device_mode;
11333
Jeff Johnson32d95a32012-09-10 13:15:23 -070011334 if( operatingChannel )
11335 {
11336 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
11337 pRoamProfile->ChannelInfo.numOfChannels = 1;
11338 }
Chet Lanctot186b5732013-03-18 10:26:30 -070011339 else
11340 {
11341 pRoamProfile->ChannelInfo.ChannelList = NULL;
11342 pRoamProfile->ChannelInfo.numOfChannels = 0;
11343 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011344 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
11345 {
11346 hdd_select_cbmode(pAdapter,operatingChannel);
11347 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011348
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011349 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
11350 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011351 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011352 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011353 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
11354 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011355 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11356 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053011357 {
11358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11359 "%s: Set HDD connState to eConnectionState_Connecting",
11360 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011361 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
11362 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053011363 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011364 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011365 pAdapter->sessionId, pRoamProfile, &roamId);
11366
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011367 if ((eHAL_STATUS_SUCCESS != status) &&
11368 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11369 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011370
11371 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011372 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
11373 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
11374 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011375 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011376 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011377 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011378
11379 pRoamProfile->ChannelInfo.ChannelList = NULL;
11380 pRoamProfile->ChannelInfo.numOfChannels = 0;
11381
Jeff Johnson295189b2012-06-20 16:38:30 -070011382 }
11383 else
11384 {
11385 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
11386 return -EINVAL;
11387 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011388 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011389 return status;
11390}
11391
11392/*
11393 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
11394 * This function is used to set the authentication type (OPEN/SHARED).
11395 *
11396 */
11397static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
11398 enum nl80211_auth_type auth_type)
11399{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011400 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011401 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11402
11403 ENTER();
11404
11405 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011406 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070011407 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011408 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011409 hddLog(VOS_TRACE_LEVEL_INFO,
11410 "%s: set authentication type to AUTOSWITCH", __func__);
11411 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
11412 break;
11413
11414 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011415#ifdef WLAN_FEATURE_VOWIFI_11R
11416 case NL80211_AUTHTYPE_FT:
11417#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011418 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011419 "%s: set authentication type to OPEN", __func__);
11420 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11421 break;
11422
11423 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011424 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011425 "%s: set authentication type to SHARED", __func__);
11426 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
11427 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011428#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011429 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011430 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011431 "%s: set authentication type to CCKM WPA", __func__);
11432 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
11433 break;
11434#endif
11435
11436
11437 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011438 hddLog(VOS_TRACE_LEVEL_ERROR,
11439 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011440 auth_type);
11441 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
11442 return -EINVAL;
11443 }
11444
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011445 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011446 pHddStaCtx->conn_info.authType;
11447 return 0;
11448}
11449
11450/*
11451 * FUNCTION: wlan_hdd_set_akm_suite
11452 * This function is used to set the key mgmt type(PSK/8021x).
11453 *
11454 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011455static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011456 u32 key_mgmt
11457 )
11458{
11459 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11460 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053011461 /* Should be in ieee802_11_defs.h */
11462#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
11463#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070011464 /*set key mgmt type*/
11465 switch(key_mgmt)
11466 {
11467 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053011468 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011469#ifdef WLAN_FEATURE_VOWIFI_11R
11470 case WLAN_AKM_SUITE_FT_PSK:
11471#endif
11472 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070011473 __func__);
11474 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
11475 break;
11476
11477 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053011478 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011479#ifdef WLAN_FEATURE_VOWIFI_11R
11480 case WLAN_AKM_SUITE_FT_8021X:
11481#endif
11482 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070011483 __func__);
11484 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11485 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011486#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011487#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
11488#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
11489 case WLAN_AKM_SUITE_CCKM:
11490 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
11491 __func__);
11492 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
11493 break;
11494#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070011495#ifndef WLAN_AKM_SUITE_OSEN
11496#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
11497 case WLAN_AKM_SUITE_OSEN:
11498 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
11499 __func__);
11500 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11501 break;
11502#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011503
11504 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011505 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011506 __func__, key_mgmt);
11507 return -EINVAL;
11508
11509 }
11510 return 0;
11511}
11512
11513/*
11514 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011515 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070011516 * (NONE/WEP40/WEP104/TKIP/CCMP).
11517 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011518static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
11519 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070011520 bool ucast
11521 )
11522{
11523 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011524 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011525 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11526
11527 ENTER();
11528
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011529 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011530 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011531 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070011532 __func__, cipher);
11533 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11534 }
11535 else
11536 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011537
Jeff Johnson295189b2012-06-20 16:38:30 -070011538 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011539 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011540 {
11541 case IW_AUTH_CIPHER_NONE:
11542 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11543 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011544
Jeff Johnson295189b2012-06-20 16:38:30 -070011545 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011546 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070011547 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011548
Jeff Johnson295189b2012-06-20 16:38:30 -070011549 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011550 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070011551 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011552
Jeff Johnson295189b2012-06-20 16:38:30 -070011553 case WLAN_CIPHER_SUITE_TKIP:
11554 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
11555 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011556
Jeff Johnson295189b2012-06-20 16:38:30 -070011557 case WLAN_CIPHER_SUITE_CCMP:
11558 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11559 break;
11560#ifdef FEATURE_WLAN_WAPI
11561 case WLAN_CIPHER_SUITE_SMS4:
11562 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
11563 break;
11564#endif
11565
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011566#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011567 case WLAN_CIPHER_SUITE_KRK:
11568 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
11569 break;
11570#endif
11571 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011572 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011573 __func__, cipher);
11574 return -EOPNOTSUPP;
11575 }
11576 }
11577
11578 if (ucast)
11579 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011580 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011581 __func__, encryptionType);
11582 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11583 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011584 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011585 encryptionType;
11586 }
11587 else
11588 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011589 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011590 __func__, encryptionType);
11591 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
11592 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
11593 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
11594 }
11595
11596 return 0;
11597}
11598
11599
11600/*
11601 * FUNCTION: wlan_hdd_cfg80211_set_ie
11602 * This function is used to parse WPA/RSN IE's.
11603 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011604int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
11605 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070011606 size_t ie_len
11607 )
11608{
11609 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11610 u8 *genie = ie;
11611 v_U16_t remLen = ie_len;
11612#ifdef FEATURE_WLAN_WAPI
11613 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
11614 u16 *tmp;
11615 v_U16_t akmsuiteCount;
11616 int *akmlist;
11617#endif
11618 ENTER();
11619
11620 /* clear previous assocAddIE */
11621 pWextState->assocAddIE.length = 0;
11622 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011623 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011624
11625 while (remLen >= 2)
11626 {
11627 v_U16_t eLen = 0;
11628 v_U8_t elementId;
11629 elementId = *genie++;
11630 eLen = *genie++;
11631 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011632
Arif Hussain6d2a3322013-11-17 19:50:10 -080011633 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070011634 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011635
11636 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070011637 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011638 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011639 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 -070011640 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011641 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011642 "%s: Invalid WPA IE", __func__);
11643 return -EINVAL;
11644 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011645 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070011646 {
11647 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011648 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011649 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011650
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011651 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011652 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011653 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
11654 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011655 VOS_ASSERT(0);
11656 return -ENOMEM;
11657 }
11658 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11659 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11660 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011661
Jeff Johnson295189b2012-06-20 16:38:30 -070011662 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
11663 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11664 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11665 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011666 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
11667 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011668 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
11669 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11670 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
11671 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
11672 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
11673 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011674 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053011675 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011676 {
11677 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011678 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011679 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011680
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011681 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011682 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011683 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11684 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011685 VOS_ASSERT(0);
11686 return -ENOMEM;
11687 }
11688 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11689 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11690 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011691
Jeff Johnson295189b2012-06-20 16:38:30 -070011692 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11693 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11694 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011695#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011696 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
11697 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011698 /*Consider WFD IE, only for P2P Client */
11699 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11700 {
11701 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011702 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011703 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011704
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011705 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011706 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011707 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11708 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011709 VOS_ASSERT(0);
11710 return -ENOMEM;
11711 }
11712 // WFD IE is saved to Additional IE ; it should be accumulated to handle
11713 // WPS IE + P2P IE + WFD IE
11714 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11715 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011716
Jeff Johnson295189b2012-06-20 16:38:30 -070011717 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11718 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11719 }
11720#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011721 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011722 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011723 HS20_OUI_TYPE_SIZE)) )
11724 {
11725 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011726 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011727 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011728
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011729 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011730 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011731 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11732 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011733 VOS_ASSERT(0);
11734 return -ENOMEM;
11735 }
11736 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11737 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011738
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011739 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11740 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11741 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011742 /* Appending OSEN Information Element in Assiciation Request */
11743 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
11744 OSEN_OUI_TYPE_SIZE)) )
11745 {
11746 v_U16_t curAddIELen = pWextState->assocAddIE.length;
11747 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
11748 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011749
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011750 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011751 {
11752 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11753 "Need bigger buffer space");
11754 VOS_ASSERT(0);
11755 return -ENOMEM;
11756 }
11757 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11758 pWextState->assocAddIE.length += eLen + 2;
11759
11760 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
11761 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11762 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11763 }
11764
Abhishek Singh4322e622015-06-10 15:42:54 +053011765 /* Update only for WPA IE */
11766 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
11767 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070011768
11769 /* populating as ADDIE in beacon frames */
11770 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11771 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
11772 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
11773 {
11774 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11775 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
11776 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11777 {
11778 hddLog(LOGE,
11779 "Coldn't pass "
11780 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
11781 }
11782 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
11783 else
11784 hddLog(LOGE,
11785 "Could not pass on "
11786 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
11787
11788 /* IBSS mode doesn't contain params->proberesp_ies still
11789 beaconIE's need to be populated in probe response frames */
11790 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
11791 {
11792 u16 rem_probe_resp_ie_len = eLen + 2;
11793 u8 probe_rsp_ie_len[3] = {0};
11794 u8 counter = 0;
11795
11796 /* Check Probe Resp Length if it is greater then 255 then
11797 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
11798 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
11799 not able Store More then 255 bytes into One Variable */
11800
11801 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
11802 {
11803 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
11804 {
11805 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
11806 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
11807 }
11808 else
11809 {
11810 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
11811 rem_probe_resp_ie_len = 0;
11812 }
11813 }
11814
11815 rem_probe_resp_ie_len = 0;
11816
11817 if (probe_rsp_ie_len[0] > 0)
11818 {
11819 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11820 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
11821 (tANI_U8*)(genie - 2),
11822 probe_rsp_ie_len[0], NULL,
11823 eANI_BOOLEAN_FALSE)
11824 == eHAL_STATUS_FAILURE)
11825 {
11826 hddLog(LOGE,
11827 "Could not pass"
11828 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
11829 }
11830 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
11831 }
11832
11833 if (probe_rsp_ie_len[1] > 0)
11834 {
11835 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11836 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
11837 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11838 probe_rsp_ie_len[1], NULL,
11839 eANI_BOOLEAN_FALSE)
11840 == eHAL_STATUS_FAILURE)
11841 {
11842 hddLog(LOGE,
11843 "Could not pass"
11844 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
11845 }
11846 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
11847 }
11848
11849 if (probe_rsp_ie_len[2] > 0)
11850 {
11851 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11852 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
11853 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11854 probe_rsp_ie_len[2], NULL,
11855 eANI_BOOLEAN_FALSE)
11856 == eHAL_STATUS_FAILURE)
11857 {
11858 hddLog(LOGE,
11859 "Could not pass"
11860 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
11861 }
11862 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
11863 }
11864
11865 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11866 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
11867 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11868 {
11869 hddLog(LOGE,
11870 "Could not pass"
11871 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
11872 }
11873 }
11874 else
11875 {
11876 // Reset WNI_CFG_PROBE_RSP Flags
11877 wlan_hdd_reset_prob_rspies(pAdapter);
11878
11879 hddLog(VOS_TRACE_LEVEL_INFO,
11880 "%s: No Probe Response IE received in set beacon",
11881 __func__);
11882 }
11883 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011884 break;
11885 case DOT11F_EID_RSN:
11886 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
11887 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11888 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
11889 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
11890 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
11891 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053011892
11893 /* Appending Extended Capabilities with Interworking bit set
11894 * in Assoc Req.
11895 *
11896 * In assoc req this EXT Cap will only be taken into account if
11897 * interworkingService bit is set to 1. Currently
11898 * driver is only interested in interworkingService capability
11899 * from supplicant. If in future any other EXT Cap info is
11900 * required from supplicat, it needs to be handled while
11901 * sending Assoc Req in LIM.
11902 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011903 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011904 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011905 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011906 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011907 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011908
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011909 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011910 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011911 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11912 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011913 VOS_ASSERT(0);
11914 return -ENOMEM;
11915 }
11916 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11917 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011918
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011919 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11920 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11921 break;
11922 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011923#ifdef FEATURE_WLAN_WAPI
11924 case WLAN_EID_WAPI:
11925 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011926 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011927 pAdapter->wapi_info.nWapiMode);
11928 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011929 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070011930 akmsuiteCount = WPA_GET_LE16(tmp);
11931 tmp = tmp + 1;
11932 akmlist = (int *)(tmp);
11933 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
11934 {
11935 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
11936 }
11937 else
11938 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011939 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070011940 VOS_ASSERT(0);
11941 return -EINVAL;
11942 }
11943
11944 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
11945 {
11946 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011947 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011948 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011949 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011950 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011951 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011952 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011953 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011954 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
11955 }
11956 break;
11957#endif
11958 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011959 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011960 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011961 /* when Unknown IE is received we should break and continue
11962 * to the next IE in the buffer instead we were returning
11963 * so changing this to break */
11964 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011965 }
11966 genie += eLen;
11967 remLen -= eLen;
11968 }
11969 EXIT();
11970 return 0;
11971}
11972
11973/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053011974 * FUNCTION: hdd_isWPAIEPresent
11975 * Parse the received IE to find the WPA IE
11976 *
11977 */
11978static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
11979{
11980 v_U8_t eLen = 0;
11981 v_U16_t remLen = ie_len;
11982 v_U8_t elementId = 0;
11983
11984 while (remLen >= 2)
11985 {
11986 elementId = *ie++;
11987 eLen = *ie++;
11988 remLen -= 2;
11989 if (eLen > remLen)
11990 {
11991 hddLog(VOS_TRACE_LEVEL_ERROR,
11992 "%s: IE length is wrong %d", __func__, eLen);
11993 return FALSE;
11994 }
11995 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
11996 {
11997 /* OUI - 0x00 0X50 0XF2
11998 WPA Information Element - 0x01
11999 WPA version - 0x01*/
12000 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
12001 return TRUE;
12002 }
12003 ie += eLen;
12004 remLen -= eLen;
12005 }
12006 return FALSE;
12007}
12008
12009/*
Jeff Johnson295189b2012-06-20 16:38:30 -070012010 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012011 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012012 * parameters during connect operation.
12013 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012014int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012015 struct cfg80211_connect_params *req
12016 )
12017{
12018 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012019 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012020 ENTER();
12021
12022 /*set wpa version*/
12023 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
12024
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012025 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012026 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053012027 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012028 {
12029 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12030 }
12031 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
12032 {
12033 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12034 }
12035 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012036
12037 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012038 pWextState->wpaVersion);
12039
12040 /*set authentication type*/
12041 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
12042
12043 if (0 > status)
12044 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012045 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012046 "%s: failed to set authentication type ", __func__);
12047 return status;
12048 }
12049
12050 /*set key mgmt type*/
12051 if (req->crypto.n_akm_suites)
12052 {
12053 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
12054 if (0 > status)
12055 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012056 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070012057 __func__);
12058 return status;
12059 }
12060 }
12061
12062 /*set pairwise cipher type*/
12063 if (req->crypto.n_ciphers_pairwise)
12064 {
12065 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
12066 req->crypto.ciphers_pairwise[0], true);
12067 if (0 > status)
12068 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012069 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012070 "%s: failed to set unicast cipher type", __func__);
12071 return status;
12072 }
12073 }
12074 else
12075 {
12076 /*Reset previous cipher suite to none*/
12077 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
12078 if (0 > status)
12079 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012080 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012081 "%s: failed to set unicast cipher type", __func__);
12082 return status;
12083 }
12084 }
12085
12086 /*set group cipher type*/
12087 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
12088 false);
12089
12090 if (0 > status)
12091 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012092 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070012093 __func__);
12094 return status;
12095 }
12096
Chet Lanctot186b5732013-03-18 10:26:30 -070012097#ifdef WLAN_FEATURE_11W
12098 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
12099#endif
12100
Jeff Johnson295189b2012-06-20 16:38:30 -070012101 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
12102 if (req->ie_len)
12103 {
12104 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
12105 if ( 0 > status)
12106 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012107 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012108 __func__);
12109 return status;
12110 }
12111 }
12112
12113 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012114 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012115 {
12116 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
12117 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
12118 )
12119 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012120 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070012121 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
12122 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012123 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012124 __func__);
12125 return -EOPNOTSUPP;
12126 }
12127 else
12128 {
12129 u8 key_len = req->key_len;
12130 u8 key_idx = req->key_idx;
12131
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012132 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012133 && (CSR_MAX_NUM_KEY > key_idx)
12134 )
12135 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012136 hddLog(VOS_TRACE_LEVEL_INFO,
12137 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012138 __func__, key_idx, key_len);
12139 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012140 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012141 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012142 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012143 (u8)key_len;
12144 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
12145 }
12146 }
12147 }
12148 }
12149
12150 return status;
12151}
12152
12153/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012154 * FUNCTION: wlan_hdd_try_disconnect
12155 * This function is used to disconnect from previous
12156 * connection
12157 */
12158static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
12159{
12160 long ret = 0;
12161 hdd_station_ctx_t *pHddStaCtx;
12162 eMib_dot11DesiredBssType connectedBssType;
12163
12164 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12165
12166 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
12167
12168 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
12169 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
12170 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
12171 {
12172 /* Issue disconnect to CSR */
12173 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12174 if( eHAL_STATUS_SUCCESS ==
12175 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12176 pAdapter->sessionId,
12177 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12178 {
12179 ret = wait_for_completion_interruptible_timeout(
12180 &pAdapter->disconnect_comp_var,
12181 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12182 if (0 >= ret)
12183 {
12184 hddLog(LOGE, FL("Failed to receive disconnect event"));
12185 return -EALREADY;
12186 }
12187 }
12188 }
12189 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
12190 {
12191 ret = wait_for_completion_interruptible_timeout(
12192 &pAdapter->disconnect_comp_var,
12193 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12194 if (0 >= ret)
12195 {
12196 hddLog(LOGE, FL("Failed to receive disconnect event"));
12197 return -EALREADY;
12198 }
12199 }
12200
12201 return 0;
12202}
12203
12204/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053012205 * FUNCTION: __wlan_hdd_cfg80211_connect
12206 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070012207 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012208static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012209 struct net_device *ndev,
12210 struct cfg80211_connect_params *req
12211 )
12212{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012213 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012214 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012215 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053012216 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012217
12218 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012219
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012220 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12221 TRACE_CODE_HDD_CFG80211_CONNECT,
12222 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012223 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012224 "%s: device_mode = %s (%d)", __func__,
12225 hdd_device_modetoString(pAdapter->device_mode),
12226 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012227
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012228 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012229 if (!pHddCtx)
12230 {
12231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12232 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053012233 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012234 }
12235
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012236 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012237 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012238 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012239 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012240 }
12241
Agarwal Ashish51325b52014-06-16 16:50:49 +053012242 if (vos_max_concurrent_connections_reached()) {
12243 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12244 return -ECONNREFUSED;
12245 }
12246
Jeff Johnson295189b2012-06-20 16:38:30 -070012247#ifdef WLAN_BTAMP_FEATURE
12248 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012249 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070012250 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012251 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012252 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012253 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070012254 }
12255#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012256
12257 //If Device Mode is Station Concurrent Sessions Exit BMps
12258 //P2P Mode will be taken care in Open/close adapter
12259 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012260 (vos_concurrent_open_sessions_running())) {
12261 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
12262 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012263 }
12264
12265 /*Try disconnecting if already in connected state*/
12266 status = wlan_hdd_try_disconnect(pAdapter);
12267 if ( 0 > status)
12268 {
12269 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12270 " connection"));
12271 return -EALREADY;
12272 }
12273
Jeff Johnson295189b2012-06-20 16:38:30 -070012274 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012275 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070012276
12277 if ( 0 > status)
12278 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012279 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070012280 __func__);
12281 return status;
12282 }
Mohit Khanna765234a2012-09-11 15:08:35 -070012283 if ( req->channel )
12284 {
12285 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
12286 req->ssid_len, req->bssid,
12287 req->channel->hw_value);
12288 }
12289 else
12290 {
12291 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012292 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070012293 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012294
Sushant Kaushikd7083982015-03-18 14:33:24 +053012295 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012296 {
12297 //ReEnable BMPS if disabled
12298 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
12299 (NULL != pHddCtx))
12300 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012301 if (pHddCtx->hdd_wlan_suspended)
12302 {
12303 hdd_set_pwrparams(pHddCtx);
12304 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012305 //ReEnable Bmps and Imps back
12306 hdd_enable_bmps_imps(pHddCtx);
12307 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053012308 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070012309 return status;
12310 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012311 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012312 EXIT();
12313 return status;
12314}
12315
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012316static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
12317 struct net_device *ndev,
12318 struct cfg80211_connect_params *req)
12319{
12320 int ret;
12321 vos_ssr_protect(__func__);
12322 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
12323 vos_ssr_unprotect(__func__);
12324
12325 return ret;
12326}
Jeff Johnson295189b2012-06-20 16:38:30 -070012327
12328/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012329 * FUNCTION: wlan_hdd_disconnect
12330 * This function is used to issue a disconnect request to SME
12331 */
12332int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
12333{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012334 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012335 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012336 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012337 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012338
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012339 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012340
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012341 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012342 if (0 != status)
12343 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012344 return status;
12345 }
12346
Sushant Kaushikb4834d22015-07-15 15:29:05 +053012347 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
12348 {
12349 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
12350 pAdapter->sessionId);
12351 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012352 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012353
Agarwal Ashish47d18112014-08-04 19:55:07 +053012354 /* Need to apply spin lock before decreasing active sessions
12355 * as there can be chance for double decrement if context switch
12356 * Calls hdd_DisConnectHandler.
12357 */
12358
12359 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012360 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
12361 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012362 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
12363 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053012364 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
12365 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012366
Abhishek Singhf4669da2014-05-26 15:07:49 +053012367 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053012368 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
12369
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012370 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012371
Mihir Shete182a0b22014-08-18 16:08:48 +053012372 /*
12373 * stop tx queues before deleting STA/BSS context from the firmware.
12374 * tx has to be disabled because the firmware can get busy dropping
12375 * the tx frames after BSS/STA has been deleted and will not send
12376 * back a response resulting in WDI timeout
12377 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053012378 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053012379 netif_tx_disable(pAdapter->dev);
12380 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012381
Mihir Shete182a0b22014-08-18 16:08:48 +053012382 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012383 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12384 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012385 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
12386 {
12387 hddLog(VOS_TRACE_LEVEL_INFO,
12388 FL("status = %d, already disconnected"),
12389 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012390
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012391 }
12392 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012393 {
12394 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012395 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012396 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012397 result = -EINVAL;
12398 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012399 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012400 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012401 &pAdapter->disconnect_comp_var,
12402 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012403 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012404 {
12405 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012406 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012407 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012408 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012409 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012410 {
12411 hddLog(VOS_TRACE_LEVEL_ERROR,
12412 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012413 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012414 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012415disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12417 FL("Set HDD connState to eConnectionState_NotConnected"));
12418 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
12419
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012420 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012421 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012422}
12423
12424
12425/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012426 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070012427 * This function is used to issue a disconnect request to SME
12428 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012429static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012430 struct net_device *dev,
12431 u16 reason
12432 )
12433{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012434 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012435 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012436 tCsrRoamProfile *pRoamProfile;
12437 hdd_station_ctx_t *pHddStaCtx;
12438 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012439#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012440 tANI_U8 staIdx;
12441#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012442
Jeff Johnson295189b2012-06-20 16:38:30 -070012443 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012444
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012445 if (!pAdapter) {
12446 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
12447 return -EINVAL;
12448 }
12449
12450 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12451 if (!pHddStaCtx) {
12452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
12453 return -EINVAL;
12454 }
12455
12456 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12457 status = wlan_hdd_validate_context(pHddCtx);
12458 if (0 != status)
12459 {
12460 return status;
12461 }
12462
12463 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
12464
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012465 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12466 TRACE_CODE_HDD_CFG80211_DISCONNECT,
12467 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012468 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
12469 __func__, hdd_device_modetoString(pAdapter->device_mode),
12470 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012471
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012472 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
12473 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070012474
Jeff Johnson295189b2012-06-20 16:38:30 -070012475 if (NULL != pRoamProfile)
12476 {
12477 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012478 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
12479 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070012480 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012481 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070012482 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012483 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012484 switch(reason)
12485 {
12486 case WLAN_REASON_MIC_FAILURE:
12487 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
12488 break;
12489
12490 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
12491 case WLAN_REASON_DISASSOC_AP_BUSY:
12492 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
12493 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
12494 break;
12495
12496 case WLAN_REASON_PREV_AUTH_NOT_VALID:
12497 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053012498 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070012499 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
12500 break;
12501
Jeff Johnson295189b2012-06-20 16:38:30 -070012502 default:
12503 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
12504 break;
12505 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012506 pScanInfo = &pHddCtx->scan_info;
12507 if (pScanInfo->mScanPending)
12508 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012509 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012510 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012511 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012512 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012513 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012514
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012515#ifdef FEATURE_WLAN_TDLS
12516 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012517 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012518 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012519 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
12520 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012521 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012522 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012523 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012525 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012526 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012527 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012528 status = sme_DeleteTdlsPeerSta(
12529 WLAN_HDD_GET_HAL_CTX(pAdapter),
12530 pAdapter->sessionId,
12531 mac);
12532 if (status != eHAL_STATUS_SUCCESS) {
12533 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
12534 return -EPERM;
12535 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012536 }
12537 }
12538#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012539 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012540 status = wlan_hdd_disconnect(pAdapter, reasonCode);
12541 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070012542 {
12543 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012544 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012545 __func__, (int)status );
12546 return -EINVAL;
12547 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012548 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012549 else
12550 {
12551 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
12552 "called while in %d state", __func__,
12553 pHddStaCtx->conn_info.connState);
12554 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012555 }
12556 else
12557 {
12558 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
12559 }
12560
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012561 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012562 return status;
12563}
12564
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012565static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
12566 struct net_device *dev,
12567 u16 reason
12568 )
12569{
12570 int ret;
12571 vos_ssr_protect(__func__);
12572 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
12573 vos_ssr_unprotect(__func__);
12574
12575 return ret;
12576}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012577
Jeff Johnson295189b2012-06-20 16:38:30 -070012578/*
12579 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012580 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012581 * settings in IBSS mode.
12582 */
12583static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012584 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012585 struct cfg80211_ibss_params *params
12586 )
12587{
12588 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012589 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012590 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12591 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012592
Jeff Johnson295189b2012-06-20 16:38:30 -070012593 ENTER();
12594
12595 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070012596 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070012597
12598 if (params->ie_len && ( NULL != params->ie) )
12599 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012600 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12601 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012602 {
12603 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12604 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12605 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012606 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012607 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012608 tDot11fIEWPA dot11WPAIE;
12609 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012610 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012611
Wilson Yang00256342013-10-10 23:13:38 -070012612 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012613 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12614 params->ie_len, DOT11F_EID_WPA);
12615 if ( NULL != ie )
12616 {
12617 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12618 // Unpack the WPA IE
12619 //Skip past the EID byte and length byte - and four byte WiFi OUI
12620 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
12621 &ie[2+4],
12622 ie[1] - 4,
12623 &dot11WPAIE);
12624 /*Extract the multicast cipher, the encType for unicast
12625 cipher for wpa-none is none*/
12626 encryptionType =
12627 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
12628 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012629 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012630
Jeff Johnson295189b2012-06-20 16:38:30 -070012631 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
12632
12633 if (0 > status)
12634 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012635 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012636 __func__);
12637 return status;
12638 }
12639 }
12640
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012641 pWextState->roamProfile.AuthType.authType[0] =
12642 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012643 eCSR_AUTH_TYPE_OPEN_SYSTEM;
12644
12645 if (params->privacy)
12646 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012647 /* Security enabled IBSS, At this time there is no information available
12648 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070012649 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012650 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070012651 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012652 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070012653 *enable privacy bit in beacons */
12654
12655 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12656 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012657 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
12658 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070012659 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12660 pWextState->roamProfile.EncryptionType.numEntries = 1;
12661 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070012662 return status;
12663}
12664
12665/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012666 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012667 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012668 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012669static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012670 struct net_device *dev,
12671 struct cfg80211_ibss_params *params
12672 )
12673{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012674 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012675 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12676 tCsrRoamProfile *pRoamProfile;
12677 int status;
krunal sonie9002db2013-11-25 14:24:17 -080012678 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012679 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12680 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012681
12682 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012683
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012684 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12685 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
12686 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012687 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012688 "%s: device_mode = %s (%d)", __func__,
12689 hdd_device_modetoString(pAdapter->device_mode),
12690 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012691
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012692 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012693 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012694 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012695 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012696 }
12697
12698 if (NULL == pWextState)
12699 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012700 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012701 __func__);
12702 return -EIO;
12703 }
12704
Agarwal Ashish51325b52014-06-16 16:50:49 +053012705 if (vos_max_concurrent_connections_reached()) {
12706 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12707 return -ECONNREFUSED;
12708 }
12709
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012710 /*Try disconnecting if already in connected state*/
12711 status = wlan_hdd_try_disconnect(pAdapter);
12712 if ( 0 > status)
12713 {
12714 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12715 " IBSS connection"));
12716 return -EALREADY;
12717 }
12718
Jeff Johnson295189b2012-06-20 16:38:30 -070012719 pRoamProfile = &pWextState->roamProfile;
12720
12721 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
12722 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012723 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012724 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012725 return -EINVAL;
12726 }
12727
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012728 /* BSSID is provided by upper layers hence no need to AUTO generate */
12729 if (NULL != params->bssid) {
12730 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12731 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
12732 hddLog (VOS_TRACE_LEVEL_ERROR,
12733 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12734 return -EIO;
12735 }
12736 }
krunal sonie9002db2013-11-25 14:24:17 -080012737 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
12738 {
12739 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12740 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
12741 {
12742 hddLog (VOS_TRACE_LEVEL_ERROR,
12743 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12744 return -EIO;
12745 }
Sachin Ahuja46ff4912015-03-23 22:48:43 +053012746 params->bssid = vos_mem_malloc(VOS_MAC_ADDR_SIZE);
krunal sonie9002db2013-11-25 14:24:17 -080012747 if (!params->bssid)
12748 {
12749 hddLog (VOS_TRACE_LEVEL_ERROR,
12750 "%s:Failed memory allocation", __func__);
12751 return -EIO;
12752 }
12753 vos_mem_copy((v_U8_t *)params->bssid,
12754 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
12755 VOS_MAC_ADDR_SIZE);
12756 alloc_bssid = VOS_TRUE;
12757 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012758
Jeff Johnson295189b2012-06-20 16:38:30 -070012759 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070012760 if (NULL !=
12761#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12762 params->chandef.chan)
12763#else
12764 params->channel)
12765#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012766 {
12767 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012768 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12769 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
12770 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12771 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012772
12773 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012774 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070012775 ieee80211_frequency_to_channel(
12776#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12777 params->chandef.chan->center_freq);
12778#else
12779 params->channel->center_freq);
12780#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012781
12782 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12783 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070012784 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012785 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
12786 __func__);
12787 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012788 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012789
12790 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012791 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012792 if (channelNum == validChan[indx])
12793 {
12794 break;
12795 }
12796 }
12797 if (indx >= numChans)
12798 {
12799 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012800 __func__, channelNum);
12801 return -EINVAL;
12802 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012803 /* Set the Operational Channel */
12804 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
12805 channelNum);
12806 pRoamProfile->ChannelInfo.numOfChannels = 1;
12807 pHddStaCtx->conn_info.operationChannel = channelNum;
12808 pRoamProfile->ChannelInfo.ChannelList =
12809 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070012810 }
12811
12812 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012813 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070012814 if (status < 0)
12815 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012816 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070012817 __func__);
12818 return status;
12819 }
12820
12821 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012822 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012823 params->ssid_len, params->bssid,
12824 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012825
12826 if (0 > status)
12827 {
12828 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
12829 return status;
12830 }
12831
krunal sonie9002db2013-11-25 14:24:17 -080012832 if (NULL != params->bssid &&
12833 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
12834 alloc_bssid == VOS_TRUE)
12835 {
12836 vos_mem_free(params->bssid);
12837 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012838 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012839 return 0;
12840}
12841
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012842static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
12843 struct net_device *dev,
12844 struct cfg80211_ibss_params *params
12845 )
12846{
12847 int ret = 0;
12848
12849 vos_ssr_protect(__func__);
12850 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
12851 vos_ssr_unprotect(__func__);
12852
12853 return ret;
12854}
12855
Jeff Johnson295189b2012-06-20 16:38:30 -070012856/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012857 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012858 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012859 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012860static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012861 struct net_device *dev
12862 )
12863{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012864 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012865 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12866 tCsrRoamProfile *pRoamProfile;
12867 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012868 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012869
12870 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012871
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012872 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12873 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
12874 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012875 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012876 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012877 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012878 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012879 }
12880
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012881 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
12882 hdd_device_modetoString(pAdapter->device_mode),
12883 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012884 if (NULL == pWextState)
12885 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012886 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012887 __func__);
12888 return -EIO;
12889 }
12890
12891 pRoamProfile = &pWextState->roamProfile;
12892
12893 /* Issue disconnect only if interface type is set to IBSS */
12894 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
12895 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012896 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070012897 __func__);
12898 return -EINVAL;
12899 }
12900
12901 /* Issue Disconnect request */
12902 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12903 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12904 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
12905
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012906 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012907 return 0;
12908}
12909
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012910static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
12911 struct net_device *dev
12912 )
12913{
12914 int ret = 0;
12915
12916 vos_ssr_protect(__func__);
12917 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
12918 vos_ssr_unprotect(__func__);
12919
12920 return ret;
12921}
12922
Jeff Johnson295189b2012-06-20 16:38:30 -070012923/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012924 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070012925 * This function is used to set the phy parameters
12926 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
12927 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012928static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012929 u32 changed)
12930{
12931 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
12932 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012933 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012934
12935 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012936
12937 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012938 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
12939 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012940
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012941 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012942 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012943 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012944 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012945 }
12946
Jeff Johnson295189b2012-06-20 16:38:30 -070012947 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
12948 {
12949 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
12950 WNI_CFG_RTS_THRESHOLD_STAMAX :
12951 wiphy->rts_threshold;
12952
12953 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012954 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070012955 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012956 hddLog(VOS_TRACE_LEVEL_ERROR,
12957 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012958 __func__, rts_threshold);
12959 return -EINVAL;
12960 }
12961
12962 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
12963 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012964 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012965 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012966 hddLog(VOS_TRACE_LEVEL_ERROR,
12967 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012968 __func__, rts_threshold);
12969 return -EIO;
12970 }
12971
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012972 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012973 rts_threshold);
12974 }
12975
12976 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
12977 {
12978 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
12979 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
12980 wiphy->frag_threshold;
12981
12982 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012983 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012984 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012985 hddLog(VOS_TRACE_LEVEL_ERROR,
12986 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012987 frag_threshold);
12988 return -EINVAL;
12989 }
12990
12991 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
12992 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012993 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012994 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012995 hddLog(VOS_TRACE_LEVEL_ERROR,
12996 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012997 __func__, frag_threshold);
12998 return -EIO;
12999 }
13000
13001 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
13002 frag_threshold);
13003 }
13004
13005 if ((changed & WIPHY_PARAM_RETRY_SHORT)
13006 || (changed & WIPHY_PARAM_RETRY_LONG))
13007 {
13008 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
13009 wiphy->retry_short :
13010 wiphy->retry_long;
13011
13012 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
13013 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
13014 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013015 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013016 __func__, retry_value);
13017 return -EINVAL;
13018 }
13019
13020 if (changed & WIPHY_PARAM_RETRY_SHORT)
13021 {
13022 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
13023 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013024 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013025 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013026 hddLog(VOS_TRACE_LEVEL_ERROR,
13027 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013028 __func__, retry_value);
13029 return -EIO;
13030 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013031 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013032 __func__, retry_value);
13033 }
13034 else if (changed & WIPHY_PARAM_RETRY_SHORT)
13035 {
13036 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
13037 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013038 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013039 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013040 hddLog(VOS_TRACE_LEVEL_ERROR,
13041 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013042 __func__, retry_value);
13043 return -EIO;
13044 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013045 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013046 __func__, retry_value);
13047 }
13048 }
13049
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013050 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013051 return 0;
13052}
13053
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013054static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
13055 u32 changed)
13056{
13057 int ret;
13058
13059 vos_ssr_protect(__func__);
13060 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
13061 vos_ssr_unprotect(__func__);
13062
13063 return ret;
13064}
13065
Jeff Johnson295189b2012-06-20 16:38:30 -070013066/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013067 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013068 * This function is used to set the txpower
13069 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013070static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013071#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13072 struct wireless_dev *wdev,
13073#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013074#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013075 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013076#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013077 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013078#endif
13079 int dbm)
13080{
13081 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013082 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013083 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13084 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013085 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013086
13087 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013088
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013089 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13090 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
13091 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013092 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013093 if (0 != status)
13094 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013095 return status;
13096 }
13097
13098 hHal = pHddCtx->hHal;
13099
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013100 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
13101 dbm, ccmCfgSetCallback,
13102 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013103 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013104 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013105 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
13106 return -EIO;
13107 }
13108
13109 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
13110 dbm);
13111
13112 switch(type)
13113 {
13114 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
13115 /* Fall through */
13116 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
13117 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
13118 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013119 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
13120 __func__);
13121 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013122 }
13123 break;
13124 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013125 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070013126 __func__);
13127 return -EOPNOTSUPP;
13128 break;
13129 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013130 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
13131 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070013132 return -EIO;
13133 }
13134
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013135 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013136 return 0;
13137}
13138
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013139static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
13140#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13141 struct wireless_dev *wdev,
13142#endif
13143#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13144 enum tx_power_setting type,
13145#else
13146 enum nl80211_tx_power_setting type,
13147#endif
13148 int dbm)
13149{
13150 int ret;
13151 vos_ssr_protect(__func__);
13152 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
13153#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13154 wdev,
13155#endif
13156#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13157 type,
13158#else
13159 type,
13160#endif
13161 dbm);
13162 vos_ssr_unprotect(__func__);
13163
13164 return ret;
13165}
13166
Jeff Johnson295189b2012-06-20 16:38:30 -070013167/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013168 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013169 * This function is used to read the txpower
13170 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013171static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013172#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13173 struct wireless_dev *wdev,
13174#endif
13175 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070013176{
13177
13178 hdd_adapter_t *pAdapter;
13179 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013180 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013181
Jeff Johnsone7245742012-09-05 17:12:55 -070013182 ENTER();
13183
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013184 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013185 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013186 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013187 *dbm = 0;
13188 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013189 }
13190
Jeff Johnson295189b2012-06-20 16:38:30 -070013191 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
13192 if (NULL == pAdapter)
13193 {
13194 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
13195 return -ENOENT;
13196 }
13197
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053013198 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13199 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
13200 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013201 wlan_hdd_get_classAstats(pAdapter);
13202 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
13203
Jeff Johnsone7245742012-09-05 17:12:55 -070013204 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013205 return 0;
13206}
13207
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013208static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
13209#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13210 struct wireless_dev *wdev,
13211#endif
13212 int *dbm)
13213{
13214 int ret;
13215
13216 vos_ssr_protect(__func__);
13217 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
13218#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13219 wdev,
13220#endif
13221 dbm);
13222 vos_ssr_unprotect(__func__);
13223
13224 return ret;
13225}
13226
13227
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013228static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070013229 u8* mac, struct station_info *sinfo)
13230{
13231 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13232 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13233 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053013234 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013235
13236 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
13237 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070013238
13239 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
13240 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
13241 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
13242 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
13243 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
13244 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
13245 tANI_U16 maxRate = 0;
13246 tANI_U16 myRate;
13247 tANI_U16 currentRate = 0;
13248 tANI_U8 maxSpeedMCS = 0;
13249 tANI_U8 maxMCSIdx = 0;
13250 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053013251 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013252 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013253 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013254
Leo Chang6f8870f2013-03-26 18:11:36 -070013255#ifdef WLAN_FEATURE_11AC
13256 tANI_U32 vht_mcs_map;
13257 eDataRate11ACMaxMcs vhtMaxMcs;
13258#endif /* WLAN_FEATURE_11AC */
13259
Jeff Johnsone7245742012-09-05 17:12:55 -070013260 ENTER();
13261
Jeff Johnson295189b2012-06-20 16:38:30 -070013262 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
13263 (0 == ssidlen))
13264 {
13265 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
13266 " Invalid ssidlen, %d", __func__, ssidlen);
13267 /*To keep GUI happy*/
13268 return 0;
13269 }
13270
Mukul Sharma811205f2014-07-09 21:07:30 +053013271 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
13272 {
13273 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13274 "%s: Roaming in progress, so unable to proceed this request", __func__);
13275 return 0;
13276 }
13277
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013278 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013279 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013280 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013281 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013282 }
13283
Jeff Johnson295189b2012-06-20 16:38:30 -070013284
Kiet Lam3b17fc82013-09-27 05:24:08 +053013285 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
13286 sinfo->filled |= STATION_INFO_SIGNAL;
13287
c_hpothu09f19542014-05-30 21:53:31 +053013288 wlan_hdd_get_station_stats(pAdapter);
13289 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
13290
13291 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053013292 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
13293 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053013294 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053013295 {
13296 rate_flags = pAdapter->maxRateFlags;
13297 }
c_hpothu44ff4e02014-05-08 00:13:57 +053013298
Jeff Johnson295189b2012-06-20 16:38:30 -070013299 //convert to the UI units of 100kbps
13300 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
13301
13302#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070013303 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 -070013304 sinfo->signal,
13305 pCfg->reportMaxLinkSpeed,
13306 myRate,
13307 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013308 (int) pCfg->linkSpeedRssiMid,
13309 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070013310 (int) rate_flags,
13311 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013312#endif //LINKSPEED_DEBUG_ENABLED
13313
13314 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
13315 {
13316 // we do not want to necessarily report the current speed
13317 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
13318 {
13319 // report the max possible speed
13320 rssidx = 0;
13321 }
13322 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
13323 {
13324 // report the max possible speed with RSSI scaling
13325 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
13326 {
13327 // report the max possible speed
13328 rssidx = 0;
13329 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013330 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070013331 {
13332 // report middle speed
13333 rssidx = 1;
13334 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013335 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
13336 {
13337 // report middle speed
13338 rssidx = 2;
13339 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013340 else
13341 {
13342 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013343 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070013344 }
13345 }
13346 else
13347 {
13348 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
13349 hddLog(VOS_TRACE_LEVEL_ERROR,
13350 "%s: Invalid value for reportMaxLinkSpeed: %u",
13351 __func__, pCfg->reportMaxLinkSpeed);
13352 rssidx = 0;
13353 }
13354
13355 maxRate = 0;
13356
13357 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013358 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
13359 OperationalRates, &ORLeng))
13360 {
13361 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13362 /*To keep GUI happy*/
13363 return 0;
13364 }
13365
Jeff Johnson295189b2012-06-20 16:38:30 -070013366 for (i = 0; i < ORLeng; i++)
13367 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013368 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013369 {
13370 /* Validate Rate Set */
13371 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
13372 {
13373 currentRate = supported_data_rate[j].supported_rate[rssidx];
13374 break;
13375 }
13376 }
13377 /* Update MAX rate */
13378 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13379 }
13380
13381 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013382 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
13383 ExtendedRates, &ERLeng))
13384 {
13385 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13386 /*To keep GUI happy*/
13387 return 0;
13388 }
13389
Jeff Johnson295189b2012-06-20 16:38:30 -070013390 for (i = 0; i < ERLeng; i++)
13391 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013392 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013393 {
13394 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
13395 {
13396 currentRate = supported_data_rate[j].supported_rate[rssidx];
13397 break;
13398 }
13399 }
13400 /* Update MAX rate */
13401 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13402 }
c_hpothu79aab322014-07-14 21:11:01 +053013403
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013404 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053013405 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013406 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053013407 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070013408 {
c_hpothu79aab322014-07-14 21:11:01 +053013409 if (rate_flags & eHAL_TX_RATE_VHT80)
13410 mode = 2;
13411 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
13412 mode = 1;
13413 else
13414 mode = 0;
13415
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013416 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
13417 MCSRates, &MCSLeng))
13418 {
13419 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13420 /*To keep GUI happy*/
13421 return 0;
13422 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013423 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070013424#ifdef WLAN_FEATURE_11AC
13425 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013426 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070013427 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013428 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013429 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070013430 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070013431 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013432 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013433 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013434 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070013435 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013436 maxMCSIdx = 7;
13437 }
13438 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
13439 {
13440 maxMCSIdx = 8;
13441 }
13442 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
13443 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013444 //VHT20 is supporting 0~8
13445 if (rate_flags & eHAL_TX_RATE_VHT20)
13446 maxMCSIdx = 8;
13447 else
13448 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070013449 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013450
c_hpothu79aab322014-07-14 21:11:01 +053013451 if (0 != rssidx)/*check for scaled */
13452 {
13453 //get middle rate MCS index if rssi=1/2
13454 for (i=0; i <= maxMCSIdx; i++)
13455 {
13456 if (sinfo->signal <= rssiMcsTbl[mode][i])
13457 {
13458 maxMCSIdx = i;
13459 break;
13460 }
13461 }
13462 }
13463
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013464 if (rate_flags & eHAL_TX_RATE_VHT80)
13465 {
13466 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
13467 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
13468 }
13469 else if (rate_flags & eHAL_TX_RATE_VHT40)
13470 {
13471 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
13472 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
13473 }
13474 else if (rate_flags & eHAL_TX_RATE_VHT20)
13475 {
13476 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
13477 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
13478 }
13479
Leo Chang6f8870f2013-03-26 18:11:36 -070013480 maxSpeedMCS = 1;
13481 if (currentRate > maxRate)
13482 {
13483 maxRate = currentRate;
13484 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013485
Leo Chang6f8870f2013-03-26 18:11:36 -070013486 }
13487 else
13488#endif /* WLAN_FEATURE_11AC */
13489 {
13490 if (rate_flags & eHAL_TX_RATE_HT40)
13491 {
13492 rateFlag |= 1;
13493 }
13494 if (rate_flags & eHAL_TX_RATE_SGI)
13495 {
13496 rateFlag |= 2;
13497 }
13498
Girish Gowli01abcee2014-07-31 20:18:55 +053013499 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053013500 if (rssidx == 1 || rssidx == 2)
13501 {
13502 //get middle rate MCS index if rssi=1/2
13503 for (i=0; i <= 7; i++)
13504 {
13505 if (sinfo->signal <= rssiMcsTbl[mode][i])
13506 {
13507 temp = i+1;
13508 break;
13509 }
13510 }
13511 }
c_hpothu79aab322014-07-14 21:11:01 +053013512
13513 for (i = 0; i < MCSLeng; i++)
13514 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013515 for (j = 0; j < temp; j++)
13516 {
13517 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
13518 {
13519 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053013520 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013521 break;
13522 }
13523 }
13524 if ((j < temp) && (currentRate > maxRate))
13525 {
13526 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070013527 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013528 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053013529 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013530 }
13531 }
13532
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013533 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
13534 {
13535 maxRate = myRate;
13536 maxSpeedMCS = 1;
13537 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13538 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013539 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053013540 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070013541 {
13542 maxRate = myRate;
13543 if (rate_flags & eHAL_TX_RATE_LEGACY)
13544 {
13545 maxSpeedMCS = 0;
13546 }
13547 else
13548 {
13549 maxSpeedMCS = 1;
13550 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13551 }
13552 }
13553
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013554 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070013555 {
13556 sinfo->txrate.legacy = maxRate;
13557#ifdef LINKSPEED_DEBUG_ENABLED
13558 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
13559#endif //LINKSPEED_DEBUG_ENABLED
13560 }
13561 else
13562 {
13563 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070013564#ifdef WLAN_FEATURE_11AC
13565 sinfo->txrate.nss = 1;
13566 if (rate_flags & eHAL_TX_RATE_VHT80)
13567 {
13568 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013569 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070013570 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013571 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070013572 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013573 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13574 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13575 }
13576 else if (rate_flags & eHAL_TX_RATE_VHT20)
13577 {
13578 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13579 }
13580#endif /* WLAN_FEATURE_11AC */
13581 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
13582 {
13583 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13584 if (rate_flags & eHAL_TX_RATE_HT40)
13585 {
13586 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13587 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013588 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013589 if (rate_flags & eHAL_TX_RATE_SGI)
13590 {
13591 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13592 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013593
Jeff Johnson295189b2012-06-20 16:38:30 -070013594#ifdef LINKSPEED_DEBUG_ENABLED
13595 pr_info("Reporting MCS rate %d flags %x\n",
13596 sinfo->txrate.mcs,
13597 sinfo->txrate.flags );
13598#endif //LINKSPEED_DEBUG_ENABLED
13599 }
13600 }
13601 else
13602 {
13603 // report current rate instead of max rate
13604
13605 if (rate_flags & eHAL_TX_RATE_LEGACY)
13606 {
13607 //provide to the UI in units of 100kbps
13608 sinfo->txrate.legacy = myRate;
13609#ifdef LINKSPEED_DEBUG_ENABLED
13610 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
13611#endif //LINKSPEED_DEBUG_ENABLED
13612 }
13613 else
13614 {
13615 //must be MCS
13616 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013617#ifdef WLAN_FEATURE_11AC
13618 sinfo->txrate.nss = 1;
13619 if (rate_flags & eHAL_TX_RATE_VHT80)
13620 {
13621 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13622 }
13623 else
13624#endif /* WLAN_FEATURE_11AC */
13625 {
13626 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13627 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013628 if (rate_flags & eHAL_TX_RATE_SGI)
13629 {
13630 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13631 }
13632 if (rate_flags & eHAL_TX_RATE_HT40)
13633 {
13634 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13635 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013636#ifdef WLAN_FEATURE_11AC
13637 else if (rate_flags & eHAL_TX_RATE_VHT80)
13638 {
13639 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
13640 }
13641#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070013642#ifdef LINKSPEED_DEBUG_ENABLED
13643 pr_info("Reporting actual MCS rate %d flags %x\n",
13644 sinfo->txrate.mcs,
13645 sinfo->txrate.flags );
13646#endif //LINKSPEED_DEBUG_ENABLED
13647 }
13648 }
13649 sinfo->filled |= STATION_INFO_TX_BITRATE;
13650
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013651 sinfo->tx_packets =
13652 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
13653 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
13654 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
13655 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
13656
13657 sinfo->tx_retries =
13658 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
13659 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
13660 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
13661 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
13662
13663 sinfo->tx_failed =
13664 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
13665 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
13666 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
13667 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
13668
13669 sinfo->filled |=
13670 STATION_INFO_TX_PACKETS |
13671 STATION_INFO_TX_RETRIES |
13672 STATION_INFO_TX_FAILED;
13673
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013674 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13675 TRACE_CODE_HDD_CFG80211_GET_STA,
13676 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013677 EXIT();
13678 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013679}
13680
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013681static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13682 u8* mac, struct station_info *sinfo)
13683{
13684 int ret;
13685
13686 vos_ssr_protect(__func__);
13687 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
13688 vos_ssr_unprotect(__func__);
13689
13690 return ret;
13691}
13692
13693static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070013694 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070013695{
13696 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013697 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013698 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013699 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013700
Jeff Johnsone7245742012-09-05 17:12:55 -070013701 ENTER();
13702
Jeff Johnson295189b2012-06-20 16:38:30 -070013703 if (NULL == pAdapter)
13704 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013705 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013706 return -ENODEV;
13707 }
13708
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013709 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13710 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
13711 pAdapter->sessionId, timeout));
13712
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013713 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013714 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013715 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013716 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013717 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013718 }
13719
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013720 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
13721 (TRUE == pHddCtx->hdd_wlan_suspended) &&
13722 (pHddCtx->cfg_ini->fhostArpOffload) &&
13723 (eConnectionState_Associated ==
13724 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13725 {
Amar Singhald53568e2013-09-26 11:03:45 -070013726
13727 hddLog(VOS_TRACE_LEVEL_INFO,
13728 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053013729 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013730 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13731 {
13732 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013733 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013734 __func__, vos_status);
13735 }
13736 }
13737
Jeff Johnson295189b2012-06-20 16:38:30 -070013738 /**The get power cmd from the supplicant gets updated by the nl only
13739 *on successful execution of the function call
13740 *we are oppositely mapped w.r.t mode in the driver
13741 **/
13742 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
13743
13744 if (VOS_STATUS_E_FAILURE == vos_status)
13745 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13747 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013748 return -EINVAL;
13749 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013750 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013751 return 0;
13752}
13753
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013754static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
13755 struct net_device *dev, bool mode, int timeout)
13756{
13757 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013758
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013759 vos_ssr_protect(__func__);
13760 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
13761 vos_ssr_unprotect(__func__);
13762
13763 return ret;
13764}
Jeff Johnson295189b2012-06-20 16:38:30 -070013765#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013766static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
13767 struct net_device *netdev,
13768 u8 key_index)
13769{
13770 ENTER();
13771 return 0;
13772}
13773
Jeff Johnson295189b2012-06-20 16:38:30 -070013774static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013775 struct net_device *netdev,
13776 u8 key_index)
13777{
13778 int ret;
13779 vos_ssr_protect(__func__);
13780 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
13781 vos_ssr_unprotect(__func__);
13782 return ret;
13783}
13784#endif //LINUX_VERSION_CODE
13785
13786#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13787static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13788 struct net_device *dev,
13789 struct ieee80211_txq_params *params)
13790{
13791 ENTER();
13792 return 0;
13793}
13794#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13795static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13796 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013797{
Jeff Johnsone7245742012-09-05 17:12:55 -070013798 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013799 return 0;
13800}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013801#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070013802
13803#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13804static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013805 struct net_device *dev,
13806 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013807{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013808 int ret;
13809
13810 vos_ssr_protect(__func__);
13811 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
13812 vos_ssr_unprotect(__func__);
13813 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013814}
13815#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13816static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
13817 struct ieee80211_txq_params *params)
13818{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013819 int ret;
13820
13821 vos_ssr_protect(__func__);
13822 ret = __wlan_hdd_set_txq_params(wiphy, params);
13823 vos_ssr_unprotect(__func__);
13824 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013825}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013826#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013827
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013828static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013829 struct net_device *dev,
13830 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070013831{
13832 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013833 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013834 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013835 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013836 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013837 v_CONTEXT_t pVosContext = NULL;
13838 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013839
Jeff Johnsone7245742012-09-05 17:12:55 -070013840 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013841
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013842 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070013843 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013844 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013845 return -EINVAL;
13846 }
13847
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013848 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13849 TRACE_CODE_HDD_CFG80211_DEL_STA,
13850 pAdapter->sessionId, pAdapter->device_mode));
13851
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013852 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13853 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013854 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013855 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013856 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013857 }
13858
Jeff Johnson295189b2012-06-20 16:38:30 -070013859 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013860 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013861 )
13862 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013863 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13864 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13865 if(pSapCtx == NULL){
13866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13867 FL("psapCtx is NULL"));
13868 return -ENOENT;
13869 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013870 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013871 {
13872 v_U16_t i;
13873 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13874 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013875 if ((pSapCtx->aStaInfo[i].isUsed) &&
13876 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070013877 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013878 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013879 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013880 ETHER_ADDR_LEN);
13881
Jeff Johnson295189b2012-06-20 16:38:30 -070013882 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013883 "%s: Delete STA with MAC::"
13884 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013885 __func__,
13886 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
13887 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013888 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013889 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013890 }
13891 }
13892 }
13893 else
13894 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013895
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013896 vos_status = hdd_softap_GetStaId(pAdapter,
13897 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013898 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13899 {
13900 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013901 "%s: Skip this DEL STA as this is not used::"
13902 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013903 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013904 return -ENOENT;
13905 }
13906
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013907 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013908 {
13909 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013910 "%s: Skip this DEL STA as deauth is in progress::"
13911 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013912 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013913 return -ENOENT;
13914 }
13915
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013916 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013917
Jeff Johnson295189b2012-06-20 16:38:30 -070013918 hddLog(VOS_TRACE_LEVEL_INFO,
13919 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013920 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013921 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013922 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013923
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013924 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013925 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13926 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013927 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013928 hddLog(VOS_TRACE_LEVEL_INFO,
13929 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013930 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013931 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013932 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013933 return -ENOENT;
13934 }
13935
Jeff Johnson295189b2012-06-20 16:38:30 -070013936 }
13937 }
13938
13939 EXIT();
13940
13941 return 0;
13942}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013943
13944#ifdef CFG80211_DEL_STA_V2
13945static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13946 struct net_device *dev,
13947 struct station_del_parameters *param)
13948#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013949static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13950 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013951#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013952{
13953 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013954 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070013955
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013956 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013957
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013958#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013959 if (NULL == param) {
13960 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013961 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013962 return -EINVAL;
13963 }
13964
13965 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
13966 param->subtype, &delStaParams);
13967
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013968#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053013969 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013970 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013971#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013972 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
13973
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013974 vos_ssr_unprotect(__func__);
13975
13976 return ret;
13977}
13978
13979static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013980 struct net_device *dev, u8 *mac, struct station_parameters *params)
13981{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013982 hdd_adapter_t *pAdapter;
13983 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013984 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013985#ifdef FEATURE_WLAN_TDLS
13986 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013987
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013988 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013989
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013990 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13991 if (NULL == pAdapter)
13992 {
13993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13994 "%s: Adapter is NULL",__func__);
13995 return -EINVAL;
13996 }
13997 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13998 status = wlan_hdd_validate_context(pHddCtx);
13999 if (0 != status)
14000 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014001 return status;
14002 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014003
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014004 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14005 TRACE_CODE_HDD_CFG80211_ADD_STA,
14006 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014007 mask = params->sta_flags_mask;
14008
14009 set = params->sta_flags_set;
14010
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014012 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
14013 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014014
14015 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
14016 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014017 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014018 }
14019 }
14020#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014021 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014022 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014023}
14024
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014025static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14026 struct net_device *dev, u8 *mac, struct station_parameters *params)
14027{
14028 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014029
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014030 vos_ssr_protect(__func__);
14031 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
14032 vos_ssr_unprotect(__func__);
14033
14034 return ret;
14035}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014036#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070014037
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014038static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070014039 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014040{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014041 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14042 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014043 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014044 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014045 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014046 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070014047
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014048 ENTER();
14049
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014050 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014051 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014052 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014053 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014054 return -EINVAL;
14055 }
14056
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014057 if (!pmksa) {
14058 hddLog(LOGE, FL("pmksa is NULL"));
14059 return -EINVAL;
14060 }
14061
14062 if (!pmksa->bssid || !pmksa->pmkid) {
14063 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
14064 pmksa->bssid, pmksa->pmkid);
14065 return -EINVAL;
14066 }
14067
14068 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
14069 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14070
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014071 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14072 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014073 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014074 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014075 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014076 }
14077
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014078 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014079 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14080
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014081 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
14082 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014083
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014084 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014085 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014086 &pmk_id, 1, FALSE);
14087
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014088 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14089 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
14090 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014091
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014092 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014093 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014094}
14095
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014096static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
14097 struct cfg80211_pmksa *pmksa)
14098{
14099 int ret;
14100
14101 vos_ssr_protect(__func__);
14102 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
14103 vos_ssr_unprotect(__func__);
14104
14105 return ret;
14106}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014107
Wilson Yang6507c4e2013-10-01 20:11:19 -070014108
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014109static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070014110 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014111{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014112 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14113 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014114 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014115 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014116
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014117 ENTER();
14118
Wilson Yang6507c4e2013-10-01 20:11:19 -070014119 /* Validate pAdapter */
14120 if (NULL == pAdapter)
14121 {
14122 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
14123 return -EINVAL;
14124 }
14125
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014126 if (!pmksa) {
14127 hddLog(LOGE, FL("pmksa is NULL"));
14128 return -EINVAL;
14129 }
14130
14131 if (!pmksa->bssid) {
14132 hddLog(LOGE, FL("pmksa->bssid is NULL"));
14133 return -EINVAL;
14134 }
14135
Kiet Lam98c46a12014-10-31 15:34:57 -070014136 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
14137 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14138
Wilson Yang6507c4e2013-10-01 20:11:19 -070014139 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14140 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014141 if (0 != status)
14142 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014143 return status;
14144 }
14145
14146 /*Retrieve halHandle*/
14147 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14148
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014149 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14150 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
14151 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014152 /* Delete the PMKID CSR cache */
14153 if (eHAL_STATUS_SUCCESS !=
14154 sme_RoamDelPMKIDfromCache(halHandle,
14155 pAdapter->sessionId, pmksa->bssid, FALSE)) {
14156 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
14157 MAC_ADDR_ARRAY(pmksa->bssid));
14158 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014159 }
14160
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014161 EXIT();
14162 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014163}
14164
Wilson Yang6507c4e2013-10-01 20:11:19 -070014165
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014166static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
14167 struct cfg80211_pmksa *pmksa)
14168{
14169 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014170
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014171 vos_ssr_protect(__func__);
14172 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
14173 vos_ssr_unprotect(__func__);
14174
14175 return ret;
14176
14177}
14178
14179static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014180{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014181 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14182 tHalHandle halHandle;
14183 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014184 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014185
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014186 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070014187
14188 /* Validate pAdapter */
14189 if (NULL == pAdapter)
14190 {
14191 hddLog(VOS_TRACE_LEVEL_ERROR,
14192 "%s: Invalid Adapter" ,__func__);
14193 return -EINVAL;
14194 }
14195
14196 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14197 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014198 if (0 != status)
14199 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014200 return status;
14201 }
14202
14203 /*Retrieve halHandle*/
14204 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14205
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014206 /* Flush the PMKID cache in CSR */
14207 if (eHAL_STATUS_SUCCESS !=
14208 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
14209 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
14210 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014211 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014212 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080014213 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014214}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014215
14216static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
14217{
14218 int ret;
14219
14220 vos_ssr_protect(__func__);
14221 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
14222 vos_ssr_unprotect(__func__);
14223
14224 return ret;
14225}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014226#endif
14227
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014228#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014229static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14230 struct net_device *dev,
14231 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014232{
14233 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14234 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014235 hdd_context_t *pHddCtx;
14236 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014237
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014238 ENTER();
14239
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014240 if (NULL == pAdapter)
14241 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014242 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014243 return -ENODEV;
14244 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014245 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14246 ret = wlan_hdd_validate_context(pHddCtx);
14247 if (0 != ret)
14248 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014249 return ret;
14250 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014251 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014252 if (NULL == pHddStaCtx)
14253 {
14254 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
14255 return -EINVAL;
14256 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014257
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014258 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14259 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
14260 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014261 // Added for debug on reception of Re-assoc Req.
14262 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
14263 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014264 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014265 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080014266 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014267 }
14268
14269#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080014270 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014271 ftie->ie_len);
14272#endif
14273
14274 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014275 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
14276 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014277 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014278
14279 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014280 return 0;
14281}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014282
14283static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14284 struct net_device *dev,
14285 struct cfg80211_update_ft_ies_params *ftie)
14286{
14287 int ret;
14288
14289 vos_ssr_protect(__func__);
14290 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
14291 vos_ssr_unprotect(__func__);
14292
14293 return ret;
14294}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014295#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014296
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014297#ifdef FEATURE_WLAN_SCAN_PNO
14298
14299void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
14300 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
14301{
14302 int ret;
14303 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
14304 hdd_context_t *pHddCtx;
14305
Nirav Shah80830bf2013-12-31 16:35:12 +053014306 ENTER();
14307
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014308 if (NULL == pAdapter)
14309 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014311 "%s: HDD adapter is Null", __func__);
14312 return ;
14313 }
14314
14315 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14316 if (NULL == pHddCtx)
14317 {
14318 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14319 "%s: HDD context is Null!!!", __func__);
14320 return ;
14321 }
14322
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014323 spin_lock(&pHddCtx->schedScan_lock);
14324 if (TRUE == pHddCtx->isWiphySuspended)
14325 {
14326 pHddCtx->isSchedScanUpdatePending = TRUE;
14327 spin_unlock(&pHddCtx->schedScan_lock);
14328 hddLog(VOS_TRACE_LEVEL_INFO,
14329 "%s: Update cfg80211 scan database after it resume", __func__);
14330 return ;
14331 }
14332 spin_unlock(&pHddCtx->schedScan_lock);
14333
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014334 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
14335
14336 if (0 > ret)
14337 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
14338
14339 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14341 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014342}
14343
14344/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014345 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014346 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014347 */
14348static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
14349{
14350 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14351 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014352 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014353 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14354 int status = 0;
14355 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
14356
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014357 /* The current firmware design does not allow PNO during any
14358 * active sessions. Hence, determine the active sessions
14359 * and return a failure.
14360 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014361 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
14362 {
14363 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014364 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014365
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014366 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
14367 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
14368 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
14369 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
14370 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053014371 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014372 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014373 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014374 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014375 }
14376 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14377 pAdapterNode = pNext;
14378 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014379 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014380}
14381
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014382void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
14383{
14384 hdd_adapter_t *pAdapter = callbackContext;
14385 hdd_context_t *pHddCtx;
14386
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014387 ENTER();
14388
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014389 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
14390 {
14391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14392 FL("Invalid adapter or adapter has invalid magic"));
14393 return;
14394 }
14395
14396 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14397 if (0 != wlan_hdd_validate_context(pHddCtx))
14398 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014399 return;
14400 }
14401
c_hpothub53c45d2014-08-18 16:53:14 +053014402 if (VOS_STATUS_SUCCESS != status)
14403 {
14404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014405 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053014406 pHddCtx->isPnoEnable = FALSE;
14407 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014408
14409 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
14410 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014411 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014412}
14413
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014414/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014415 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
14416 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014417 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014418static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014419 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14420{
14421 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014422 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014423 hdd_context_t *pHddCtx;
14424 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014425 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053014426 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
14427 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014428 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14429 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014430 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014431 hdd_config_t *pConfig = NULL;
14432 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014433
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014434 ENTER();
14435
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014436 if (NULL == pAdapter)
14437 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014439 "%s: HDD adapter is Null", __func__);
14440 return -ENODEV;
14441 }
14442
14443 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014444 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014445
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014446 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014447 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014448 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014449 }
14450
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014451 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014452 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14453 if (NULL == hHal)
14454 {
14455 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14456 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014457 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014458 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014459 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14460 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
14461 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053014462 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014463 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053014464 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014465 {
14466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14467 "%s: aborting the existing scan is unsuccessfull", __func__);
14468 return -EBUSY;
14469 }
14470
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014471 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014472 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014473 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014474 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014475 return -EBUSY;
14476 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014477
c_hpothu37f21312014-04-09 21:49:54 +053014478 if (TRUE == pHddCtx->isPnoEnable)
14479 {
14480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14481 FL("already PNO is enabled"));
14482 return -EBUSY;
14483 }
c_hpothu225aa7c2014-10-22 17:45:13 +053014484
14485 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
14486 {
14487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14488 "%s: abort ROC failed ", __func__);
14489 return -EBUSY;
14490 }
14491
c_hpothu37f21312014-04-09 21:49:54 +053014492 pHddCtx->isPnoEnable = TRUE;
14493
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014494 pnoRequest.enable = 1; /*Enable PNO */
14495 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014496
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014497 if (( !pnoRequest.ucNetworksCount ) ||
14498 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014499 {
14500 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014501 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014502 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014503 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014504 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014505 goto error;
14506 }
14507
14508 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
14509 {
14510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014511 "%s: Incorrect number of channels %d",
14512 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014513 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014514 goto error;
14515 }
14516
14517 /* Framework provides one set of channels(all)
14518 * common for all saved profile */
14519 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14520 channels_allowed, &num_channels_allowed))
14521 {
14522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14523 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014524 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014525 goto error;
14526 }
14527 /* Checking each channel against allowed channel list */
14528 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053014529 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014530 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014531 char chList [(request->n_channels*5)+1];
14532 int len;
14533 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014534 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014535 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014536 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014537 if (request->channels[i]->hw_value == channels_allowed[indx])
14538 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014539 if ((!pConfig->enableDFSPnoChnlScan) &&
14540 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
14541 {
14542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14543 "%s : Dropping DFS channel : %d",
14544 __func__,channels_allowed[indx]);
14545 num_ignore_dfs_ch++;
14546 break;
14547 }
14548
Nirav Shah80830bf2013-12-31 16:35:12 +053014549 valid_ch[num_ch++] = request->channels[i]->hw_value;
14550 len += snprintf(chList+len, 5, "%d ",
14551 request->channels[i]->hw_value);
14552 break ;
14553 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014554 }
14555 }
Nirav Shah80830bf2013-12-31 16:35:12 +053014556 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014557
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014558 /*If all channels are DFS and dropped, then ignore the PNO request*/
14559 if (num_ignore_dfs_ch == request->n_channels)
14560 {
14561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14562 "%s : All requested channels are DFS channels", __func__);
14563 ret = -EINVAL;
14564 goto error;
14565 }
14566 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014567
14568 pnoRequest.aNetworks =
14569 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14570 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014571 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014572 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14573 FL("failed to allocate memory aNetworks %u"),
14574 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14575 goto error;
14576 }
14577 vos_mem_zero(pnoRequest.aNetworks,
14578 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14579
14580 /* Filling per profile params */
14581 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
14582 {
14583 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014584 request->match_sets[i].ssid.ssid_len;
14585
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014586 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
14587 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014588 {
14589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014590 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014591 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014592 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014593 goto error;
14594 }
14595
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014596 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014597 request->match_sets[i].ssid.ssid,
14598 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14600 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014601 i, pnoRequest.aNetworks[i].ssId.ssId);
14602 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
14603 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
14604 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014605
14606 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014607 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
14608 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014609
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014610 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014611 }
14612
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014613 for (i = 0; i < request->n_ssids; i++)
14614 {
14615 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014616 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014617 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014618 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014619 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014620 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014621 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014622 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014623 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014624 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014625 break;
14626 }
14627 j++;
14628 }
14629 }
14630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14631 "Number of hidden networks being Configured = %d",
14632 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080014634 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014635
14636 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14637 if (pnoRequest.p24GProbeTemplate == NULL)
14638 {
14639 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14640 FL("failed to allocate memory p24GProbeTemplate %u"),
14641 SIR_PNO_MAX_PB_REQ_SIZE);
14642 goto error;
14643 }
14644
14645 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14646 if (pnoRequest.p5GProbeTemplate == NULL)
14647 {
14648 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14649 FL("failed to allocate memory p5GProbeTemplate %u"),
14650 SIR_PNO_MAX_PB_REQ_SIZE);
14651 goto error;
14652 }
14653
14654 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14655 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14656
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053014657 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
14658 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014659 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014660 pnoRequest.us24GProbeTemplateLen = request->ie_len;
14661 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
14662 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014663
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014664 pnoRequest.us5GProbeTemplateLen = request->ie_len;
14665 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
14666 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014667 }
14668
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014669 /* Driver gets only one time interval which is hardcoded in
14670 * supplicant for 10000ms. Taking power consumption into account 6 timers
14671 * will be used, Timervalue is increased exponentially i.e 10,20,40,
14672 * 80,160,320 secs. And number of scan cycle for each timer
14673 * is configurable through INI param gPNOScanTimerRepeatValue.
14674 * If it is set to 0 only one timer will be used and PNO scan cycle
14675 * will be repeated after each interval specified by supplicant
14676 * till PNO is disabled.
14677 */
14678 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014679 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014680 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014681 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014682 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
14683
14684 tempInterval = (request->interval)/1000;
14685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14686 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
14687 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014688 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014689 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014690 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014691 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014692 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014693 tempInterval *= 2;
14694 }
14695 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014696 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014697
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014698 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014699
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014700 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014701 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
14702 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014703 pAdapter->pno_req_status = 0;
14704
Nirav Shah80830bf2013-12-31 16:35:12 +053014705 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14706 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014707 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
14708 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053014709
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014710 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014711 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014712 hdd_cfg80211_sched_scan_done_callback, pAdapter);
14713 if (eHAL_STATUS_SUCCESS != status)
14714 {
14715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014716 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014717 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014718 goto error;
14719 }
14720
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014721 ret = wait_for_completion_timeout(
14722 &pAdapter->pno_comp_var,
14723 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
14724 if (0 >= ret)
14725 {
14726 // Did not receive the response for PNO enable in time.
14727 // Assuming the PNO enable was success.
14728 // Returning error from here, because we timeout, results
14729 // in side effect of Wifi (Wifi Setting) not to work.
14730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14731 FL("Timed out waiting for PNO to be Enabled"));
14732 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014733 }
14734
14735 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053014736 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014737
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014738error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014739 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14740 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053014741 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014742 if (pnoRequest.aNetworks)
14743 vos_mem_free(pnoRequest.aNetworks);
14744 if (pnoRequest.p24GProbeTemplate)
14745 vos_mem_free(pnoRequest.p24GProbeTemplate);
14746 if (pnoRequest.p5GProbeTemplate)
14747 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014748
14749 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014750 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014751}
14752
14753/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014754 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
14755 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014756 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014757static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
14758 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14759{
14760 int ret;
14761
14762 vos_ssr_protect(__func__);
14763 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
14764 vos_ssr_unprotect(__func__);
14765
14766 return ret;
14767}
14768
14769/*
14770 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
14771 * Function to disable PNO
14772 */
14773static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014774 struct net_device *dev)
14775{
14776 eHalStatus status = eHAL_STATUS_FAILURE;
14777 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14778 hdd_context_t *pHddCtx;
14779 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014780 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014781 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014782
14783 ENTER();
14784
14785 if (NULL == pAdapter)
14786 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014787 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014788 "%s: HDD adapter is Null", __func__);
14789 return -ENODEV;
14790 }
14791
14792 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014793
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014794 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014795 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014797 "%s: HDD context is Null", __func__);
14798 return -ENODEV;
14799 }
14800
14801 /* The return 0 is intentional when isLogpInProgress and
14802 * isLoadUnloadInProgress. We did observe a crash due to a return of
14803 * failure in sched_scan_stop , especially for a case where the unload
14804 * of the happens at the same time. The function __cfg80211_stop_sched_scan
14805 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
14806 * success. If it returns a failure , then its next invocation due to the
14807 * clean up of the second interface will have the dev pointer corresponding
14808 * to the first one leading to a crash.
14809 */
14810 if (pHddCtx->isLogpInProgress)
14811 {
14812 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14813 "%s: LOGP in Progress. Ignore!!!", __func__);
14814 return ret;
14815 }
14816
Mihir Shete18156292014-03-11 15:38:30 +053014817 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014818 {
14819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14820 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14821 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014822 }
14823
14824 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14825 if (NULL == hHal)
14826 {
14827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14828 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014829 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014830 }
14831
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014832 pnoRequest.enable = 0; /* Disable PNO */
14833 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014834
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014835 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14836 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
14837 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014838 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014839 pAdapter->sessionId,
14840 NULL, pAdapter);
14841 if (eHAL_STATUS_SUCCESS != status)
14842 {
14843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14844 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014845 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014846 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014847 }
c_hpothu37f21312014-04-09 21:49:54 +053014848 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014849
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014850error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014851 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014852 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014853
14854 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014855 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014856}
14857
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014858/*
14859 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
14860 * NL interface to disable PNO
14861 */
14862static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
14863 struct net_device *dev)
14864{
14865 int ret;
14866
14867 vos_ssr_protect(__func__);
14868 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
14869 vos_ssr_unprotect(__func__);
14870
14871 return ret;
14872}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014873#endif /*FEATURE_WLAN_SCAN_PNO*/
14874
14875
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014876#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014877#if TDLS_MGMT_VERSION2
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014878static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014879 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014880 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
14881#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014882static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014883 u8 *peer, u8 action_code, u8 dialog_token,
14884 u16 status_code, const u8 *buf, size_t len)
14885#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014886{
14887
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014888 hdd_adapter_t *pAdapter;
14889 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014890 u8 peerMac[6];
14891 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070014892 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080014893 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070014894 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014895 int ret;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014896#if !(TDLS_MGMT_VERSION2)
14897 u32 peer_capability = 0;
14898#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014899 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014900
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014901 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14902 if (NULL == pAdapter)
14903 {
14904 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14905 "%s: Adapter is NULL",__func__);
14906 return -EINVAL;
14907 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014908 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14909 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
14910 pAdapter->sessionId, action_code));
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014911 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014912 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014913 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014915 "Invalid arguments");
14916 return -EINVAL;
14917 }
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014918 if (pHddCtx->isLogpInProgress)
14919 {
14920 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14921 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053014922 wlan_hdd_tdls_set_link_status(pAdapter,
14923 peer,
14924 eTDLS_LINK_IDLE,
14925 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014926 return -EBUSY;
14927 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014928 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
14929 {
14930 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14931 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14932 return -EAGAIN;
14933 }
Hoonki Lee27511902013-03-14 18:19:06 -070014934 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014935 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014936 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070014937 "%s: TDLS mode is disabled OR not enabled in FW."
14938 MAC_ADDRESS_STR " action %d declined.",
14939 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014940 return -ENOTSUPP;
14941 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014942
Hoonki Lee27511902013-03-14 18:19:06 -070014943 /* other than teardown frame, other mgmt frames are not sent if disabled */
14944 if (SIR_MAC_TDLS_TEARDOWN != action_code)
14945 {
14946 /* if tdls_mode is disabled to respond to peer's request */
14947 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
14948 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070014950 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014951 " TDLS mode is disabled. action %d declined.",
14952 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070014953
14954 return -ENOTSUPP;
14955 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014956
14957 if (vos_max_concurrent_connections_reached())
14958 {
14959 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14960 return -EINVAL;
14961 }
Hoonki Lee27511902013-03-14 18:19:06 -070014962 }
14963
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014964 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
14965 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053014966 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014967 {
14968 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014969 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014970 " TDLS setup is ongoing. action %d declined.",
14971 __func__, MAC_ADDR_ARRAY(peer), action_code);
14972 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014973 }
14974 }
14975
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014976 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
14977 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080014978 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014979 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14980 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014981 {
14982 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
14983 we return error code at 'add_station()'. Hence we have this
14984 check again in addtion to add_station().
14985 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014986 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014987 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014988 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14989 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014990 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
14991 __func__, MAC_ADDR_ARRAY(peer), action_code,
14992 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053014993 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080014994 }
14995 else
14996 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014997 /* maximum reached. tweak to send error code to peer and return
14998 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014999 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15001 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015002 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
15003 __func__, MAC_ADDR_ARRAY(peer), status_code,
15004 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070015005 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015006 /* fall through to send setup resp with failure status
15007 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015008 }
15009 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015010 else
15011 {
15012 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053015013 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015014 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015015 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015016 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015017 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
15018 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015019 return -EPERM;
15020 }
15021 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015022 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015023 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015024
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015025 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015026 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015027 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
15028 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015029
Hoonki Leea34dd892013-02-05 22:56:02 -080015030 /*Except teardown responder will not be used so just make 0*/
15031 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015032 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080015033 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015034
15035 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053015036 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015037
15038 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
15039 responder = pTdlsPeer->is_responder;
15040 else
Hoonki Leea34dd892013-02-05 22:56:02 -080015041 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015043 "%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 -070015044 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
15045 dialog_token, status_code, len);
15046 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080015047 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015048 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015049
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015050 /* For explicit trigger of DIS_REQ come out of BMPS for
15051 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070015052 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015053 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
15054 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070015055 {
15056 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
15057 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015059 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015060 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
15061 if (status != VOS_STATUS_SUCCESS) {
15062 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
15063 }
Hoonki Lee14621352013-04-16 17:51:19 -070015064 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015065 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
15066 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED)) {
15067 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
15068 }
15069 }
Hoonki Lee14621352013-04-16 17:51:19 -070015070 }
15071
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015072 /* make sure doesn't call send_mgmt() while it is pending */
15073 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
15074 {
15075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015076 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015077 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015078 ret = -EBUSY;
15079 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015080 }
15081
15082 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015083 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
15084
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015085 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053015086 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015087
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015088 if (VOS_STATUS_SUCCESS != status)
15089 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15091 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015092 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015093 ret = -EINVAL;
15094 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015095 }
15096
Hoonki Leed37cbb32013-04-20 00:31:14 -070015097 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
15098 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
15099
15100 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015101 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070015102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015103 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070015104 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015105 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080015106
15107 if (pHddCtx->isLogpInProgress)
15108 {
15109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15110 "%s: LOGP in Progress. Ignore!!!", __func__);
15111 return -EAGAIN;
15112 }
15113
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015114 ret = -EINVAL;
15115 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015116 }
15117
Gopichand Nakkala05922802013-03-14 12:23:19 -070015118 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070015119 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015120 ret = max_sta_failed;
15121 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070015122 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015123
Hoonki Leea34dd892013-02-05 22:56:02 -080015124 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
15125 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015126 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE)) {
15127 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15128 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015129 }
15130 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
15131 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015132 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE)) {
15133 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15134 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015135 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015136
15137 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015138
15139tx_failed:
15140 /* add_station will be called before sending TDLS_SETUP_REQ and
15141 * TDLS_SETUP_RSP and as part of add_station driver will enable
15142 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
15143 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
15144 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
15145 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
15146 */
15147
15148 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
15149 (SIR_MAC_TDLS_SETUP_RSP == action_code))
15150 wlan_hdd_tdls_check_bmps(pAdapter);
15151 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015152}
15153
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015154#if TDLS_MGMT_VERSION2
15155static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15156 u8 *peer, u8 action_code, u8 dialog_token,
15157 u16 status_code, u32 peer_capability,
15158 const u8 *buf, size_t len)
15159#else
15160static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15161 u8 *peer, u8 action_code, u8 dialog_token,
15162 u16 status_code, const u8 *buf, size_t len)
15163#endif
15164{
15165 int ret;
15166
15167 vos_ssr_protect(__func__);
15168#if TDLS_MGMT_VERSION2
15169 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
15170 status_code, peer_capability, buf, len);
15171#else
15172 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
15173 status_code, buf, len);
15174#endif
15175 vos_ssr_unprotect(__func__);
15176
15177 return ret;
15178}
Atul Mittal115287b2014-07-08 13:26:33 +053015179
15180int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
15181 u8 *peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015182 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053015183 cfg80211_exttdls_callback callback)
15184{
15185
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015186 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053015187 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015188 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053015189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15190 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
15191 __func__, MAC_ADDR_ARRAY(peer));
15192
15193 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15194 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15195
15196 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015197 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15198 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15199 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015200 return -ENOTSUPP;
15201 }
15202
15203 /* To cater the requirement of establishing the TDLS link
15204 * irrespective of the data traffic , get an entry of TDLS peer.
15205 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015206 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015207 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
15208 if (pTdlsPeer == NULL) {
15209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15210 "%s: peer " MAC_ADDRESS_STR " not existing",
15211 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015212 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015213 return -EINVAL;
15214 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015215 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015216
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015217 /* check FW TDLS Off Channel capability */
15218 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015219 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015220 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015221 {
15222 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
15223 pTdlsPeer->peerParams.global_operating_class =
15224 tdls_peer_params->global_operating_class;
15225 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
15226 pTdlsPeer->peerParams.min_bandwidth_kbps =
15227 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015228 /* check configured channel is valid, non dfs and
15229 * not current operating channel */
15230 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
15231 tdls_peer_params->channel)) &&
15232 (pHddStaCtx) &&
15233 (tdls_peer_params->channel !=
15234 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015235 {
15236 pTdlsPeer->isOffChannelConfigured = TRUE;
15237 }
15238 else
15239 {
15240 pTdlsPeer->isOffChannelConfigured = FALSE;
15241 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15242 "%s: Configured Tdls Off Channel is not valid", __func__);
15243
15244 }
15245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015246 "%s: tdls_off_channel %d isOffChannelConfigured %d "
15247 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015248 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015249 pTdlsPeer->isOffChannelConfigured,
15250 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015251 }
15252 else
15253 {
15254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015255 "%s: TDLS off channel FW capability %d, "
15256 "host capab %d or Invalid TDLS Peer Params", __func__,
15257 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
15258 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015259 }
15260
Atul Mittal115287b2014-07-08 13:26:33 +053015261 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
15262
15263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15264 " %s TDLS Add Force Peer Failed",
15265 __func__);
15266 return -EINVAL;
15267 }
15268 /*EXT TDLS*/
15269
15270 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
15271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15272 " %s TDLS set callback Failed",
15273 __func__);
15274 return -EINVAL;
15275 }
15276
15277 return(0);
15278
15279}
15280
15281int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
15282{
15283
15284 hddTdlsPeer_t *pTdlsPeer;
15285 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15287 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
15288 __func__, MAC_ADDR_ARRAY(peer));
15289
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015290 if (0 != wlan_hdd_validate_context(pHddCtx)) {
15291 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
15292 return -EINVAL;
15293 }
15294
Atul Mittal115287b2014-07-08 13:26:33 +053015295 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15296 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15297
15298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015299 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15300 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15301 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015302 return -ENOTSUPP;
15303 }
15304
15305
15306 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15307
15308 if ( NULL == pTdlsPeer ) {
15309 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015310 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053015311 __func__, MAC_ADDR_ARRAY(peer));
15312 return -EINVAL;
15313 }
15314 else {
15315 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
15316 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015317 /* if channel switch is configured, reset
15318 the channel for this peer */
15319 if (TRUE == pTdlsPeer->isOffChannelConfigured)
15320 {
15321 pTdlsPeer->peerParams.channel = 0;
15322 pTdlsPeer->isOffChannelConfigured = FALSE;
15323 }
Atul Mittal115287b2014-07-08 13:26:33 +053015324 }
15325
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015326 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
15327 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053015328 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015329 }
Atul Mittal115287b2014-07-08 13:26:33 +053015330
15331 /*EXT TDLS*/
15332
15333 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
15334
15335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15336 " %s TDLS set callback Failed",
15337 __func__);
15338 return -EINVAL;
15339 }
15340 return(0);
15341
15342}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015343static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015344 u8 *peer, enum nl80211_tdls_operation oper)
15345{
15346 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15347 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015348 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015349 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015350
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015351 ENTER();
15352
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015353 if (!pAdapter) {
15354 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15355 return -EINVAL;
15356 }
15357
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015358 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15359 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
15360 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015361 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015362 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015363 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070015364 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015365 return -EINVAL;
15366 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015367
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015368 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015369 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015370 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015371 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015372 }
15373
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015374
15375 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015376 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015377 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015379 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
15380 "Cannot process TDLS commands",
15381 pHddCtx->cfg_ini->fEnableTDLSSupport,
15382 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015383 return -ENOTSUPP;
15384 }
15385
15386 switch (oper) {
15387 case NL80211_TDLS_ENABLE_LINK:
15388 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015389 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015390 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015391 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053015392 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015393 tANI_U16 numCurrTdlsPeers = 0;
15394 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015395 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015396
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15398 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
15399 __func__, MAC_ADDR_ARRAY(peer));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015400 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015401 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015402 if ( NULL == pTdlsPeer ) {
15403 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15404 " (oper %d) not exsting. ignored",
15405 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15406 return -EINVAL;
15407 }
15408
15409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15410 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15411 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15412 "NL80211_TDLS_ENABLE_LINK");
15413
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070015414 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
15415 {
15416 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
15417 MAC_ADDRESS_STR " failed",
15418 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
15419 return -EINVAL;
15420 }
15421
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053015422 /* before starting tdls connection, set tdls
15423 * off channel established status to default value */
15424 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015425 /* TDLS Off Channel, Disable tdls channel switch,
15426 when there are more than one tdls link */
15427 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053015428 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015429 {
15430 /* get connected peer and send disable tdls off chan */
15431 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015432 if ((connPeer) &&
15433 (connPeer->isOffChannelSupported == TRUE) &&
15434 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015435 {
15436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15437 "%s: More then one peer connected, Disable "
15438 "TDLS channel switch", __func__);
15439
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015440 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015441 ret = sme_SendTdlsChanSwitchReq(
15442 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015443 pAdapter->sessionId,
15444 connPeer->peerMac,
15445 connPeer->peerParams.channel,
15446 TDLS_OFF_CHANNEL_BW_OFFSET,
15447 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015448 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015449 hddLog(VOS_TRACE_LEVEL_ERROR,
15450 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015451 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015452 }
15453 else
15454 {
15455 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15456 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015457 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015458 "isOffChannelConfigured %d",
15459 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015460 (connPeer ? (connPeer->isOffChannelSupported)
15461 : -1),
15462 (connPeer ? (connPeer->isOffChannelConfigured)
15463 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015464 }
15465 }
15466
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015467 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015468 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015469 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053015470
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015471 if (0 != wlan_hdd_tdls_get_link_establish_params(
15472 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015473 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015474 return -EINVAL;
15475 }
15476 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015477
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015478 ret = sme_SendTdlsLinkEstablishParams(
15479 WLAN_HDD_GET_HAL_CTX(pAdapter),
15480 pAdapter->sessionId, peer,
15481 &tdlsLinkEstablishParams);
15482 if (ret != VOS_STATUS_SUCCESS) {
15483 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
15484 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015485 /* Send TDLS peer UAPSD capabilities to the firmware and
15486 * register with the TL on after the response for this operation
15487 * is received .
15488 */
15489 ret = wait_for_completion_interruptible_timeout(
15490 &pAdapter->tdls_link_establish_req_comp,
15491 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
15492 if (ret <= 0)
15493 {
15494 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015495 FL("Link Establish Request Failed Status %ld"),
15496 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015497 return -EINVAL;
15498 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015499 }
Atul Mittal115287b2014-07-08 13:26:33 +053015500 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15501 eTDLS_LINK_CONNECTED,
15502 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015503 staDesc.ucSTAId = pTdlsPeer->staId;
15504 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015505 ret = WLANTL_UpdateTdlsSTAClient(
15506 pHddCtx->pvosContext,
15507 &staDesc);
15508 if (ret != VOS_STATUS_SUCCESS) {
15509 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
15510 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053015511
Gopichand Nakkala471708b2013-06-04 20:03:01 +053015512 /* Mark TDLS client Authenticated .*/
15513 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
15514 pTdlsPeer->staId,
15515 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015516 if (VOS_STATUS_SUCCESS == status)
15517 {
Hoonki Lee14621352013-04-16 17:51:19 -070015518 if (pTdlsPeer->is_responder == 0)
15519 {
15520 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
15521
15522 wlan_hdd_tdls_timer_restart(pAdapter,
15523 &pTdlsPeer->initiatorWaitTimeoutTimer,
15524 WAIT_TIME_TDLS_INITIATOR);
15525 /* suspend initiator TX until it receives direct packet from the
15526 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015527 ret = WLANTL_SuspendDataTx(
15528 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15529 &staId, NULL);
15530 if (ret != VOS_STATUS_SUCCESS) {
15531 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
15532 }
Hoonki Lee14621352013-04-16 17:51:19 -070015533 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015534
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015535 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015536 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015537 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015538 suppChannelLen =
15539 tdlsLinkEstablishParams.supportedChannelsLen;
15540
15541 if ((suppChannelLen > 0) &&
15542 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
15543 {
15544 tANI_U8 suppPeerChannel = 0;
15545 int i = 0;
15546 for (i = 0U; i < suppChannelLen; i++)
15547 {
15548 suppPeerChannel =
15549 tdlsLinkEstablishParams.supportedChannels[i];
15550
15551 pTdlsPeer->isOffChannelSupported = FALSE;
15552 if (suppPeerChannel ==
15553 pTdlsPeer->peerParams.channel)
15554 {
15555 pTdlsPeer->isOffChannelSupported = TRUE;
15556 break;
15557 }
15558 }
15559 }
15560 else
15561 {
15562 pTdlsPeer->isOffChannelSupported = FALSE;
15563 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015564 }
15565 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15566 "%s: TDLS channel switch request for channel "
15567 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015568 "%d isOffChannelSupported %d", __func__,
15569 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015570 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015571 suppChannelLen,
15572 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015573
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015574 /* TDLS Off Channel, Enable tdls channel switch,
15575 when their is only one tdls link and it supports */
15576 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15577 if ((numCurrTdlsPeers == 1) &&
15578 (TRUE == pTdlsPeer->isOffChannelSupported) &&
15579 (TRUE == pTdlsPeer->isOffChannelConfigured))
15580 {
15581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15582 "%s: Send TDLS channel switch request for channel %d",
15583 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015584
15585 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015586 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
15587 pAdapter->sessionId,
15588 pTdlsPeer->peerMac,
15589 pTdlsPeer->peerParams.channel,
15590 TDLS_OFF_CHANNEL_BW_OFFSET,
15591 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015592 if (ret != VOS_STATUS_SUCCESS) {
15593 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
15594 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015595 }
15596 else
15597 {
15598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15599 "%s: TDLS channel switch request not sent"
15600 " numCurrTdlsPeers %d "
15601 "isOffChannelSupported %d "
15602 "isOffChannelConfigured %d",
15603 __func__, numCurrTdlsPeers,
15604 pTdlsPeer->isOffChannelSupported,
15605 pTdlsPeer->isOffChannelConfigured);
15606 }
15607
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015608 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015609 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015610
15611 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015612 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
15613 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015614 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015615 int ac;
15616 uint8 ucAc[4] = { WLANTL_AC_VO,
15617 WLANTL_AC_VI,
15618 WLANTL_AC_BK,
15619 WLANTL_AC_BE };
15620 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
15621 for(ac=0; ac < 4; ac++)
15622 {
15623 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15624 pTdlsPeer->staId, ucAc[ac],
15625 tlTid[ac], tlTid[ac], 0, 0,
15626 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015627 if (status != VOS_STATUS_SUCCESS) {
15628 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
15629 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015630 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015631 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015632 }
15633
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015634 }
15635 break;
15636 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080015637 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015638 tANI_U16 numCurrTdlsPeers = 0;
15639 hddTdlsPeer_t *connPeer = NULL;
15640
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015641 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15642 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
15643 __func__, MAC_ADDR_ARRAY(peer));
15644
Sunil Dutt41de4e22013-11-14 18:09:02 +053015645 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15646
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015647
Sunil Dutt41de4e22013-11-14 18:09:02 +053015648 if ( NULL == pTdlsPeer ) {
15649 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15650 " (oper %d) not exsting. ignored",
15651 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15652 return -EINVAL;
15653 }
15654
15655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15656 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15657 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15658 "NL80211_TDLS_DISABLE_LINK");
15659
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015660 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080015661 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015662 long status;
15663
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053015664 /* set tdls off channel status to false for this peer */
15665 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053015666 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15667 eTDLS_LINK_TEARING,
15668 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
15669 eTDLS_LINK_UNSPECIFIED:
15670 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015671 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
15672
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015673 status = sme_DeleteTdlsPeerSta(
15674 WLAN_HDD_GET_HAL_CTX(pAdapter),
15675 pAdapter->sessionId, peer );
15676 if (status != VOS_STATUS_SUCCESS) {
15677 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15678 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015679
15680 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
15681 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053015682 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053015683 eTDLS_LINK_IDLE,
15684 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015685 if (status <= 0)
15686 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15688 "%s: Del station failed status %ld",
15689 __func__, status);
15690 return -EPERM;
15691 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015692
15693 /* TDLS Off Channel, Enable tdls channel switch,
15694 when their is only one tdls link and it supports */
15695 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15696 if (numCurrTdlsPeers == 1)
15697 {
15698 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
15699 if ((connPeer) &&
15700 (connPeer->isOffChannelSupported == TRUE) &&
15701 (connPeer->isOffChannelConfigured == TRUE))
15702 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015703 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015704 status = sme_SendTdlsChanSwitchReq(
15705 WLAN_HDD_GET_HAL_CTX(pAdapter),
15706 pAdapter->sessionId,
15707 connPeer->peerMac,
15708 connPeer->peerParams.channel,
15709 TDLS_OFF_CHANNEL_BW_OFFSET,
15710 TDLS_CHANNEL_SWITCH_ENABLE);
15711 if (status != VOS_STATUS_SUCCESS) {
15712 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
15713 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015714 }
15715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15716 "%s: TDLS channel switch "
15717 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015718 "isOffChannelConfigured %d "
15719 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015720 __func__,
15721 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015722 (connPeer ? connPeer->isOffChannelConfigured : -1),
15723 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015724 }
15725 else
15726 {
15727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15728 "%s: TDLS channel switch request not sent "
15729 "numCurrTdlsPeers %d ",
15730 __func__, numCurrTdlsPeers);
15731 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015732 }
15733 else
15734 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15736 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080015737 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015738 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015739 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015740 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015741 {
Atul Mittal115287b2014-07-08 13:26:33 +053015742 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015743
Atul Mittal115287b2014-07-08 13:26:33 +053015744 if (0 != status)
15745 {
15746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015747 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053015748 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015749 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053015750 break;
15751 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015752 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015753 {
Atul Mittal115287b2014-07-08 13:26:33 +053015754 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
15755 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015756 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053015757 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015758
Atul Mittal115287b2014-07-08 13:26:33 +053015759 if (0 != status)
15760 {
15761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015762 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053015763 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053015764 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053015765 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015766 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015767 case NL80211_TDLS_DISCOVERY_REQ:
15768 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015769 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015770 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015771 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015772 return -ENOTSUPP;
15773 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15775 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015776 return -ENOTSUPP;
15777 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015778
15779 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015780 return 0;
15781}
Chilam NG571c65a2013-01-19 12:27:36 +053015782
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015783static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
15784 u8 *peer, enum nl80211_tdls_operation oper)
15785{
15786 int ret;
15787
15788 vos_ssr_protect(__func__);
15789 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
15790 vos_ssr_unprotect(__func__);
15791
15792 return ret;
15793}
15794
Chilam NG571c65a2013-01-19 12:27:36 +053015795int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
15796 struct net_device *dev, u8 *peer)
15797{
Arif Hussaina7c8e412013-11-20 11:06:42 -080015798 hddLog(VOS_TRACE_LEVEL_INFO,
15799 "tdls send discover req: "MAC_ADDRESS_STR,
15800 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053015801
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015802#if TDLS_MGMT_VERSION2
15803 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15804 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15805#else
Chilam NG571c65a2013-01-19 12:27:36 +053015806 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15807 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015808#endif
Chilam NG571c65a2013-01-19 12:27:36 +053015809}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015810#endif
15811
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015812#ifdef WLAN_FEATURE_GTK_OFFLOAD
15813/*
15814 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
15815 * Callback rountine called upon receiving response for
15816 * get offload info
15817 */
15818void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
15819 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
15820{
15821
15822 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015823 tANI_U8 tempReplayCounter[8];
15824 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015825
15826 ENTER();
15827
15828 if (NULL == pAdapter)
15829 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053015830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015831 "%s: HDD adapter is Null", __func__);
15832 return ;
15833 }
15834
15835 if (NULL == pGtkOffloadGetInfoRsp)
15836 {
15837 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15838 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
15839 return ;
15840 }
15841
15842 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
15843 {
15844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15845 "%s: wlan Failed to get replay counter value",
15846 __func__);
15847 return ;
15848 }
15849
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015850 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15851 /* Update replay counter */
15852 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
15853 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15854
15855 {
15856 /* changing from little to big endian since supplicant
15857 * works on big endian format
15858 */
15859 int i;
15860 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15861
15862 for (i = 0; i < 8; i++)
15863 {
15864 tempReplayCounter[7-i] = (tANI_U8)p[i];
15865 }
15866 }
15867
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015868 /* Update replay counter to NL */
15869 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015870 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015871}
15872
15873/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015874 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015875 * This function is used to offload GTK rekeying job to the firmware.
15876 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015877int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015878 struct cfg80211_gtk_rekey_data *data)
15879{
15880 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15881 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15882 hdd_station_ctx_t *pHddStaCtx;
15883 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015884 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015885 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015886 eHalStatus status = eHAL_STATUS_FAILURE;
15887
15888 ENTER();
15889
15890 if (NULL == pAdapter)
15891 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015892 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015893 "%s: HDD adapter is Null", __func__);
15894 return -ENODEV;
15895 }
15896
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015897 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15898 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
15899 pAdapter->sessionId, pAdapter->device_mode));
15900
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015901 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015902 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015903 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015904 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015905 }
15906
15907 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15908 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15909 if (NULL == hHal)
15910 {
15911 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15912 "%s: HAL context is Null!!!", __func__);
15913 return -EAGAIN;
15914 }
15915
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015916 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
15917 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
15918 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
15919 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015920 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015921 {
15922 /* changing from big to little endian since driver
15923 * works on little endian format
15924 */
15925 tANI_U8 *p =
15926 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
15927 int i;
15928
15929 for (i = 0; i < 8; i++)
15930 {
15931 p[7-i] = data->replay_ctr[i];
15932 }
15933 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015934
15935 if (TRUE == pHddCtx->hdd_wlan_suspended)
15936 {
15937 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015938 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
15939 sizeof (tSirGtkOffloadParams));
15940 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015941 pAdapter->sessionId);
15942
15943 if (eHAL_STATUS_SUCCESS != status)
15944 {
15945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15946 "%s: sme_SetGTKOffload failed, returned %d",
15947 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053015948
15949 /* Need to clear any trace of key value in the memory.
15950 * Thus zero out the memory even though it is local
15951 * variable.
15952 */
15953 vos_mem_zero(&hddGtkOffloadReqParams,
15954 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015955 return status;
15956 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15958 "%s: sme_SetGTKOffload successfull", __func__);
15959 }
15960 else
15961 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015962 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15963 "%s: wlan not suspended GTKOffload request is stored",
15964 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015965 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015966
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053015967 /* Need to clear any trace of key value in the memory.
15968 * Thus zero out the memory even though it is local
15969 * variable.
15970 */
15971 vos_mem_zero(&hddGtkOffloadReqParams,
15972 sizeof(hddGtkOffloadReqParams));
15973
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015974 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015975 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015976}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015977
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015978int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
15979 struct cfg80211_gtk_rekey_data *data)
15980{
15981 int ret;
15982
15983 vos_ssr_protect(__func__);
15984 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
15985 vos_ssr_unprotect(__func__);
15986
15987 return ret;
15988}
15989#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015990/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015991 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015992 * This function is used to set access control policy
15993 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015994static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
15995 struct net_device *dev,
15996 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015997{
15998 int i;
15999 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16000 hdd_hostapd_state_t *pHostapdState;
16001 tsap_Config_t *pConfig;
16002 v_CONTEXT_t pVosContext = NULL;
16003 hdd_context_t *pHddCtx;
16004 int status;
16005
16006 ENTER();
16007
16008 if (NULL == pAdapter)
16009 {
16010 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16011 "%s: HDD adapter is Null", __func__);
16012 return -ENODEV;
16013 }
16014
16015 if (NULL == params)
16016 {
16017 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16018 "%s: params is Null", __func__);
16019 return -EINVAL;
16020 }
16021
16022 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16023 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016024 if (0 != status)
16025 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016026 return status;
16027 }
16028
16029 pVosContext = pHddCtx->pvosContext;
16030 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
16031
16032 if (NULL == pHostapdState)
16033 {
16034 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16035 "%s: pHostapdState is Null", __func__);
16036 return -EINVAL;
16037 }
16038
16039 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
16040 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016041 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16042 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
16043 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016044
16045 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
16046 {
16047 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
16048
16049 /* default value */
16050 pConfig->num_accept_mac = 0;
16051 pConfig->num_deny_mac = 0;
16052
16053 /**
16054 * access control policy
16055 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
16056 * listed in hostapd.deny file.
16057 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
16058 * listed in hostapd.accept file.
16059 */
16060 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
16061 {
16062 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
16063 }
16064 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
16065 {
16066 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
16067 }
16068 else
16069 {
16070 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16071 "%s:Acl Policy : %d is not supported",
16072 __func__, params->acl_policy);
16073 return -ENOTSUPP;
16074 }
16075
16076 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
16077 {
16078 pConfig->num_accept_mac = params->n_acl_entries;
16079 for (i = 0; i < params->n_acl_entries; i++)
16080 {
16081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16082 "** Add ACL MAC entry %i in WhiletList :"
16083 MAC_ADDRESS_STR, i,
16084 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16085
16086 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
16087 sizeof(qcmacaddr));
16088 }
16089 }
16090 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
16091 {
16092 pConfig->num_deny_mac = params->n_acl_entries;
16093 for (i = 0; i < params->n_acl_entries; i++)
16094 {
16095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16096 "** Add ACL MAC entry %i in BlackList :"
16097 MAC_ADDRESS_STR, i,
16098 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16099
16100 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
16101 sizeof(qcmacaddr));
16102 }
16103 }
16104
16105 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
16106 {
16107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16108 "%s: SAP Set Mac Acl fail", __func__);
16109 return -EINVAL;
16110 }
16111 }
16112 else
16113 {
16114 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016115 "%s: Invalid device_mode = %s (%d)",
16116 __func__, hdd_device_modetoString(pAdapter->device_mode),
16117 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016118 return -EINVAL;
16119 }
16120
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016121 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016122 return 0;
16123}
16124
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016125static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16126 struct net_device *dev,
16127 const struct cfg80211_acl_data *params)
16128{
16129 int ret;
16130 vos_ssr_protect(__func__);
16131 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
16132 vos_ssr_unprotect(__func__);
16133
16134 return ret;
16135}
16136
Leo Chang9056f462013-08-01 19:21:11 -070016137#ifdef WLAN_NL80211_TESTMODE
16138#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070016139void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070016140(
16141 void *pAdapter,
16142 void *indCont
16143)
16144{
Leo Changd9df8aa2013-09-26 13:32:26 -070016145 tSirLPHBInd *lphbInd;
16146 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053016147 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070016148
16149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016150 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070016151
c_hpothu73f35e62014-04-18 13:40:08 +053016152 if (pAdapter == NULL)
16153 {
16154 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16155 "%s: pAdapter is NULL\n",__func__);
16156 return;
16157 }
16158
Leo Chang9056f462013-08-01 19:21:11 -070016159 if (NULL == indCont)
16160 {
16161 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016162 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070016163 return;
16164 }
16165
c_hpothu73f35e62014-04-18 13:40:08 +053016166 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070016167 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070016168 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053016169 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070016170 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070016171 GFP_ATOMIC);
16172 if (!skb)
16173 {
16174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16175 "LPHB timeout, NL buffer alloc fail");
16176 return;
16177 }
16178
Leo Changac3ba772013-10-07 09:47:04 -070016179 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070016180 {
16181 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16182 "WLAN_HDD_TM_ATTR_CMD put fail");
16183 goto nla_put_failure;
16184 }
Leo Changac3ba772013-10-07 09:47:04 -070016185 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070016186 {
16187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16188 "WLAN_HDD_TM_ATTR_TYPE put fail");
16189 goto nla_put_failure;
16190 }
Leo Changac3ba772013-10-07 09:47:04 -070016191 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070016192 sizeof(tSirLPHBInd), lphbInd))
16193 {
16194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16195 "WLAN_HDD_TM_ATTR_DATA put fail");
16196 goto nla_put_failure;
16197 }
Leo Chang9056f462013-08-01 19:21:11 -070016198 cfg80211_testmode_event(skb, GFP_ATOMIC);
16199 return;
16200
16201nla_put_failure:
16202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16203 "NLA Put fail");
16204 kfree_skb(skb);
16205
16206 return;
16207}
16208#endif /* FEATURE_WLAN_LPHB */
16209
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016210static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070016211{
16212 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
16213 int err = 0;
16214#ifdef FEATURE_WLAN_LPHB
16215 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070016216 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016217
16218 ENTER();
16219
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016220 err = wlan_hdd_validate_context(pHddCtx);
16221 if (0 != err)
16222 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016223 return err;
16224 }
Leo Chang9056f462013-08-01 19:21:11 -070016225#endif /* FEATURE_WLAN_LPHB */
16226
16227 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
16228 if (err)
16229 {
16230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16231 "%s Testmode INV ATTR", __func__);
16232 return err;
16233 }
16234
16235 if (!tb[WLAN_HDD_TM_ATTR_CMD])
16236 {
16237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16238 "%s Testmode INV CMD", __func__);
16239 return -EINVAL;
16240 }
16241
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016242 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16243 TRACE_CODE_HDD_CFG80211_TESTMODE,
16244 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070016245 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
16246 {
16247#ifdef FEATURE_WLAN_LPHB
16248 /* Low Power Heartbeat configuration request */
16249 case WLAN_HDD_TM_CMD_WLAN_HB:
16250 {
16251 int buf_len;
16252 void *buf;
16253 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080016254 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070016255
16256 if (!tb[WLAN_HDD_TM_ATTR_DATA])
16257 {
16258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16259 "%s Testmode INV DATA", __func__);
16260 return -EINVAL;
16261 }
16262
16263 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
16264 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080016265
16266 hb_params_temp =(tSirLPHBReq *)buf;
16267 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
16268 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
16269 return -EINVAL;
16270
Leo Chang9056f462013-08-01 19:21:11 -070016271 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
16272 if (NULL == hb_params)
16273 {
16274 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16275 "%s Request Buffer Alloc Fail", __func__);
16276 return -EINVAL;
16277 }
16278
16279 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070016280 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
16281 hb_params,
16282 wlan_hdd_cfg80211_lphb_ind_handler);
16283 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070016284 {
Leo Changd9df8aa2013-09-26 13:32:26 -070016285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16286 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070016287 vos_mem_free(hb_params);
16288 }
Leo Chang9056f462013-08-01 19:21:11 -070016289 return 0;
16290 }
16291#endif /* FEATURE_WLAN_LPHB */
16292 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16294 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070016295 return -EOPNOTSUPP;
16296 }
16297
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016298 EXIT();
16299 return err;
Leo Chang9056f462013-08-01 19:21:11 -070016300}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016301
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053016302static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
16303#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
16304 struct wireless_dev *wdev,
16305#endif
16306 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016307{
16308 int ret;
16309
16310 vos_ssr_protect(__func__);
16311 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
16312 vos_ssr_unprotect(__func__);
16313
16314 return ret;
16315}
Leo Chang9056f462013-08-01 19:21:11 -070016316#endif /* CONFIG_NL80211_TESTMODE */
16317
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016318static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016319 struct net_device *dev,
16320 int idx, struct survey_info *survey)
16321{
16322 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16323 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053016324 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016325 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053016326 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016327 v_S7_t snr,rssi;
16328 int status, i, j, filled = 0;
16329
16330 ENTER();
16331
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016332 if (NULL == pAdapter)
16333 {
16334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16335 "%s: HDD adapter is Null", __func__);
16336 return -ENODEV;
16337 }
16338
16339 if (NULL == wiphy)
16340 {
16341 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16342 "%s: wiphy is Null", __func__);
16343 return -ENODEV;
16344 }
16345
16346 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16347 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016348 if (0 != status)
16349 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016350 return status;
16351 }
16352
Mihir Sheted9072e02013-08-21 17:02:29 +053016353 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16354
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016355 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053016356 0 != pAdapter->survey_idx ||
16357 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016358 {
16359 /* The survey dump ops when implemented completely is expected to
16360 * return a survey of all channels and the ops is called by the
16361 * kernel with incremental values of the argument 'idx' till it
16362 * returns -ENONET. But we can only support the survey for the
16363 * operating channel for now. survey_idx is used to track
16364 * that the ops is called only once and then return -ENONET for
16365 * the next iteration
16366 */
16367 pAdapter->survey_idx = 0;
16368 return -ENONET;
16369 }
16370
Mukul Sharma9d5233b2015-06-11 20:28:20 +053016371 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16372 {
16373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16374 "%s: Roaming in progress, hence return ", __func__);
16375 return -ENONET;
16376 }
16377
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016378 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16379
16380 wlan_hdd_get_snr(pAdapter, &snr);
16381 wlan_hdd_get_rssi(pAdapter, &rssi);
16382
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016383 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16384 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
16385 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016386 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
16387 hdd_wlan_get_freq(channel, &freq);
16388
16389
16390 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
16391 {
16392 if (NULL == wiphy->bands[i])
16393 {
16394 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
16395 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
16396 continue;
16397 }
16398
16399 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
16400 {
16401 struct ieee80211_supported_band *band = wiphy->bands[i];
16402
16403 if (band->channels[j].center_freq == (v_U16_t)freq)
16404 {
16405 survey->channel = &band->channels[j];
16406 /* The Rx BDs contain SNR values in dB for the received frames
16407 * while the supplicant expects noise. So we calculate and
16408 * return the value of noise (dBm)
16409 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
16410 */
16411 survey->noise = rssi - snr;
16412 survey->filled = SURVEY_INFO_NOISE_DBM;
16413 filled = 1;
16414 }
16415 }
16416 }
16417
16418 if (filled)
16419 pAdapter->survey_idx = 1;
16420 else
16421 {
16422 pAdapter->survey_idx = 0;
16423 return -ENONET;
16424 }
16425
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016426 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016427 return 0;
16428}
16429
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016430static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
16431 struct net_device *dev,
16432 int idx, struct survey_info *survey)
16433{
16434 int ret;
16435
16436 vos_ssr_protect(__func__);
16437 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
16438 vos_ssr_unprotect(__func__);
16439
16440 return ret;
16441}
16442
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016443/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016444 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016445 * this is called when cfg80211 driver resume
16446 * driver updates latest sched_scan scan result(if any) to cfg80211 database
16447 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016448int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016449{
16450 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16451 hdd_adapter_t *pAdapter;
16452 hdd_adapter_list_node_t *pAdapterNode, *pNext;
16453 VOS_STATUS status = VOS_STATUS_SUCCESS;
16454
16455 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016456
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016457 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016458 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016459 return 0;
16460 }
16461
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016462 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
16463 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016464 spin_lock(&pHddCtx->schedScan_lock);
16465 pHddCtx->isWiphySuspended = FALSE;
16466 if (TRUE != pHddCtx->isSchedScanUpdatePending)
16467 {
16468 spin_unlock(&pHddCtx->schedScan_lock);
16469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16470 "%s: Return resume is not due to PNO indication", __func__);
16471 return 0;
16472 }
16473 // Reset flag to avoid updatating cfg80211 data old results again
16474 pHddCtx->isSchedScanUpdatePending = FALSE;
16475 spin_unlock(&pHddCtx->schedScan_lock);
16476
16477 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
16478
16479 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
16480 {
16481 pAdapter = pAdapterNode->pAdapter;
16482 if ( (NULL != pAdapter) &&
16483 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
16484 {
16485 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016486 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16488 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016489 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016490 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016491 {
16492 /* Acquire wakelock to handle the case where APP's tries to
16493 * suspend immediately after updating the scan results. Whis
16494 * results in app's is in suspended state and not able to
16495 * process the connect request to AP
16496 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053016497 hdd_prevent_suspend_timeout(2000,
16498 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016499 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016500 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016501
16502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16503 "%s : cfg80211 scan result database updated", __func__);
16504
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016505 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016506 return 0;
16507
16508 }
16509 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16510 pAdapterNode = pNext;
16511 }
16512
16513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16514 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016515 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016516 return 0;
16517}
16518
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016519int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
16520{
16521 int ret;
16522
16523 vos_ssr_protect(__func__);
16524 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
16525 vos_ssr_unprotect(__func__);
16526
16527 return ret;
16528}
16529
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016530/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016531 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016532 * this is called when cfg80211 driver suspends
16533 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016534int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016535 struct cfg80211_wowlan *wow)
16536{
16537 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016538 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016539
16540 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016541
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016542 ret = wlan_hdd_validate_context(pHddCtx);
16543 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016544 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016545 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016546 }
16547
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016548
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016549 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16550 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
16551 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016552 pHddCtx->isWiphySuspended = TRUE;
16553
16554 EXIT();
16555
16556 return 0;
16557}
16558
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016559int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
16560 struct cfg80211_wowlan *wow)
16561{
16562 int ret;
16563
16564 vos_ssr_protect(__func__);
16565 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
16566 vos_ssr_unprotect(__func__);
16567
16568 return ret;
16569}
Jeff Johnson295189b2012-06-20 16:38:30 -070016570/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016571static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070016572{
16573 .add_virtual_intf = wlan_hdd_add_virtual_intf,
16574 .del_virtual_intf = wlan_hdd_del_virtual_intf,
16575 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
16576 .change_station = wlan_hdd_change_station,
16577#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
16578 .add_beacon = wlan_hdd_cfg80211_add_beacon,
16579 .del_beacon = wlan_hdd_cfg80211_del_beacon,
16580 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016581#else
16582 .start_ap = wlan_hdd_cfg80211_start_ap,
16583 .change_beacon = wlan_hdd_cfg80211_change_beacon,
16584 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070016585#endif
16586 .change_bss = wlan_hdd_cfg80211_change_bss,
16587 .add_key = wlan_hdd_cfg80211_add_key,
16588 .get_key = wlan_hdd_cfg80211_get_key,
16589 .del_key = wlan_hdd_cfg80211_del_key,
16590 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016591#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070016592 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016593#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016594 .scan = wlan_hdd_cfg80211_scan,
16595 .connect = wlan_hdd_cfg80211_connect,
16596 .disconnect = wlan_hdd_cfg80211_disconnect,
16597 .join_ibss = wlan_hdd_cfg80211_join_ibss,
16598 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
16599 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
16600 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
16601 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070016602 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
16603 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053016604 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070016605#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16606 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
16607 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
16608 .set_txq_params = wlan_hdd_set_txq_params,
16609#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016610 .get_station = wlan_hdd_cfg80211_get_station,
16611 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
16612 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016613 .add_station = wlan_hdd_cfg80211_add_station,
16614#ifdef FEATURE_WLAN_LFR
16615 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
16616 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
16617 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
16618#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016619#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
16620 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
16621#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016622#ifdef FEATURE_WLAN_TDLS
16623 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
16624 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
16625#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016626#ifdef WLAN_FEATURE_GTK_OFFLOAD
16627 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
16628#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016629#ifdef FEATURE_WLAN_SCAN_PNO
16630 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
16631 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
16632#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016633 .resume = wlan_hdd_cfg80211_resume_wlan,
16634 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016635 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070016636#ifdef WLAN_NL80211_TESTMODE
16637 .testmode_cmd = wlan_hdd_cfg80211_testmode,
16638#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016639 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070016640};
16641