blob: 9a4ed7b36315b8ebafac376eb27e3e15cb8ac753 [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
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05304710static int wlan_hdd_cfg80211_exttdls_callback(
4711#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
4712 const tANI_U8* mac,
4713#else
4714 tANI_U8* mac,
4715#endif
Atul Mittal115287b2014-07-08 13:26:33 +05304716 tANI_S32 state,
4717 tANI_S32 reason,
4718 void *ctx)
4719{
4720 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05304721 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304722 tANI_S32 global_operating_class = 0;
4723 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304724 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05304725
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304726 ENTER();
4727
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304728 if (!pAdapter) {
4729 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4730 return -EINVAL;
4731 }
4732
4733 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05304734 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304735 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304736 return -EINVAL;
4737 }
4738
4739 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304740 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304741 return -ENOTSUPP;
4742 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304743 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
4744#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4745 NULL,
4746#endif
Atul Mittal115287b2014-07-08 13:26:33 +05304747 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4748 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4749 GFP_KERNEL);
4750
4751 if (!skb) {
4752 hddLog(VOS_TRACE_LEVEL_ERROR,
4753 FL("cfg80211_vendor_event_alloc failed"));
4754 return -EINVAL;
4755 }
4756 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304757 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4758 reason,
4759 state,
4760 global_operating_class,
4761 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304762 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4763 MAC_ADDR_ARRAY(mac));
4764
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304765 if (nla_put(skb,
4766 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4767 VOS_MAC_ADDR_SIZE, mac) ||
4768 nla_put_s32(skb,
4769 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4770 state) ||
4771 nla_put_s32(skb,
4772 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4773 reason) ||
4774 nla_put_s32(skb,
4775 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4776 channel) ||
4777 nla_put_s32(skb,
4778 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4779 global_operating_class)
4780 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304781 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4782 goto nla_put_failure;
4783 }
4784
4785 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304786 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05304787 return (0);
4788
4789nla_put_failure:
4790 kfree_skb(skb);
4791 return -EINVAL;
4792}
4793
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304794static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304795 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304796 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304797 int data_len)
4798{
4799 u8 peer[6] = {0};
4800 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304801 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4802 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4803 eHalStatus status;
4804 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304805 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304806 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304807
4808 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304809
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304810 if (!dev) {
4811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4812 return -EINVAL;
4813 }
4814
4815 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4816 if (!pAdapter) {
4817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4818 return -EINVAL;
4819 }
4820
Atul Mittal115287b2014-07-08 13:26:33 +05304821 status = wlan_hdd_validate_context(pHddCtx);
4822 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304823 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304824 return -EINVAL;
4825 }
4826 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304828 return -ENOTSUPP;
4829 }
4830 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4831 data, data_len,
4832 wlan_hdd_tdls_config_enable_policy)) {
4833 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4834 return -EINVAL;
4835 }
4836
4837 /* Parse and fetch mac address */
4838 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4839 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4840 return -EINVAL;
4841 }
4842
4843 memcpy(peer, nla_data(
4844 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4845 sizeof(peer));
4846 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4847
4848 /* Parse and fetch channel */
4849 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4850 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4851 return -EINVAL;
4852 }
4853 pReqMsg.channel = nla_get_s32(
4854 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4855 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4856
4857 /* Parse and fetch global operating class */
4858 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4859 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4860 return -EINVAL;
4861 }
4862 pReqMsg.global_operating_class = nla_get_s32(
4863 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4864 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4865 pReqMsg.global_operating_class);
4866
4867 /* Parse and fetch latency ms */
4868 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4869 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4870 return -EINVAL;
4871 }
4872 pReqMsg.max_latency_ms = nla_get_s32(
4873 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4874 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4875 pReqMsg.max_latency_ms);
4876
4877 /* Parse and fetch required bandwidth kbps */
4878 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4879 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4880 return -EINVAL;
4881 }
4882
4883 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4884 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4885 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4886 pReqMsg.min_bandwidth_kbps);
4887
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304888 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05304889 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05304890 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304891 wlan_hdd_cfg80211_exttdls_callback);
4892
4893 EXIT();
4894 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304895}
4896
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304897static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4898 struct wireless_dev *wdev,
4899 const void *data,
4900 int data_len)
4901{
4902 int ret = 0;
4903
4904 vos_ssr_protect(__func__);
4905 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
4906 vos_ssr_unprotect(__func__);
4907
4908 return ret;
4909}
4910
4911static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304912 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304913 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304914 int data_len)
4915{
4916 u8 peer[6] = {0};
4917 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304918 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4919 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4920 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304921 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304922 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304923
4924 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304925
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304926 if (!dev) {
4927 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4928 return -EINVAL;
4929 }
4930
4931 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4932 if (!pAdapter) {
4933 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
4934 return -EINVAL;
4935 }
4936
Atul Mittal115287b2014-07-08 13:26:33 +05304937 status = wlan_hdd_validate_context(pHddCtx);
4938 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304939 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304940 return -EINVAL;
4941 }
4942 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304943 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304944 return -ENOTSUPP;
4945 }
4946 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4947 data, data_len,
4948 wlan_hdd_tdls_config_disable_policy)) {
4949 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4950 return -EINVAL;
4951 }
4952 /* Parse and fetch mac address */
4953 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4954 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4955 return -EINVAL;
4956 }
4957
4958 memcpy(peer, nla_data(
4959 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4960 sizeof(peer));
4961 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4962
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304963 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
4964
4965 EXIT();
4966 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304967}
4968
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304969static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4970 struct wireless_dev *wdev,
4971 const void *data,
4972 int data_len)
4973{
4974 int ret = 0;
4975
4976 vos_ssr_protect(__func__);
4977 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
4978 vos_ssr_unprotect(__func__);
4979
4980 return ret;
4981}
4982
Dasari Srinivas7875a302014-09-26 17:50:57 +05304983static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304984__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05304985 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304986 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05304987{
4988 struct net_device *dev = wdev->netdev;
4989 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4990 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4991 struct sk_buff *skb = NULL;
4992 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304993 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05304994
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304995 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304996
4997 ret = wlan_hdd_validate_context(pHddCtx);
4998 if (0 != ret)
4999 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305000 return ret;
5001 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305002 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5003 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5004 fset |= WIFI_FEATURE_INFRA;
5005 }
5006
5007 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5008 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5009 fset |= WIFI_FEATURE_INFRA_5G;
5010 }
5011
5012#ifdef WLAN_FEATURE_P2P
5013 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5014 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5015 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5016 fset |= WIFI_FEATURE_P2P;
5017 }
5018#endif
5019
5020 /* Soft-AP is supported currently by default */
5021 fset |= WIFI_FEATURE_SOFT_AP;
5022
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305023 /* HOTSPOT is a supplicant feature, enable it by default */
5024 fset |= WIFI_FEATURE_HOTSPOT;
5025
Dasari Srinivas7875a302014-09-26 17:50:57 +05305026#ifdef WLAN_FEATURE_EXTSCAN
5027 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
5028 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
5029 hddLog(LOG1, FL("EXTScan is supported by firmware"));
5030 fset |= WIFI_FEATURE_EXTSCAN;
5031 }
5032#endif
5033
Dasari Srinivas7875a302014-09-26 17:50:57 +05305034 if (sme_IsFeatureSupportedByFW(NAN)) {
5035 hddLog(LOG1, FL("NAN is supported by firmware"));
5036 fset |= WIFI_FEATURE_NAN;
5037 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305038
5039 /* D2D RTT is not supported currently by default */
5040 if (sme_IsFeatureSupportedByFW(RTT)) {
5041 hddLog(LOG1, FL("RTT is supported by firmware"));
5042 fset |= WIFI_FEATURE_D2AP_RTT;
5043 }
5044
5045#ifdef FEATURE_WLAN_BATCH_SCAN
5046 if (fset & WIFI_FEATURE_EXTSCAN) {
5047 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5048 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5049 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5050 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5051 fset |= WIFI_FEATURE_BATCH_SCAN;
5052 }
5053#endif
5054
5055#ifdef FEATURE_WLAN_SCAN_PNO
5056 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5057 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5058 hddLog(LOG1, FL("PNO is supported by firmware"));
5059 fset |= WIFI_FEATURE_PNO;
5060 }
5061#endif
5062
5063 /* STA+STA is supported currently by default */
5064 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5065
5066#ifdef FEATURE_WLAN_TDLS
5067 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5068 sme_IsFeatureSupportedByFW(TDLS)) {
5069 hddLog(LOG1, FL("TDLS is supported by firmware"));
5070 fset |= WIFI_FEATURE_TDLS;
5071 }
5072
5073 /* TDLS_OFFCHANNEL is not supported currently by default */
5074#endif
5075
5076#ifdef WLAN_AP_STA_CONCURRENCY
5077 /* AP+STA concurrency is supported currently by default */
5078 fset |= WIFI_FEATURE_AP_STA;
5079#endif
5080
5081 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5082 NLMSG_HDRLEN);
5083
5084 if (!skb) {
5085 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5086 return -EINVAL;
5087 }
5088 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5089
5090 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5091 hddLog(LOGE, FL("nla put fail"));
5092 goto nla_put_failure;
5093 }
5094
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305095 ret = cfg80211_vendor_cmd_reply(skb);
5096 EXIT();
5097 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305098
5099nla_put_failure:
5100 kfree_skb(skb);
5101 return -EINVAL;
5102}
5103
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305104static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305105wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5106 struct wireless_dev *wdev,
5107 const void *data, int data_len)
5108{
5109 int ret = 0;
5110
5111 vos_ssr_protect(__func__);
5112 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5113 vos_ssr_unprotect(__func__);
5114
5115 return ret;
5116}
5117
5118static int
5119__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305120 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305121 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305122{
5123 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5124 uint8_t i, feature_sets, max_feature_sets;
5125 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5126 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305127 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5128 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305129
5130 ENTER();
5131
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305132 ret = wlan_hdd_validate_context(pHddCtx);
5133 if (0 != ret)
5134 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305135 return ret;
5136 }
5137
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305138 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5139 data, data_len, NULL)) {
5140 hddLog(LOGE, FL("Invalid ATTR"));
5141 return -EINVAL;
5142 }
5143
5144 /* Parse and fetch max feature set */
5145 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5146 hddLog(LOGE, FL("Attr max feature set size failed"));
5147 return -EINVAL;
5148 }
5149 max_feature_sets = nla_get_u32(
5150 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5151 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5152
5153 /* Fill feature combination matrix */
5154 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305155 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5156 WIFI_FEATURE_P2P;
5157
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305158 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5159 WIFI_FEATURE_SOFT_AP;
5160
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305161 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5162 WIFI_FEATURE_SOFT_AP;
5163
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305164 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5165 WIFI_FEATURE_SOFT_AP |
5166 WIFI_FEATURE_P2P;
5167
5168 /* Add more feature combinations here */
5169
5170 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5171 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5172 hddLog(LOG1, "Feature set matrix");
5173 for (i = 0; i < feature_sets; i++)
5174 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5175
5176 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5177 sizeof(u32) * feature_sets +
5178 NLMSG_HDRLEN);
5179
5180 if (reply_skb) {
5181 if (nla_put_u32(reply_skb,
5182 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5183 feature_sets) ||
5184 nla_put(reply_skb,
5185 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5186 sizeof(u32) * feature_sets, feature_set_matrix)) {
5187 hddLog(LOGE, FL("nla put fail"));
5188 kfree_skb(reply_skb);
5189 return -EINVAL;
5190 }
5191
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305192 ret = cfg80211_vendor_cmd_reply(reply_skb);
5193 EXIT();
5194 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305195 }
5196 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5197 return -ENOMEM;
5198
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305199}
5200
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305201static int
5202wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5203 struct wireless_dev *wdev,
5204 const void *data, int data_len)
5205{
5206 int ret = 0;
5207
5208 vos_ssr_protect(__func__);
5209 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5210 data_len);
5211 vos_ssr_unprotect(__func__);
5212
5213 return ret;
5214}
5215
Agarwal Ashish738843c2014-09-25 12:27:56 +05305216static const struct nla_policy
5217wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5218 +1] =
5219{
5220 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5221};
5222
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305223static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305224 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305225 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305226 int data_len)
5227{
5228 struct net_device *dev = wdev->netdev;
5229 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5230 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5231 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5232 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5233 eHalStatus status;
5234 u32 dfsFlag = 0;
5235
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305236 ENTER();
5237
Agarwal Ashish738843c2014-09-25 12:27:56 +05305238 status = wlan_hdd_validate_context(pHddCtx);
5239 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305240 return -EINVAL;
5241 }
5242 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5243 data, data_len,
5244 wlan_hdd_set_no_dfs_flag_config_policy)) {
5245 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5246 return -EINVAL;
5247 }
5248
5249 /* Parse and fetch required bandwidth kbps */
5250 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5251 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5252 return -EINVAL;
5253 }
5254
5255 dfsFlag = nla_get_u32(
5256 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5257 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5258 dfsFlag);
5259
5260 pHddCtx->disable_dfs_flag = dfsFlag;
5261
5262 sme_disable_dfs_channel(hHal, dfsFlag);
5263 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305264
5265 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305266 return 0;
5267}
Atul Mittal115287b2014-07-08 13:26:33 +05305268
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305269static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5270 struct wireless_dev *wdev,
5271 const void *data,
5272 int data_len)
5273{
5274 int ret = 0;
5275
5276 vos_ssr_protect(__func__);
5277 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5278 vos_ssr_unprotect(__func__);
5279
5280 return ret;
5281
5282}
5283
Mukul Sharma2a271632014-10-13 14:59:01 +05305284const struct
5285nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5286{
5287 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5288 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5289};
5290
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305291static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305292 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305293{
5294
5295 u8 bssid[6] = {0};
5296 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5297 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5298 eHalStatus status = eHAL_STATUS_SUCCESS;
5299 v_U32_t isFwrRoamEnabled = FALSE;
5300 int ret;
5301
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305302 ENTER();
5303
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305304 ret = wlan_hdd_validate_context(pHddCtx);
5305 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305306 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305307 }
5308
5309 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5310 data, data_len,
5311 qca_wlan_vendor_attr);
5312 if (ret){
5313 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5314 return -EINVAL;
5315 }
5316
5317 /* Parse and fetch Enable flag */
5318 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5319 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5320 return -EINVAL;
5321 }
5322
5323 isFwrRoamEnabled = nla_get_u32(
5324 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5325
5326 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5327
5328 /* Parse and fetch bssid */
5329 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5330 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5331 return -EINVAL;
5332 }
5333
5334 memcpy(bssid, nla_data(
5335 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5336 sizeof(bssid));
5337 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5338
5339 //Update roaming
5340 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305341 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305342 return status;
5343}
5344
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305345static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5346 struct wireless_dev *wdev, const void *data, int data_len)
5347{
5348 int ret = 0;
5349
5350 vos_ssr_protect(__func__);
5351 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5352 vos_ssr_unprotect(__func__);
5353
5354 return ret;
5355}
5356
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305357/**
5358 * __wlan_hdd_cfg80211_setband() - set band
5359 * @wiphy: Pointer to wireless phy
5360 * @wdev: Pointer to wireless device
5361 * @data: Pointer to data
5362 * @data_len: Data length
5363 *
5364 * Return: 0 on success, negative errno on failure
5365 */
5366static int
5367__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5368 struct wireless_dev *wdev,
5369 const void *data,
5370 int data_len)
5371{
5372 struct net_device *dev = wdev->netdev;
5373 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5374 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5375 int ret;
5376 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
5377 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
5378
5379 ENTER();
5380
5381 ret = wlan_hdd_validate_context(hdd_ctx);
5382 if (0 != ret) {
5383 hddLog(LOGE, FL("HDD context is not valid"));
5384 return ret;
5385 }
5386
5387 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
5388 policy)) {
5389 hddLog(LOGE, FL("Invalid ATTR"));
5390 return -EINVAL;
5391 }
5392
5393 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
5394 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
5395 return -EINVAL;
5396 }
5397
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305398 hdd_ctx->isSetBandByNL = TRUE;
5399 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305400 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305401 hdd_ctx->isSetBandByNL = FALSE;
5402
5403 EXIT();
5404 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305405}
5406
5407/**
5408 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
5409 * @wiphy: wiphy structure pointer
5410 * @wdev: Wireless device structure pointer
5411 * @data: Pointer to the data received
5412 * @data_len: Length of @data
5413 *
5414 * Return: 0 on success; errno on failure
5415 */
5416static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5417 struct wireless_dev *wdev,
5418 const void *data,
5419 int data_len)
5420{
5421 int ret = 0;
5422
5423 vos_ssr_protect(__func__);
5424 ret = __wlan_hdd_cfg80211_setband(wiphy,
5425 wdev, data, data_len);
5426 vos_ssr_unprotect(__func__);
5427
5428 return ret;
5429}
5430
Sunil Duttc69bccb2014-05-26 21:30:20 +05305431const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
5432{
Mukul Sharma2a271632014-10-13 14:59:01 +05305433 {
5434 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5435 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
5436 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5437 WIPHY_VENDOR_CMD_NEED_NETDEV |
5438 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305439 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05305440 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305441
5442 {
5443 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5444 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
5445 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5446 WIPHY_VENDOR_CMD_NEED_NETDEV |
5447 WIPHY_VENDOR_CMD_NEED_RUNNING,
5448 .doit = wlan_hdd_cfg80211_nan_request
5449 },
5450
Sunil Duttc69bccb2014-05-26 21:30:20 +05305451#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5452 {
5453 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5454 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
5455 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5456 WIPHY_VENDOR_CMD_NEED_NETDEV |
5457 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305458 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05305459 },
5460
5461 {
5462 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5463 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
5464 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5465 WIPHY_VENDOR_CMD_NEED_NETDEV |
5466 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305467 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05305468 },
5469
5470 {
5471 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5472 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
5473 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5474 WIPHY_VENDOR_CMD_NEED_NETDEV |
5475 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305476 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05305477 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305478#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305479#ifdef WLAN_FEATURE_EXTSCAN
5480 {
5481 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5482 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
5483 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5484 WIPHY_VENDOR_CMD_NEED_NETDEV |
5485 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305486 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05305487 },
5488 {
5489 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5490 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
5491 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5492 WIPHY_VENDOR_CMD_NEED_NETDEV |
5493 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305494 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05305495 },
5496 {
5497 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5498 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
5499 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5500 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305501 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05305502 },
5503 {
5504 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5505 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
5506 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5507 WIPHY_VENDOR_CMD_NEED_NETDEV |
5508 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305509 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05305510 },
5511 {
5512 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5513 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
5514 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5515 WIPHY_VENDOR_CMD_NEED_NETDEV |
5516 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305517 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05305518 },
5519 {
5520 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5521 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
5522 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5523 WIPHY_VENDOR_CMD_NEED_NETDEV |
5524 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305525 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305526 },
5527 {
5528 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5529 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
5530 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5531 WIPHY_VENDOR_CMD_NEED_NETDEV |
5532 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305533 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305534 },
5535 {
5536 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5537 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
5538 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5539 WIPHY_VENDOR_CMD_NEED_NETDEV |
5540 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305541 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305542 },
5543 {
5544 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5545 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
5546 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5547 WIPHY_VENDOR_CMD_NEED_NETDEV |
5548 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305549 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305550 },
5551#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305552/*EXT TDLS*/
5553 {
5554 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5555 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
5556 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5557 WIPHY_VENDOR_CMD_NEED_NETDEV |
5558 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305559 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05305560 },
5561 {
5562 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5563 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
5564 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5565 WIPHY_VENDOR_CMD_NEED_NETDEV |
5566 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305567 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05305568 },
5569 {
5570 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5571 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
5572 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5573 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305574 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05305575 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05305576 {
5577 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5578 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
5579 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5580 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305581 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05305582 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05305583 {
5584 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5585 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
5586 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5587 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305588 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05305589 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305590 {
5591 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5592 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
5593 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5594 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305595 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305596 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305597 {
5598 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5599 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
5600 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5601 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305602 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305603 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305604 {
5605 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5606 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
5607 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5608 WIPHY_VENDOR_CMD_NEED_NETDEV |
5609 WIPHY_VENDOR_CMD_NEED_RUNNING,
5610 .doit = wlan_hdd_cfg80211_setband
5611 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05305612};
5613
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005614/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05305615static const
5616struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005617{
5618#ifdef FEATURE_WLAN_CH_AVOID
5619 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05305620 .vendor_id = QCA_NL80211_VENDOR_ID,
5621 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005622 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305623#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
5624#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5625 {
5626 /* Index = 1*/
5627 .vendor_id = QCA_NL80211_VENDOR_ID,
5628 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
5629 },
5630 {
5631 /* Index = 2*/
5632 .vendor_id = QCA_NL80211_VENDOR_ID,
5633 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
5634 },
5635 {
5636 /* Index = 3*/
5637 .vendor_id = QCA_NL80211_VENDOR_ID,
5638 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
5639 },
5640 {
5641 /* Index = 4*/
5642 .vendor_id = QCA_NL80211_VENDOR_ID,
5643 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
5644 },
5645 {
5646 /* Index = 5*/
5647 .vendor_id = QCA_NL80211_VENDOR_ID,
5648 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
5649 },
5650 {
5651 /* Index = 6*/
5652 .vendor_id = QCA_NL80211_VENDOR_ID,
5653 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
5654 },
5655#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305656#ifdef WLAN_FEATURE_EXTSCAN
5657 {
5658 .vendor_id = QCA_NL80211_VENDOR_ID,
5659 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
5660 },
5661 {
5662 .vendor_id = QCA_NL80211_VENDOR_ID,
5663 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
5664 },
5665 {
5666 .vendor_id = QCA_NL80211_VENDOR_ID,
5667 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
5668 },
5669 {
5670 .vendor_id = QCA_NL80211_VENDOR_ID,
5671 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
5672 },
5673 {
5674 .vendor_id = QCA_NL80211_VENDOR_ID,
5675 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
5676 },
5677 {
5678 .vendor_id = QCA_NL80211_VENDOR_ID,
5679 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
5680 },
5681 {
5682 .vendor_id = QCA_NL80211_VENDOR_ID,
5683 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
5684 },
5685 {
5686 .vendor_id = QCA_NL80211_VENDOR_ID,
5687 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
5688 },
5689 {
5690 .vendor_id = QCA_NL80211_VENDOR_ID,
5691 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
5692 },
5693 {
5694 .vendor_id = QCA_NL80211_VENDOR_ID,
5695 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
5696 },
5697 {
5698 .vendor_id = QCA_NL80211_VENDOR_ID,
5699 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
5700 },
5701 {
5702 .vendor_id = QCA_NL80211_VENDOR_ID,
5703 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
5704 },
5705 {
5706 .vendor_id = QCA_NL80211_VENDOR_ID,
5707 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
5708 },
5709#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305710/*EXT TDLS*/
5711 {
5712 .vendor_id = QCA_NL80211_VENDOR_ID,
5713 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
5714 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305715
5716 {
5717 .vendor_id = QCA_NL80211_VENDOR_ID,
5718 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
5719 },
5720
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005721};
5722
Jeff Johnson295189b2012-06-20 16:38:30 -07005723/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305724 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305725 * This function is called by hdd_wlan_startup()
5726 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305727 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07005728 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305729struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07005730{
5731 struct wiphy *wiphy;
5732 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305733 /*
5734 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07005735 */
5736 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
5737
5738 if (!wiphy)
5739 {
5740 /* Print error and jump into err label and free the memory */
5741 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
5742 return NULL;
5743 }
5744
Sunil Duttc69bccb2014-05-26 21:30:20 +05305745
Jeff Johnson295189b2012-06-20 16:38:30 -07005746 return wiphy;
5747}
5748
5749/*
5750 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305751 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07005752 * private ioctl to change the band value
5753 */
5754int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
5755{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305756 int i, j;
5757 eNVChannelEnabledType channelEnabledState;
5758
Jeff Johnsone7245742012-09-05 17:12:55 -07005759 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305760
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305761 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005762 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305763
5764 if (NULL == wiphy->bands[i])
5765 {
5766 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5767 __func__, i);
5768 continue;
5769 }
5770
5771 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5772 {
5773 struct ieee80211_supported_band *band = wiphy->bands[i];
5774
5775 channelEnabledState = vos_nv_getChannelEnabledState(
5776 band->channels[j].hw_value);
5777
5778 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
5779 {
Abhishek Singh678227a2014-11-04 10:52:38 +05305780 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305781 continue;
5782 }
5783 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
5784 {
5785 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5786 continue;
5787 }
5788
5789 if (NV_CHANNEL_DISABLE == channelEnabledState ||
5790 NV_CHANNEL_INVALID == channelEnabledState)
5791 {
5792 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5793 }
5794 else if (NV_CHANNEL_DFS == channelEnabledState)
5795 {
5796 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5797 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
5798 }
5799 else
5800 {
5801 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
5802 |IEEE80211_CHAN_RADAR);
5803 }
5804 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005805 }
5806 return 0;
5807}
5808/*
5809 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305810 * This function is called by hdd_wlan_startup()
5811 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005812 * This function is used to initialize and register wiphy structure.
5813 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305814int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005815 struct wiphy *wiphy,
5816 hdd_config_t *pCfg
5817 )
5818{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305819 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305820 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5821
Jeff Johnsone7245742012-09-05 17:12:55 -07005822 ENTER();
5823
Jeff Johnson295189b2012-06-20 16:38:30 -07005824 /* Now bind the underlying wlan device with wiphy */
5825 set_wiphy_dev(wiphy, dev);
5826
5827 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005828
Kiet Lam6c583332013-10-14 05:37:09 +05305829#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005830 /* the flag for the other case would be initialzed in
5831 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005832 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305833#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005834
Amar Singhalfddc28c2013-09-05 13:03:40 -07005835 /* This will disable updating of NL channels from passive to
5836 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05305837#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
5838 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
5839#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07005840 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05305841#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07005842
Amar Singhala49cbc52013-10-08 18:37:44 -07005843
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005844#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005845 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5846 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5847 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005848 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05305849#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
5850 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
5851#else
5852 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
5853#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005854#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005855
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005856#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005857 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005858#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005859 || pCfg->isFastRoamIniFeatureEnabled
5860#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005861#ifdef FEATURE_WLAN_ESE
5862 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005863#endif
5864 )
5865 {
5866 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5867 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005868#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005869#ifdef FEATURE_WLAN_TDLS
5870 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5871 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5872#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305873#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305874 if (pCfg->configPNOScanSupport)
5875 {
5876 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5877 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5878 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5879 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5880 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305881#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005882
Abhishek Singh10d85972015-04-17 10:27:23 +05305883#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5884 wiphy->features |= NL80211_FEATURE_HT_IBSS;
5885#endif
5886
Amar Singhalfddc28c2013-09-05 13:03:40 -07005887#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005888 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5889 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005890 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005891 driver need to determine what to do with both
5892 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005893
5894 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005895#else
5896 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005897#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005898
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305899 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5900
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05305901 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005902
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305903 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5904
Jeff Johnson295189b2012-06-20 16:38:30 -07005905 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05305906 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
5907 | BIT(NL80211_IFTYPE_ADHOC)
5908 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5909 | BIT(NL80211_IFTYPE_P2P_GO)
5910 | BIT(NL80211_IFTYPE_AP);
5911
5912 if (VOS_MONITOR_MODE == hdd_get_conparam())
5913 {
5914 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
5915 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005916
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305917 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005918 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305919#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5920 if( pCfg->enableMCC )
5921 {
5922 /* Currently, supports up to two channels */
5923 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005924
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305925 if( !pCfg->allowMCCGODiffBI )
5926 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005927
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305928 }
5929 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5930 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005931#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305932 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005933
Jeff Johnson295189b2012-06-20 16:38:30 -07005934 /* Before registering we need to update the ht capabilitied based
5935 * on ini values*/
5936 if( !pCfg->ShortGI20MhzEnable )
5937 {
5938 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5939 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5940 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5941 }
5942
5943 if( !pCfg->ShortGI40MhzEnable )
5944 {
5945 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5946 }
5947
5948 if( !pCfg->nChannelBondingMode5GHz )
5949 {
5950 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5951 }
5952
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305953 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305954 if (true == hdd_is_5g_supported(pHddCtx))
5955 {
5956 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5957 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305958
5959 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5960 {
5961
5962 if (NULL == wiphy->bands[i])
5963 {
5964 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5965 __func__, i);
5966 continue;
5967 }
5968
5969 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5970 {
5971 struct ieee80211_supported_band *band = wiphy->bands[i];
5972
5973 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5974 {
5975 // Enable social channels for P2P
5976 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5977 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5978 else
5979 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5980 continue;
5981 }
5982 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5983 {
5984 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5985 continue;
5986 }
5987 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005988 }
5989 /*Initialise the supported cipher suite details*/
5990 wiphy->cipher_suites = hdd_cipher_suites;
5991 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5992
5993 /*signal strength in mBm (100*dBm) */
5994 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5995
5996#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305997 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005998#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005999
Sunil Duttc69bccb2014-05-26 21:30:20 +05306000 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
6001 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006002 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
6003 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
6004
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306005 EXIT();
6006 return 0;
6007}
6008
6009/* In this function we are registering wiphy. */
6010int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
6011{
6012 ENTER();
6013 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006014 if (0 > wiphy_register(wiphy))
6015 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306016 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07006017 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
6018 return -EIO;
6019 }
6020
6021 EXIT();
6022 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306023}
Jeff Johnson295189b2012-06-20 16:38:30 -07006024
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306025/* In this function we are updating channel list when,
6026 regulatory domain is FCC and country code is US.
6027 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
6028 As per FCC smart phone is not a indoor device.
6029 GO should not opeate on indoor channels */
6030void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
6031{
6032 int j;
6033 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6034 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
6035 //Default counrtycode from NV at the time of wiphy initialization.
6036 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
6037 &defaultCountryCode[0]))
6038 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006039 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306040 }
6041 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
6042 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306043 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
6044 {
6045 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
6046 return;
6047 }
6048 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
6049 {
6050 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
6051 // Mark UNII -1 band channel as passive
6052 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
6053 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
6054 }
6055 }
6056}
6057
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306058/* This function registers for all frame which supplicant is interested in */
6059void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006060{
Jeff Johnson295189b2012-06-20 16:38:30 -07006061 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6062 /* Register for all P2P action, public action etc frames */
6063 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6064
Jeff Johnsone7245742012-09-05 17:12:55 -07006065 ENTER();
6066
Jeff Johnson295189b2012-06-20 16:38:30 -07006067 /* Right now we are registering these frame when driver is getting
6068 initialized. Once we will move to 2.6.37 kernel, in which we have
6069 frame register ops, we will move this code as a part of that */
6070 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306071 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006072 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6073
6074 /* GAS Initial Response */
6075 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6076 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306077
Jeff Johnson295189b2012-06-20 16:38:30 -07006078 /* GAS Comeback Request */
6079 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6080 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6081
6082 /* GAS Comeback Response */
6083 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6084 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6085
6086 /* P2P Public Action */
6087 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306088 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006089 P2P_PUBLIC_ACTION_FRAME_SIZE );
6090
6091 /* P2P Action */
6092 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6093 (v_U8_t*)P2P_ACTION_FRAME,
6094 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07006095
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05306096 /* WNM BSS Transition Request frame */
6097 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6098 (v_U8_t*)WNM_BSS_ACTION_FRAME,
6099 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006100
6101 /* WNM-Notification */
6102 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6103 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6104 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006105}
6106
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306107void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006108{
Jeff Johnson295189b2012-06-20 16:38:30 -07006109 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6110 /* Register for all P2P action, public action etc frames */
6111 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6112
Jeff Johnsone7245742012-09-05 17:12:55 -07006113 ENTER();
6114
Jeff Johnson295189b2012-06-20 16:38:30 -07006115 /* Right now we are registering these frame when driver is getting
6116 initialized. Once we will move to 2.6.37 kernel, in which we have
6117 frame register ops, we will move this code as a part of that */
6118 /* GAS Initial Request */
6119
6120 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6121 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6122
6123 /* GAS Initial Response */
6124 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6125 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306126
Jeff Johnson295189b2012-06-20 16:38:30 -07006127 /* GAS Comeback Request */
6128 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6129 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6130
6131 /* GAS Comeback Response */
6132 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6133 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6134
6135 /* P2P Public Action */
6136 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306137 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006138 P2P_PUBLIC_ACTION_FRAME_SIZE );
6139
6140 /* P2P Action */
6141 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6142 (v_U8_t*)P2P_ACTION_FRAME,
6143 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006144 /* WNM-Notification */
6145 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6146 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6147 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006148}
6149
6150#ifdef FEATURE_WLAN_WAPI
6151void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
6152 const u8 *mac_addr, u8 *key , int key_Len)
6153{
6154 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6155 tCsrRoamSetKey setKey;
6156 v_BOOL_t isConnected = TRUE;
6157 int status = 0;
6158 v_U32_t roamId= 0xFF;
6159 tANI_U8 *pKeyPtr = NULL;
6160 int n = 0;
6161
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306162 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6163 __func__, hdd_device_modetoString(pAdapter->device_mode),
6164 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006165
Gopichand Nakkalae7480202013-02-11 15:24:22 +05306166 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006167 setKey.keyId = key_index; // Store Key ID
6168 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
6169 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
6170 setKey.paeRole = 0 ; // the PAE role
6171 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
6172 {
6173 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
6174 }
6175 else
6176 {
6177 isConnected = hdd_connIsConnected(pHddStaCtx);
6178 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
6179 }
6180 setKey.keyLength = key_Len;
6181 pKeyPtr = setKey.Key;
6182 memcpy( pKeyPtr, key, key_Len);
6183
Arif Hussain6d2a3322013-11-17 19:50:10 -08006184 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07006185 __func__, key_Len);
6186 for (n = 0 ; n < key_Len; n++)
6187 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
6188 __func__,n,setKey.Key[n]);
6189
6190 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
6191 if ( isConnected )
6192 {
6193 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
6194 pAdapter->sessionId, &setKey, &roamId );
6195 }
6196 if ( status != 0 )
6197 {
6198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6199 "[%4d] sme_RoamSetKey returned ERROR status= %d",
6200 __LINE__, status );
6201 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
6202 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05306203 /* Need to clear any trace of key value in the memory.
6204 * Thus zero out the memory even though it is local
6205 * variable.
6206 */
6207 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006208}
6209#endif /* FEATURE_WLAN_WAPI*/
6210
6211#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306212int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006213 beacon_data_t **ppBeacon,
6214 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006215#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306216int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006217 beacon_data_t **ppBeacon,
6218 struct cfg80211_beacon_data *params,
6219 int dtim_period)
6220#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306221{
Jeff Johnson295189b2012-06-20 16:38:30 -07006222 int size;
6223 beacon_data_t *beacon = NULL;
6224 beacon_data_t *old = NULL;
6225 int head_len,tail_len;
6226
Jeff Johnsone7245742012-09-05 17:12:55 -07006227 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006228 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306229 {
6230 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6231 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006232 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306233 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006234
6235 old = pAdapter->sessionCtx.ap.beacon;
6236
6237 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306238 {
6239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6240 FL("session(%d) old and new heads points to NULL"),
6241 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006242 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306243 }
6244
6245 if (params->tail && !params->tail_len)
6246 {
6247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6248 FL("tail_len is zero but tail is not NULL"));
6249 return -EINVAL;
6250 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006251
Jeff Johnson295189b2012-06-20 16:38:30 -07006252#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
6253 /* Kernel 3.0 is not updating dtim_period for set beacon */
6254 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306255 {
6256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6257 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006258 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306259 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006260#endif
6261
6262 if(params->head)
6263 head_len = params->head_len;
6264 else
6265 head_len = old->head_len;
6266
6267 if(params->tail || !old)
6268 tail_len = params->tail_len;
6269 else
6270 tail_len = old->tail_len;
6271
6272 size = sizeof(beacon_data_t) + head_len + tail_len;
6273
6274 beacon = kzalloc(size, GFP_KERNEL);
6275
6276 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306277 {
6278 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6279 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006280 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306281 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006282
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006283#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006284 if(params->dtim_period || !old )
6285 beacon->dtim_period = params->dtim_period;
6286 else
6287 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006288#else
6289 if(dtim_period || !old )
6290 beacon->dtim_period = dtim_period;
6291 else
6292 beacon->dtim_period = old->dtim_period;
6293#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306294
Jeff Johnson295189b2012-06-20 16:38:30 -07006295 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6296 beacon->tail = beacon->head + head_len;
6297 beacon->head_len = head_len;
6298 beacon->tail_len = tail_len;
6299
6300 if(params->head) {
6301 memcpy (beacon->head,params->head,beacon->head_len);
6302 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306303 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07006304 if(old)
6305 memcpy (beacon->head,old->head,beacon->head_len);
6306 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306307
Jeff Johnson295189b2012-06-20 16:38:30 -07006308 if(params->tail) {
6309 memcpy (beacon->tail,params->tail,beacon->tail_len);
6310 }
6311 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306312 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07006313 memcpy (beacon->tail,old->tail,beacon->tail_len);
6314 }
6315
6316 *ppBeacon = beacon;
6317
6318 kfree(old);
6319
6320 return 0;
6321
6322}
Jeff Johnson295189b2012-06-20 16:38:30 -07006323
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306324v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
6325#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6326 const v_U8_t *pIes,
6327#else
6328 v_U8_t *pIes,
6329#endif
6330 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006331{
6332 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306333 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07006334 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306335
Jeff Johnson295189b2012-06-20 16:38:30 -07006336 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306337 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006338 elem_id = ptr[0];
6339 elem_len = ptr[1];
6340 left -= 2;
6341 if(elem_len > left)
6342 {
6343 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006344 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006345 eid,elem_len,left);
6346 return NULL;
6347 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306348 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006349 {
6350 return ptr;
6351 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306352
Jeff Johnson295189b2012-06-20 16:38:30 -07006353 left -= elem_len;
6354 ptr += (elem_len + 2);
6355 }
6356 return NULL;
6357}
6358
Jeff Johnson295189b2012-06-20 16:38:30 -07006359/* Check if rate is 11g rate or not */
6360static int wlan_hdd_rate_is_11g(u8 rate)
6361{
Sanjay Devnani28322e22013-06-21 16:13:40 -07006362 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006363 u8 i;
6364 for (i = 0; i < 8; i++)
6365 {
6366 if(rate == gRateArray[i])
6367 return TRUE;
6368 }
6369 return FALSE;
6370}
6371
6372/* Check for 11g rate and set proper 11g only mode */
6373static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
6374 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
6375{
6376 u8 i, num_rates = pIe[0];
6377
6378 pIe += 1;
6379 for ( i = 0; i < num_rates; i++)
6380 {
6381 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
6382 {
6383 /* If rate set have 11g rate than change the mode to 11G */
6384 *pSapHw_mode = eSAP_DOT11_MODE_11g;
6385 if (pIe[i] & BASIC_RATE_MASK)
6386 {
6387 /* If we have 11g rate as basic rate, it means mode
6388 is 11g only mode.
6389 */
6390 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
6391 *pCheckRatesfor11g = FALSE;
6392 }
6393 }
6394 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6395 {
6396 *require_ht = TRUE;
6397 }
6398 }
6399 return;
6400}
6401
6402static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
6403{
6404 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6405 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6406 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6407 u8 checkRatesfor11g = TRUE;
6408 u8 require_ht = FALSE;
6409 u8 *pIe=NULL;
6410
6411 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
6412
6413 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6414 pBeacon->head_len, WLAN_EID_SUPP_RATES);
6415 if (pIe != NULL)
6416 {
6417 pIe += 1;
6418 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6419 &pConfig->SapHw_mode);
6420 }
6421
6422 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6423 WLAN_EID_EXT_SUPP_RATES);
6424 if (pIe != NULL)
6425 {
6426
6427 pIe += 1;
6428 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6429 &pConfig->SapHw_mode);
6430 }
6431
6432 if( pConfig->channel > 14 )
6433 {
6434 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
6435 }
6436
6437 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6438 WLAN_EID_HT_CAPABILITY);
6439
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306440 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006441 {
6442 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
6443 if(require_ht)
6444 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
6445 }
6446}
6447
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306448static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
6449 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
6450{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006451 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306452 v_U8_t *pIe = NULL;
6453 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6454
6455 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6456 pBeacon->tail, pBeacon->tail_len);
6457
6458 if (pIe)
6459 {
6460 ielen = pIe[1] + 2;
6461 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6462 {
6463 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
6464 }
6465 else
6466 {
6467 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
6468 return -EINVAL;
6469 }
6470 *total_ielen += ielen;
6471 }
6472 return 0;
6473}
6474
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006475static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
6476 v_U8_t *genie, v_U8_t *total_ielen)
6477{
6478 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6479 int left = pBeacon->tail_len;
6480 v_U8_t *ptr = pBeacon->tail;
6481 v_U8_t elem_id, elem_len;
6482 v_U16_t ielen = 0;
6483
6484 if ( NULL == ptr || 0 == left )
6485 return;
6486
6487 while (left >= 2)
6488 {
6489 elem_id = ptr[0];
6490 elem_len = ptr[1];
6491 left -= 2;
6492 if (elem_len > left)
6493 {
6494 hddLog( VOS_TRACE_LEVEL_ERROR,
6495 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
6496 elem_id, elem_len, left);
6497 return;
6498 }
6499 if (IE_EID_VENDOR == elem_id)
6500 {
6501 /* skipping the VSIE's which we don't want to include or
6502 * it will be included by existing code
6503 */
6504 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
6505#ifdef WLAN_FEATURE_WFD
6506 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
6507#endif
6508 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6509 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6510 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
6511 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6512 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
6513 {
6514 ielen = ptr[1] + 2;
6515 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6516 {
6517 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
6518 *total_ielen += ielen;
6519 }
6520 else
6521 {
6522 hddLog( VOS_TRACE_LEVEL_ERROR,
6523 "IE Length is too big "
6524 "IEs eid=%d elem_len=%d total_ie_lent=%d",
6525 elem_id, elem_len, *total_ielen);
6526 }
6527 }
6528 }
6529
6530 left -= elem_len;
6531 ptr += (elem_len + 2);
6532 }
6533 return;
6534}
6535
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006536#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006537static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6538 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006539#else
6540static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6541 struct cfg80211_beacon_data *params)
6542#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006543{
6544 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306545 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006546 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07006547 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006548
6549 genie = vos_mem_malloc(MAX_GENIE_LEN);
6550
6551 if(genie == NULL) {
6552
6553 return -ENOMEM;
6554 }
6555
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306556 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6557 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006558 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306559 hddLog(LOGE,
6560 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306561 ret = -EINVAL;
6562 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006563 }
6564
6565#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306566 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6567 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
6568 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306569 hddLog(LOGE,
6570 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306571 ret = -EINVAL;
6572 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006573 }
6574#endif
6575
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306576 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6577 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006578 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306579 hddLog(LOGE,
6580 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306581 ret = -EINVAL;
6582 goto done;
6583 }
6584
6585 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
6586 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006587 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07006588 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006589
6590 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6591 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
6592 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6593 {
6594 hddLog(LOGE,
6595 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006596 ret = -EINVAL;
6597 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006598 }
6599
6600 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6601 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6602 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6603 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6604 ==eHAL_STATUS_FAILURE)
6605 {
6606 hddLog(LOGE,
6607 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006608 ret = -EINVAL;
6609 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006610 }
6611
6612 // Added for ProResp IE
6613 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
6614 {
6615 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
6616 u8 probe_rsp_ie_len[3] = {0};
6617 u8 counter = 0;
6618 /* Check Probe Resp Length if it is greater then 255 then Store
6619 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
6620 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
6621 Store More then 255 bytes into One Variable.
6622 */
6623 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6624 {
6625 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6626 {
6627 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6628 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6629 }
6630 else
6631 {
6632 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6633 rem_probe_resp_ie_len = 0;
6634 }
6635 }
6636
6637 rem_probe_resp_ie_len = 0;
6638
6639 if (probe_rsp_ie_len[0] > 0)
6640 {
6641 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6642 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6643 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6644 probe_rsp_ie_len[0], NULL,
6645 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6646 {
6647 hddLog(LOGE,
6648 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006649 ret = -EINVAL;
6650 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006651 }
6652 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6653 }
6654
6655 if (probe_rsp_ie_len[1] > 0)
6656 {
6657 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6658 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6659 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6660 probe_rsp_ie_len[1], NULL,
6661 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6662 {
6663 hddLog(LOGE,
6664 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006665 ret = -EINVAL;
6666 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006667 }
6668 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6669 }
6670
6671 if (probe_rsp_ie_len[2] > 0)
6672 {
6673 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6674 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6675 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6676 probe_rsp_ie_len[2], NULL,
6677 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6678 {
6679 hddLog(LOGE,
6680 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006681 ret = -EINVAL;
6682 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006683 }
6684 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6685 }
6686
6687 if (probe_rsp_ie_len[1] == 0 )
6688 {
6689 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6690 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (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_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006695 }
6696 }
6697
6698 if (probe_rsp_ie_len[2] == 0 )
6699 {
6700 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6701 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6702 eANI_BOOLEAN_FALSE) )
6703 {
6704 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006705 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006706 }
6707 }
6708
6709 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6710 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6711 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6712 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6713 == eHAL_STATUS_FAILURE)
6714 {
6715 hddLog(LOGE,
6716 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006717 ret = -EINVAL;
6718 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006719 }
6720 }
6721 else
6722 {
6723 // Reset WNI_CFG_PROBE_RSP Flags
6724 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
6725
6726 hddLog(VOS_TRACE_LEVEL_INFO,
6727 "%s: No Probe Response IE received in set beacon",
6728 __func__);
6729 }
6730
6731 // Added for AssocResp IE
6732 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
6733 {
6734 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6735 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
6736 params->assocresp_ies_len, NULL,
6737 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6738 {
6739 hddLog(LOGE,
6740 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006741 ret = -EINVAL;
6742 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006743 }
6744
6745 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6746 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
6747 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6748 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6749 == eHAL_STATUS_FAILURE)
6750 {
6751 hddLog(LOGE,
6752 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006753 ret = -EINVAL;
6754 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006755 }
6756 }
6757 else
6758 {
6759 hddLog(VOS_TRACE_LEVEL_INFO,
6760 "%s: No Assoc Response IE received in set beacon",
6761 __func__);
6762
6763 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6764 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6765 eANI_BOOLEAN_FALSE) )
6766 {
6767 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006768 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006769 }
6770 }
6771
Jeff Johnsone7245742012-09-05 17:12:55 -07006772done:
Jeff Johnson295189b2012-06-20 16:38:30 -07006773 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306774 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006775}
Jeff Johnson295189b2012-06-20 16:38:30 -07006776
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306777/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006778 * FUNCTION: wlan_hdd_validate_operation_channel
6779 * called by wlan_hdd_cfg80211_start_bss() and
6780 * wlan_hdd_cfg80211_set_channel()
6781 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306782 * channel list.
6783 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006784VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006785{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306786
Jeff Johnson295189b2012-06-20 16:38:30 -07006787 v_U32_t num_ch = 0;
6788 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6789 u32 indx = 0;
6790 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306791 v_U8_t fValidChannel = FALSE, count = 0;
6792 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306793
Jeff Johnson295189b2012-06-20 16:38:30 -07006794 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6795
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306796 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006797 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306798 /* Validate the channel */
6799 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006800 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306801 if ( channel == rfChannels[count].channelNum )
6802 {
6803 fValidChannel = TRUE;
6804 break;
6805 }
6806 }
6807 if (fValidChannel != TRUE)
6808 {
6809 hddLog(VOS_TRACE_LEVEL_ERROR,
6810 "%s: Invalid Channel [%d]", __func__, channel);
6811 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006812 }
6813 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306814 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006815 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306816 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6817 valid_ch, &num_ch))
6818 {
6819 hddLog(VOS_TRACE_LEVEL_ERROR,
6820 "%s: failed to get valid channel list", __func__);
6821 return VOS_STATUS_E_FAILURE;
6822 }
6823 for (indx = 0; indx < num_ch; indx++)
6824 {
6825 if (channel == valid_ch[indx])
6826 {
6827 break;
6828 }
6829 }
6830
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306831 if (indx >= num_ch)
6832 {
6833 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6834 {
6835 eCsrBand band;
6836 unsigned int freq;
6837
6838 sme_GetFreqBand(hHal, &band);
6839
6840 if (eCSR_BAND_5G == band)
6841 {
6842#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6843 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6844 {
6845 freq = ieee80211_channel_to_frequency(channel,
6846 IEEE80211_BAND_2GHZ);
6847 }
6848 else
6849 {
6850 freq = ieee80211_channel_to_frequency(channel,
6851 IEEE80211_BAND_5GHZ);
6852 }
6853#else
6854 freq = ieee80211_channel_to_frequency(channel);
6855#endif
6856 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6857 return VOS_STATUS_SUCCESS;
6858 }
6859 }
6860
6861 hddLog(VOS_TRACE_LEVEL_ERROR,
6862 "%s: Invalid Channel [%d]", __func__, channel);
6863 return VOS_STATUS_E_FAILURE;
6864 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006865 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306866
Jeff Johnson295189b2012-06-20 16:38:30 -07006867 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306868
Jeff Johnson295189b2012-06-20 16:38:30 -07006869}
6870
Viral Modi3a32cc52013-02-08 11:14:52 -08006871/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306872 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08006873 * This function is used to set the channel number
6874 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306875static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08006876 struct ieee80211_channel *chan,
6877 enum nl80211_channel_type channel_type
6878 )
6879{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306880 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006881 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006882 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006883 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306884 hdd_context_t *pHddCtx;
6885 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006886
6887 ENTER();
6888
6889 if( NULL == dev )
6890 {
6891 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006892 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006893 return -ENODEV;
6894 }
6895 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306896
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306897 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6898 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6899 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006900 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306901 "%s: device_mode = %s (%d) freq = %d", __func__,
6902 hdd_device_modetoString(pAdapter->device_mode),
6903 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306904
6905 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6906 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306907 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006908 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306909 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006910 }
6911
6912 /*
6913 * Do freq to chan conversion
6914 * TODO: for 11a
6915 */
6916
6917 channel = ieee80211_frequency_to_channel(freq);
6918
6919 /* Check freq range */
6920 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6921 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6922 {
6923 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006924 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006925 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6926 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6927 return -EINVAL;
6928 }
6929
6930 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6931
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306932 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6933 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006934 {
6935 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6936 {
6937 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006938 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006939 return -EINVAL;
6940 }
6941 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6942 "%s: set channel to [%d] for device mode =%d",
6943 __func__, channel,pAdapter->device_mode);
6944 }
6945 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006946 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006947 )
6948 {
6949 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6950 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6951 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6952
6953 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6954 {
6955 /* Link is up then return cant set channel*/
6956 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006957 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006958 return -EINVAL;
6959 }
6960
6961 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6962 pHddStaCtx->conn_info.operationChannel = channel;
6963 pRoamProfile->ChannelInfo.ChannelList =
6964 &pHddStaCtx->conn_info.operationChannel;
6965 }
6966 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006967 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006968 )
6969 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306970 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6971 {
6972 if(VOS_STATUS_SUCCESS !=
6973 wlan_hdd_validate_operation_channel(pAdapter,channel))
6974 {
6975 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006976 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306977 return -EINVAL;
6978 }
6979 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6980 }
6981 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006982 {
6983 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6984
6985 /* If auto channel selection is configured as enable/ 1 then ignore
6986 channel set by supplicant
6987 */
6988 if ( cfg_param->apAutoChannelSelection )
6989 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306990 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6991 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006992 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306993 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6994 __func__, hdd_device_modetoString(pAdapter->device_mode),
6995 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006996 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306997 else
6998 {
6999 if(VOS_STATUS_SUCCESS !=
7000 wlan_hdd_validate_operation_channel(pAdapter,channel))
7001 {
7002 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007003 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307004 return -EINVAL;
7005 }
7006 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7007 }
Viral Modi3a32cc52013-02-08 11:14:52 -08007008 }
7009 }
7010 else
7011 {
7012 hddLog(VOS_TRACE_LEVEL_FATAL,
7013 "%s: Invalid device mode failed to set valid channel", __func__);
7014 return -EINVAL;
7015 }
7016 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307017 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007018}
7019
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307020static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
7021 struct net_device *dev,
7022 struct ieee80211_channel *chan,
7023 enum nl80211_channel_type channel_type
7024 )
7025{
7026 int ret;
7027
7028 vos_ssr_protect(__func__);
7029 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
7030 vos_ssr_unprotect(__func__);
7031
7032 return ret;
7033}
7034
Jeff Johnson295189b2012-06-20 16:38:30 -07007035#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7036static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7037 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007038#else
7039static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7040 struct cfg80211_beacon_data *params,
7041 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307042 enum nl80211_hidden_ssid hidden_ssid,
7043 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007044#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007045{
7046 tsap_Config_t *pConfig;
7047 beacon_data_t *pBeacon = NULL;
7048 struct ieee80211_mgmt *pMgmt_frame;
7049 v_U8_t *pIe=NULL;
7050 v_U16_t capab_info;
7051 eCsrAuthType RSNAuthType;
7052 eCsrEncryptionType RSNEncryptType;
7053 eCsrEncryptionType mcRSNEncryptType;
7054 int status = VOS_STATUS_SUCCESS;
7055 tpWLAN_SAPEventCB pSapEventCallback;
7056 hdd_hostapd_state_t *pHostapdState;
7057 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
7058 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307059 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007060 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307061 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07007062 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08007063 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05307064 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07007065 v_BOOL_t MFPCapable = VOS_FALSE;
7066 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307067 v_BOOL_t sapEnable11AC =
7068 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07007069 ENTER();
7070
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307071 iniConfig = pHddCtx->cfg_ini;
7072
Jeff Johnson295189b2012-06-20 16:38:30 -07007073 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7074
7075 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7076
7077 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7078
7079 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7080
7081 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7082
7083 //channel is already set in the set_channel Call back
7084 //pConfig->channel = pCommitConfig->channel;
7085
7086 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307087 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07007088 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
7089
7090 pConfig->dtim_period = pBeacon->dtim_period;
7091
Arif Hussain6d2a3322013-11-17 19:50:10 -08007092 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07007093 pConfig->dtim_period);
7094
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08007095 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07007096 {
7097 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007098 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05307099 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
7100 {
7101 tANI_BOOLEAN restartNeeded;
7102 pConfig->ieee80211d = 1;
7103 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
7104 sme_setRegInfo(hHal, pConfig->countryCode);
7105 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
7106 }
7107 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007108 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07007109 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07007110 pConfig->ieee80211d = 1;
7111 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
7112 sme_setRegInfo(hHal, pConfig->countryCode);
7113 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07007114 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007115 else
7116 {
7117 pConfig->ieee80211d = 0;
7118 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307119 /*
7120 * If auto channel is configured i.e. channel is 0,
7121 * so skip channel validation.
7122 */
7123 if( AUTO_CHANNEL_SELECT != pConfig->channel )
7124 {
7125 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
7126 {
7127 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007128 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307129 return -EINVAL;
7130 }
7131 }
7132 else
7133 {
7134 if(1 != pHddCtx->is_dynamic_channel_range_set)
7135 {
7136 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
7137 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
7138 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
7139 }
7140 pHddCtx->is_dynamic_channel_range_set = 0;
7141 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007142 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007143 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007144 {
7145 pConfig->ieee80211d = 0;
7146 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307147
7148#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7149 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7150 pConfig->authType = eSAP_OPEN_SYSTEM;
7151 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7152 pConfig->authType = eSAP_SHARED_KEY;
7153 else
7154 pConfig->authType = eSAP_AUTO_SWITCH;
7155#else
7156 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7157 pConfig->authType = eSAP_OPEN_SYSTEM;
7158 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7159 pConfig->authType = eSAP_SHARED_KEY;
7160 else
7161 pConfig->authType = eSAP_AUTO_SWITCH;
7162#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007163
7164 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307165
7166 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07007167 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
7168
7169 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7170
7171 /*Set wps station to configured*/
7172 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7173
7174 if(pIe)
7175 {
7176 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
7177 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007178 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07007179 return -EINVAL;
7180 }
7181 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
7182 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007183 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07007184 /* Check 15 bit of WPS IE as it contain information for wps state
7185 * WPS state
7186 */
7187 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
7188 {
7189 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
7190 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
7191 {
7192 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7193 }
7194 }
7195 }
7196 else
7197 {
7198 pConfig->wps_state = SAP_WPS_DISABLED;
7199 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307200 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07007201
c_hpothufe599e92014-06-16 11:38:55 +05307202 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7203 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7204 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7205 eCSR_ENCRYPT_TYPE_NONE;
7206
Jeff Johnson295189b2012-06-20 16:38:30 -07007207 pConfig->RSNWPAReqIELength = 0;
7208 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307209 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007210 WLAN_EID_RSN);
7211 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307212 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007213 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7214 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7215 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307216 /* The actual processing may eventually be more extensive than
7217 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07007218 * by the app.
7219 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307220 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007221 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7222 &RSNEncryptType,
7223 &mcRSNEncryptType,
7224 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007225 &MFPCapable,
7226 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007227 pConfig->pRSNWPAReqIE[1]+2,
7228 pConfig->pRSNWPAReqIE );
7229
7230 if( VOS_STATUS_SUCCESS == status )
7231 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307232 /* Now copy over all the security attributes you have
7233 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007234 * */
7235 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7236 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7237 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7238 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307239 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007240 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007241 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7242 }
7243 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307244
Jeff Johnson295189b2012-06-20 16:38:30 -07007245 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7246 pBeacon->tail, pBeacon->tail_len);
7247
7248 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
7249 {
7250 if (pConfig->pRSNWPAReqIE)
7251 {
7252 /*Mixed mode WPA/WPA2*/
7253 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
7254 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7255 }
7256 else
7257 {
7258 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7259 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7260 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307261 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007262 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7263 &RSNEncryptType,
7264 &mcRSNEncryptType,
7265 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007266 &MFPCapable,
7267 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007268 pConfig->pRSNWPAReqIE[1]+2,
7269 pConfig->pRSNWPAReqIE );
7270
7271 if( VOS_STATUS_SUCCESS == status )
7272 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307273 /* Now copy over all the security attributes you have
7274 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007275 * */
7276 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7277 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7278 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7279 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307280 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007281 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007282 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7283 }
7284 }
7285 }
7286
Jeff Johnson4416a782013-03-25 14:17:50 -07007287 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
7288 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
7289 return -EINVAL;
7290 }
7291
Jeff Johnson295189b2012-06-20 16:38:30 -07007292 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
7293
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007294#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007295 if (params->ssid != NULL)
7296 {
7297 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
7298 pConfig->SSIDinfo.ssid.length = params->ssid_len;
7299 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7300 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7301 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007302#else
7303 if (ssid != NULL)
7304 {
7305 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
7306 pConfig->SSIDinfo.ssid.length = ssid_len;
7307 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7308 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7309 }
7310#endif
7311
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307312 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07007313 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307314
Jeff Johnson295189b2012-06-20 16:38:30 -07007315 /* default value */
7316 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7317 pConfig->num_accept_mac = 0;
7318 pConfig->num_deny_mac = 0;
7319
7320 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7321 pBeacon->tail, pBeacon->tail_len);
7322
7323 /* pIe for black list is following form:
7324 type : 1 byte
7325 length : 1 byte
7326 OUI : 4 bytes
7327 acl type : 1 byte
7328 no of mac addr in black list: 1 byte
7329 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307330 */
7331 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007332 {
7333 pConfig->SapMacaddr_acl = pIe[6];
7334 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007335 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007336 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307337 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7338 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007339 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7340 for (i = 0; i < pConfig->num_deny_mac; i++)
7341 {
7342 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7343 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307344 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007345 }
7346 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7347 pBeacon->tail, pBeacon->tail_len);
7348
7349 /* pIe for white list is following form:
7350 type : 1 byte
7351 length : 1 byte
7352 OUI : 4 bytes
7353 acl type : 1 byte
7354 no of mac addr in white list: 1 byte
7355 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307356 */
7357 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007358 {
7359 pConfig->SapMacaddr_acl = pIe[6];
7360 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007361 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007362 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307363 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7364 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007365 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7366 for (i = 0; i < pConfig->num_accept_mac; i++)
7367 {
7368 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7369 acl_entry++;
7370 }
7371 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307372
Jeff Johnson295189b2012-06-20 16:38:30 -07007373 wlan_hdd_set_sapHwmode(pHostapdAdapter);
7374
Jeff Johnsone7245742012-09-05 17:12:55 -07007375#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007376 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307377 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
7378 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05307379 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
7380 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007381 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
7382 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307383 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
7384 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07007385 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307386 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07007387 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307388 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007389
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307390 /* If ACS disable and selected channel <= 14
7391 * OR
7392 * ACS enabled and ACS operating band is choosen as 2.4
7393 * AND
7394 * VHT in 2.4G Disabled
7395 * THEN
7396 * Fallback to 11N mode
7397 */
7398 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
7399 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05307400 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307401 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007402 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307403 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
7404 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007405 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
7406 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007407 }
7408#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307409
Jeff Johnson295189b2012-06-20 16:38:30 -07007410 // ht_capab is not what the name conveys,this is used for protection bitmap
7411 pConfig->ht_capab =
7412 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
7413
7414 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
7415 {
7416 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7417 return -EINVAL;
7418 }
7419
7420 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307421 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07007422 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
7423 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307424 pConfig->obssProtEnabled =
7425 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07007426
Chet Lanctot8cecea22014-02-11 19:09:36 -08007427#ifdef WLAN_FEATURE_11W
7428 pConfig->mfpCapable = MFPCapable;
7429 pConfig->mfpRequired = MFPRequired;
7430 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
7431 pConfig->mfpCapable, pConfig->mfpRequired);
7432#endif
7433
Arif Hussain6d2a3322013-11-17 19:50:10 -08007434 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07007435 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007436 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
7437 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7438 (int)pConfig->channel);
7439 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
7440 pConfig->SapHw_mode, pConfig->privacy,
7441 pConfig->authType);
7442 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
7443 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7444 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7445 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07007446
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307447 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007448 {
7449 //Bss already started. just return.
7450 //TODO Probably it should update some beacon params.
7451 hddLog( LOGE, "Bss Already started...Ignore the request");
7452 EXIT();
7453 return 0;
7454 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307455
Agarwal Ashish51325b52014-06-16 16:50:49 +05307456 if (vos_max_concurrent_connections_reached()) {
7457 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7458 return -EINVAL;
7459 }
7460
Jeff Johnson295189b2012-06-20 16:38:30 -07007461 pConfig->persona = pHostapdAdapter->device_mode;
7462
Peng Xu2446a892014-09-05 17:21:18 +05307463 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
7464 if ( NULL != psmeConfig)
7465 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307466 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05307467 sme_GetConfigParam(hHal, psmeConfig);
7468 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307469#ifdef WLAN_FEATURE_AP_HT40_24G
7470 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7471 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
7472 && pHddCtx->cfg_ini->apHT40_24GEnabled)
7473 {
7474 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
7475 sme_UpdateConfig (hHal, psmeConfig);
7476 }
7477#endif
Peng Xu2446a892014-09-05 17:21:18 +05307478 vos_mem_free(psmeConfig);
7479 }
Peng Xuafc34e32014-09-25 13:23:55 +05307480 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05307481
Jeff Johnson295189b2012-06-20 16:38:30 -07007482 pSapEventCallback = hdd_hostapd_SAPEventCB;
7483 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
7484 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
7485 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007486 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007487 return -EINVAL;
7488 }
7489
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307490 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07007491 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7492
7493 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307494
Jeff Johnson295189b2012-06-20 16:38:30 -07007495 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307496 {
7497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007498 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07007499 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07007500 VOS_ASSERT(0);
7501 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307502
Jeff Johnson295189b2012-06-20 16:38:30 -07007503 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05307504 /* Initialize WMM configuation */
7505 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307506 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007507
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007508#ifdef WLAN_FEATURE_P2P_DEBUG
7509 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
7510 {
7511 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
7512 {
7513 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7514 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007515 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007516 }
7517 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
7518 {
7519 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7520 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007521 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007522 }
7523 }
7524#endif
7525
Jeff Johnson295189b2012-06-20 16:38:30 -07007526 pHostapdState->bCommit = TRUE;
7527 EXIT();
7528
7529 return 0;
7530}
7531
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007532#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307533static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307534 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007535 struct beacon_parameters *params)
7536{
7537 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307538 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307539 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007540
7541 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307542
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307543 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7544 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
7545 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307546 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
7547 hdd_device_modetoString(pAdapter->device_mode),
7548 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007549
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307550 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7551 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307552 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007553 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307554 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007555 }
7556
Agarwal Ashish51325b52014-06-16 16:50:49 +05307557 if (vos_max_concurrent_connections_reached()) {
7558 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7559 return -EINVAL;
7560 }
7561
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307562 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007563 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007564 )
7565 {
7566 beacon_data_t *old,*new;
7567
7568 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307569
Jeff Johnson295189b2012-06-20 16:38:30 -07007570 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307571 {
7572 hddLog(VOS_TRACE_LEVEL_WARN,
7573 FL("already beacon info added to session(%d)"),
7574 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007575 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307576 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007577
7578 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7579
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307580 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07007581 {
7582 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007583 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007584 return -EINVAL;
7585 }
7586
7587 pAdapter->sessionCtx.ap.beacon = new;
7588
7589 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7590 }
7591
7592 EXIT();
7593 return status;
7594}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307595
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307596static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
7597 struct net_device *dev,
7598 struct beacon_parameters *params)
7599{
7600 int ret;
7601
7602 vos_ssr_protect(__func__);
7603 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
7604 vos_ssr_unprotect(__func__);
7605
7606 return ret;
7607}
7608
7609static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007610 struct net_device *dev,
7611 struct beacon_parameters *params)
7612{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307613 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307614 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7615 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307616 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007617
7618 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307619
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307620 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7621 TRACE_CODE_HDD_CFG80211_SET_BEACON,
7622 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
7623 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7624 __func__, hdd_device_modetoString(pAdapter->device_mode),
7625 pAdapter->device_mode);
7626
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307627 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7628 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307629 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007630 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307631 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007632 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307633
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307634 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007635 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307636 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007637 {
7638 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307639
Jeff Johnson295189b2012-06-20 16:38:30 -07007640 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307641
Jeff Johnson295189b2012-06-20 16:38:30 -07007642 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307643 {
7644 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7645 FL("session(%d) old and new heads points to NULL"),
7646 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007647 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307648 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007649
7650 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7651
7652 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307653 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007654 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007655 return -EINVAL;
7656 }
7657
7658 pAdapter->sessionCtx.ap.beacon = new;
7659
7660 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7661 }
7662
7663 EXIT();
7664 return status;
7665}
7666
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307667static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
7668 struct net_device *dev,
7669 struct beacon_parameters *params)
7670{
7671 int ret;
7672
7673 vos_ssr_protect(__func__);
7674 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
7675 vos_ssr_unprotect(__func__);
7676
7677 return ret;
7678}
7679
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007680#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7681
7682#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307683static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007684 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007685#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307686static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007687 struct net_device *dev)
7688#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007689{
7690 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07007691 hdd_context_t *pHddCtx = NULL;
7692 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307693 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307694 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007695
7696 ENTER();
7697
7698 if (NULL == pAdapter)
7699 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007701 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007702 return -ENODEV;
7703 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007704
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307705 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7706 TRACE_CODE_HDD_CFG80211_STOP_AP,
7707 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307708 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7709 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307710 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007711 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307712 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07007713 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007714
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007715 pScanInfo = &pHddCtx->scan_info;
7716
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307717 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7718 __func__, hdd_device_modetoString(pAdapter->device_mode),
7719 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007720
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307721 ret = wlan_hdd_scan_abort(pAdapter);
7722
Girish Gowli4bf7a632014-06-12 13:42:11 +05307723 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07007724 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7726 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307727
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307728 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07007729 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7731 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08007732
Jeff Johnsone7245742012-09-05 17:12:55 -07007733 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307734 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07007735 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307736 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07007737 }
7738
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05307739 /* Delete all associated STAs before stopping AP/P2P GO */
7740 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05307741 hdd_hostapd_stop(dev);
7742
Jeff Johnson295189b2012-06-20 16:38:30 -07007743 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007744 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007745 )
7746 {
7747 beacon_data_t *old;
7748
7749 old = pAdapter->sessionCtx.ap.beacon;
7750
7751 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307752 {
7753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7754 FL("session(%d) beacon data points to NULL"),
7755 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007756 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307757 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007758
Jeff Johnson295189b2012-06-20 16:38:30 -07007759 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007760
7761 mutex_lock(&pHddCtx->sap_lock);
7762 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7763 {
Jeff Johnson4416a782013-03-25 14:17:50 -07007764 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007765 {
7766 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7767
7768 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7769
7770 if (!VOS_IS_STATUS_SUCCESS(status))
7771 {
7772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007773 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007774 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307775 }
7776 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007777 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307778 /* BSS stopped, clear the active sessions for this device mode */
7779 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007780 }
7781 mutex_unlock(&pHddCtx->sap_lock);
7782
7783 if(status != VOS_STATUS_SUCCESS)
7784 {
7785 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007786 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007787 return -EINVAL;
7788 }
7789
Jeff Johnson4416a782013-03-25 14:17:50 -07007790 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007791 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
7792 ==eHAL_STATUS_FAILURE)
7793 {
7794 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007795 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007796 }
7797
Jeff Johnson4416a782013-03-25 14:17:50 -07007798 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007799 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7800 eANI_BOOLEAN_FALSE) )
7801 {
7802 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007803 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007804 }
7805
7806 // Reset WNI_CFG_PROBE_RSP Flags
7807 wlan_hdd_reset_prob_rspies(pAdapter);
7808
7809 pAdapter->sessionCtx.ap.beacon = NULL;
7810 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007811#ifdef WLAN_FEATURE_P2P_DEBUG
7812 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7813 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
7814 {
7815 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
7816 "GO got removed");
7817 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
7818 }
7819#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007820 }
7821 EXIT();
7822 return status;
7823}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007824
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307825#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7826static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
7827 struct net_device *dev)
7828{
7829 int ret;
7830
7831 vos_ssr_protect(__func__);
7832 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
7833 vos_ssr_unprotect(__func__);
7834
7835 return ret;
7836}
7837#else
7838static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7839 struct net_device *dev)
7840{
7841 int ret;
7842
7843 vos_ssr_protect(__func__);
7844 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7845 vos_ssr_unprotect(__func__);
7846
7847 return ret;
7848}
7849#endif
7850
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007851#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7852
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307853static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307854 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007855 struct cfg80211_ap_settings *params)
7856{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307857 hdd_adapter_t *pAdapter;
7858 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307859 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007860
7861 ENTER();
7862
Girish Gowlib143d7a2015-02-18 19:39:55 +05307863 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007864 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05307866 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307867 return -ENODEV;
7868 }
7869
7870 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7871 if (NULL == pAdapter)
7872 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307874 "%s: HDD adapter is Null", __func__);
7875 return -ENODEV;
7876 }
7877
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307878 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7879 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
7880 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307881 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7882 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307884 "%s: HDD adapter magic is invalid", __func__);
7885 return -ENODEV;
7886 }
7887
7888 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307889 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307890 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307891 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307892 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307893 }
7894
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307895 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7896 __func__, hdd_device_modetoString(pAdapter->device_mode),
7897 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307898
7899 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007900 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007901 )
7902 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307903 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007904
7905 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307906
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007907 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307908 {
7909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7910 FL("already beacon info added to session(%d)"),
7911 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007912 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307913 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007914
Girish Gowlib143d7a2015-02-18 19:39:55 +05307915#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7916 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7917 &new,
7918 &params->beacon);
7919#else
7920 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7921 &new,
7922 &params->beacon,
7923 params->dtim_period);
7924#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007925
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307926 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007927 {
7928 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307929 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007930 return -EINVAL;
7931 }
7932 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007933#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007934 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7935#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7936 params->channel, params->channel_type);
7937#else
7938 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7939#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007940#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007941 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307942 params->ssid_len, params->hidden_ssid,
7943 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007944 }
7945
7946 EXIT();
7947 return status;
7948}
7949
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307950static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7951 struct net_device *dev,
7952 struct cfg80211_ap_settings *params)
7953{
7954 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007955
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307956 vos_ssr_protect(__func__);
7957 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
7958 vos_ssr_unprotect(__func__);
7959
7960 return ret;
7961}
7962
7963static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007964 struct net_device *dev,
7965 struct cfg80211_beacon_data *params)
7966{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307967 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307968 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307969 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007970
7971 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307972
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307973 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7974 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7975 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007976 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007977 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307978
7979 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7980 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307981 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007982 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307983 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007984 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007985
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307986 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007987 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307988 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007989 {
7990 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307991
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007992 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307993
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007994 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307995 {
7996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7997 FL("session(%d) beacon data points to NULL"),
7998 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007999 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308000 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008001
8002 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
8003
8004 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308005 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008006 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008007 return -EINVAL;
8008 }
8009
8010 pAdapter->sessionCtx.ap.beacon = new;
8011
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308012 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
8013 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008014 }
8015
8016 EXIT();
8017 return status;
8018}
8019
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308020static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8021 struct net_device *dev,
8022 struct cfg80211_beacon_data *params)
8023{
8024 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008025
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308026 vos_ssr_protect(__func__);
8027 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8028 vos_ssr_unprotect(__func__);
8029
8030 return ret;
8031}
8032
8033#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008034
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308035static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008036 struct net_device *dev,
8037 struct bss_parameters *params)
8038{
8039 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308040 hdd_context_t *pHddCtx;
8041 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008042
8043 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308044
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308045 if (NULL == pAdapter)
8046 {
8047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8048 "%s: HDD adapter is Null", __func__);
8049 return -ENODEV;
8050 }
8051 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308052 ret = wlan_hdd_validate_context(pHddCtx);
8053 if (0 != ret)
8054 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308055 return ret;
8056 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308057 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8058 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
8059 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308060 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8061 __func__, hdd_device_modetoString(pAdapter->device_mode),
8062 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008063
8064 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008065 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308066 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008067 {
8068 /* ap_isolate == -1 means that in change bss, upper layer doesn't
8069 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308070 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07008071 {
8072 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308073 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008074 }
8075
8076 EXIT();
8077 return 0;
8078}
8079
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308080static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
8081 struct net_device *dev,
8082 struct bss_parameters *params)
8083{
8084 int ret;
8085
8086 vos_ssr_protect(__func__);
8087 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
8088 vos_ssr_unprotect(__func__);
8089
8090 return ret;
8091}
Kiet Lam10841362013-11-01 11:36:50 +05308092/* FUNCTION: wlan_hdd_change_country_code_cd
8093* to wait for contry code completion
8094*/
8095void* wlan_hdd_change_country_code_cb(void *pAdapter)
8096{
8097 hdd_adapter_t *call_back_pAdapter = pAdapter;
8098 complete(&call_back_pAdapter->change_country_code);
8099 return NULL;
8100}
8101
Jeff Johnson295189b2012-06-20 16:38:30 -07008102/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308103 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07008104 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
8105 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308106int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008107 struct net_device *ndev,
8108 enum nl80211_iftype type,
8109 u32 *flags,
8110 struct vif_params *params
8111 )
8112{
8113 struct wireless_dev *wdev;
8114 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008115 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07008116 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008117 tCsrRoamProfile *pRoamProfile = NULL;
8118 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308119 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008120 eMib_dot11DesiredBssType connectedBssType;
8121 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308122 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008123
8124 ENTER();
8125
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308126 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008127 {
8128 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8129 "%s: Adapter context is null", __func__);
8130 return VOS_STATUS_E_FAILURE;
8131 }
8132
8133 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8134 if (!pHddCtx)
8135 {
8136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8137 "%s: HDD context is null", __func__);
8138 return VOS_STATUS_E_FAILURE;
8139 }
8140
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308141 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8142 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
8143 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308144 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308145 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07008146 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308147 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008148 }
8149
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308150 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8151 __func__, hdd_device_modetoString(pAdapter->device_mode),
8152 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008153
Agarwal Ashish51325b52014-06-16 16:50:49 +05308154 if (vos_max_concurrent_connections_reached()) {
8155 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8156 return -EINVAL;
8157 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308158 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07008159 wdev = ndev->ieee80211_ptr;
8160
8161#ifdef WLAN_BTAMP_FEATURE
8162 if((NL80211_IFTYPE_P2P_CLIENT == type)||
8163 (NL80211_IFTYPE_ADHOC == type)||
8164 (NL80211_IFTYPE_AP == type)||
8165 (NL80211_IFTYPE_P2P_GO == type))
8166 {
8167 pHddCtx->isAmpAllowed = VOS_FALSE;
8168 // stop AMP traffic
8169 status = WLANBAP_StopAmp();
8170 if(VOS_STATUS_SUCCESS != status )
8171 {
8172 pHddCtx->isAmpAllowed = VOS_TRUE;
8173 hddLog(VOS_TRACE_LEVEL_FATAL,
8174 "%s: Failed to stop AMP", __func__);
8175 return -EINVAL;
8176 }
8177 }
8178#endif //WLAN_BTAMP_FEATURE
8179 /* Reset the current device mode bit mask*/
8180 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8181
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +05308182 /* Notify Mode change in case of concurrency.
8183 * Below function invokes TDLS teardown Functionality Since TDLS is
8184 * not Supported in case of concurrency i.e Once P2P session
8185 * is detected disable offchannel and teardown TDLS links
8186 */
8187 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
8188
Jeff Johnson295189b2012-06-20 16:38:30 -07008189 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008190 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07008191 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008192 )
8193 {
8194 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008195 if (!pWextState)
8196 {
8197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8198 "%s: pWextState is null", __func__);
8199 return VOS_STATUS_E_FAILURE;
8200 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008201 pRoamProfile = &pWextState->roamProfile;
8202 LastBSSType = pRoamProfile->BSSType;
8203
8204 switch (type)
8205 {
8206 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008207 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008208 hddLog(VOS_TRACE_LEVEL_INFO,
8209 "%s: setting interface Type to INFRASTRUCTURE", __func__);
8210 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008211#ifdef WLAN_FEATURE_11AC
8212 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
8213 {
8214 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
8215 }
8216#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308217 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07008218 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008219 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008220 //Check for sub-string p2p to confirm its a p2p interface
8221 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308222 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008223 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8224 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8225 }
8226 else
8227 {
8228 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008229 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008230 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008231 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05308232
Jeff Johnson295189b2012-06-20 16:38:30 -07008233 case NL80211_IFTYPE_ADHOC:
8234 hddLog(VOS_TRACE_LEVEL_INFO,
8235 "%s: setting interface Type to ADHOC", __func__);
8236 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
8237 pRoamProfile->phyMode =
8238 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07008239 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008240 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05308241 hdd_set_ibss_ops( pAdapter );
8242 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +05308243
8244 status = hdd_sta_id_hash_attach(pAdapter);
8245 if (VOS_STATUS_SUCCESS != status) {
8246 hddLog(VOS_TRACE_LEVEL_ERROR,
8247 FL("Failed to initialize hash for IBSS"));
8248 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008249 break;
8250
8251 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008252 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008253 {
8254 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8255 "%s: setting interface Type to %s", __func__,
8256 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
8257
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008258 //Cancel any remain on channel for GO mode
8259 if (NL80211_IFTYPE_P2P_GO == type)
8260 {
8261 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
8262 }
Mohit Khanna0f232092012-09-11 14:46:08 -07008263 if (NL80211_IFTYPE_AP == type)
8264 {
8265 /* As Loading WLAN Driver one interface being created for p2p device
8266 * address. This will take one HW STA and the max number of clients
8267 * that can connect to softAP will be reduced by one. so while changing
8268 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
8269 * interface as it is not required in SoftAP mode.
8270 */
8271
8272 // Get P2P Adapter
8273 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
8274
8275 if (pP2pAdapter)
8276 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308277 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05308278 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07008279 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
8280 }
8281 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05308282 //Disable IMPS & BMPS for SAP/GO
8283 if(VOS_STATUS_E_FAILURE ==
8284 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
8285 {
8286 //Fail to Exit BMPS
8287 VOS_ASSERT(0);
8288 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05308289
8290 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
8291
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308292#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07008293
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308294 /* A Mutex Lock is introduced while changing the mode to
8295 * protect the concurrent access for the Adapters by TDLS
8296 * module.
8297 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308298 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308299#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008300 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05308301 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008302 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07008303 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8304 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308305#ifdef FEATURE_WLAN_TDLS
8306 mutex_unlock(&pHddCtx->tdls_lock);
8307#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008308 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
8309 (pConfig->apRandomBssidEnabled))
8310 {
8311 /* To meet Android requirements create a randomized
8312 MAC address of the form 02:1A:11:Fx:xx:xx */
8313 get_random_bytes(&ndev->dev_addr[3], 3);
8314 ndev->dev_addr[0] = 0x02;
8315 ndev->dev_addr[1] = 0x1A;
8316 ndev->dev_addr[2] = 0x11;
8317 ndev->dev_addr[3] |= 0xF0;
8318 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
8319 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08008320 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
8321 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008322 }
8323
Jeff Johnson295189b2012-06-20 16:38:30 -07008324 hdd_set_ap_ops( pAdapter->dev );
8325
Kiet Lam10841362013-11-01 11:36:50 +05308326 /* This is for only SAP mode where users can
8327 * control country through ini.
8328 * P2P GO follows station country code
8329 * acquired during the STA scanning. */
8330 if((NL80211_IFTYPE_AP == type) &&
8331 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
8332 {
8333 int status = 0;
8334 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
8335 "%s: setting country code from INI ", __func__);
8336 init_completion(&pAdapter->change_country_code);
8337 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
8338 (void *)(tSmeChangeCountryCallback)
8339 wlan_hdd_change_country_code_cb,
8340 pConfig->apCntryCode, pAdapter,
8341 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308342 eSIR_FALSE,
8343 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05308344 if (eHAL_STATUS_SUCCESS == status)
8345 {
8346 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308347 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05308348 &pAdapter->change_country_code,
8349 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308350 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05308351 {
8352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308353 FL("SME Timed out while setting country code %ld"),
8354 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08008355
8356 if (pHddCtx->isLogpInProgress)
8357 {
8358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8359 "%s: LOGP in Progress. Ignore!!!", __func__);
8360 return -EAGAIN;
8361 }
Kiet Lam10841362013-11-01 11:36:50 +05308362 }
8363 }
8364 else
8365 {
8366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008367 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05308368 return -EINVAL;
8369 }
8370 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008371 status = hdd_init_ap_mode(pAdapter);
8372 if(status != VOS_STATUS_SUCCESS)
8373 {
8374 hddLog(VOS_TRACE_LEVEL_FATAL,
8375 "%s: Error initializing the ap mode", __func__);
8376 return -EINVAL;
8377 }
8378 hdd_set_conparam(1);
8379
Nirav Shah7e3c8132015-06-22 23:51:42 +05308380 status = hdd_sta_id_hash_attach(pAdapter);
8381 if (VOS_STATUS_SUCCESS != status)
8382 {
8383 hddLog(VOS_TRACE_LEVEL_ERROR,
8384 FL("Failed to initialize hash for AP"));
8385 return -EINVAL;
8386 }
8387
Jeff Johnson295189b2012-06-20 16:38:30 -07008388 /*interface type changed update in wiphy structure*/
8389 if(wdev)
8390 {
8391 wdev->iftype = type;
8392 pHddCtx->change_iface = type;
8393 }
8394 else
8395 {
8396 hddLog(VOS_TRACE_LEVEL_ERROR,
8397 "%s: ERROR !!!! Wireless dev is NULL", __func__);
8398 return -EINVAL;
8399 }
8400 goto done;
8401 }
8402
8403 default:
8404 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8405 __func__);
8406 return -EOPNOTSUPP;
8407 }
8408 }
8409 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008410 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008411 )
8412 {
8413 switch(type)
8414 {
8415 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008416 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008417 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05308418
8419 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308420#ifdef FEATURE_WLAN_TDLS
8421
8422 /* A Mutex Lock is introduced while changing the mode to
8423 * protect the concurrent access for the Adapters by TDLS
8424 * module.
8425 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308426 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308427#endif
c_hpothu002231a2015-02-05 14:58:51 +05308428 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008429 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008430 //Check for sub-string p2p to confirm its a p2p interface
8431 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008432 {
8433 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8434 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8435 }
8436 else
8437 {
8438 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008439 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008440 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008441 hdd_set_conparam(0);
8442 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008443 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
8444 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308445#ifdef FEATURE_WLAN_TDLS
8446 mutex_unlock(&pHddCtx->tdls_lock);
8447#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308448 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008449 if( VOS_STATUS_SUCCESS != status )
8450 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07008451 /* In case of JB, for P2P-GO, only change interface will be called,
8452 * This is the right place to enable back bmps_imps()
8453 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308454 if (pHddCtx->hdd_wlan_suspended)
8455 {
8456 hdd_set_pwrparams(pHddCtx);
8457 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008458 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008459 goto done;
8460 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008461 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008462 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008463 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8464 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008465 goto done;
8466 default:
8467 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8468 __func__);
8469 return -EOPNOTSUPP;
8470
8471 }
8472
8473 }
8474 else
8475 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308476 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
8477 __func__, hdd_device_modetoString(pAdapter->device_mode),
8478 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008479 return -EOPNOTSUPP;
8480 }
8481
8482
8483 if(pRoamProfile)
8484 {
8485 if ( LastBSSType != pRoamProfile->BSSType )
8486 {
8487 /*interface type changed update in wiphy structure*/
8488 wdev->iftype = type;
8489
8490 /*the BSS mode changed, We need to issue disconnect
8491 if connected or in IBSS disconnect state*/
8492 if ( hdd_connGetConnectedBssType(
8493 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
8494 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
8495 {
8496 /*need to issue a disconnect to CSR.*/
8497 INIT_COMPLETION(pAdapter->disconnect_comp_var);
8498 if( eHAL_STATUS_SUCCESS ==
8499 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
8500 pAdapter->sessionId,
8501 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
8502 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308503 ret = wait_for_completion_interruptible_timeout(
8504 &pAdapter->disconnect_comp_var,
8505 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
8506 if (ret <= 0)
8507 {
8508 hddLog(VOS_TRACE_LEVEL_ERROR,
8509 FL("wait on disconnect_comp_var failed %ld"), ret);
8510 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008511 }
8512 }
8513 }
8514 }
8515
8516done:
8517 /*set bitmask based on updated value*/
8518 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07008519
8520 /* Only STA mode support TM now
8521 * all other mode, TM feature should be disabled */
8522 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
8523 (~VOS_STA & pHddCtx->concurrency_mode) )
8524 {
8525 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
8526 }
8527
Jeff Johnson295189b2012-06-20 16:38:30 -07008528#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308529 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05308530 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07008531 {
8532 //we are ok to do AMP
8533 pHddCtx->isAmpAllowed = VOS_TRUE;
8534 }
8535#endif //WLAN_BTAMP_FEATURE
8536 EXIT();
8537 return 0;
8538}
8539
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308540/*
8541 * FUNCTION: wlan_hdd_cfg80211_change_iface
8542 * wrapper function to protect the actual implementation from SSR.
8543 */
8544int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
8545 struct net_device *ndev,
8546 enum nl80211_iftype type,
8547 u32 *flags,
8548 struct vif_params *params
8549 )
8550{
8551 int ret;
8552
8553 vos_ssr_protect(__func__);
8554 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
8555 vos_ssr_unprotect(__func__);
8556
8557 return ret;
8558}
8559
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008560#ifdef FEATURE_WLAN_TDLS
8561static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308562 struct net_device *dev,
8563#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
8564 const u8 *mac,
8565#else
8566 u8 *mac,
8567#endif
8568 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008569{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008570 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008571 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308572 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308573 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308574 hdd_adapter_t *pAdapter;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008575
8576 ENTER();
8577
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308578 if (!dev) {
8579 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
8580 return -EINVAL;
8581 }
8582
8583 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8584 if (!pAdapter) {
8585 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
8586 return -EINVAL;
8587 }
8588
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308589 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008590 {
8591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8592 "Invalid arguments");
8593 return -EINVAL;
8594 }
Hoonki Lee27511902013-03-14 18:19:06 -07008595
8596 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
8597 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
8598 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07008600 "%s: TDLS mode is disabled OR not enabled in FW."
8601 MAC_ADDRESS_STR " Request declined.",
8602 __func__, MAC_ADDR_ARRAY(mac));
8603 return -ENOTSUPP;
8604 }
8605
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008606 if (pHddCtx->isLogpInProgress)
8607 {
8608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8609 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05308610 wlan_hdd_tdls_set_link_status(pAdapter,
8611 mac,
8612 eTDLS_LINK_IDLE,
8613 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008614 return -EBUSY;
8615 }
8616
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308617 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05308618 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008619
8620 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008622 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
8623 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308624 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008625 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008626 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308627 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008628
8629 /* in add station, we accept existing valid staId if there is */
8630 if ((0 == update) &&
8631 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
8632 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008633 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008635 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008636 " link_status %d. staId %d. add station ignored.",
8637 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
8638 return 0;
8639 }
8640 /* in change station, we accept only when staId is valid */
8641 if ((1 == update) &&
8642 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
8643 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
8644 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008646 "%s: " MAC_ADDRESS_STR
8647 " link status %d. staId %d. change station %s.",
8648 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
8649 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
8650 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008651 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008652
8653 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05308654 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008655 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8657 "%s: " MAC_ADDRESS_STR
8658 " TDLS setup is ongoing. Request declined.",
8659 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07008660 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008661 }
8662
8663 /* first to check if we reached to maximum supported TDLS peer.
8664 TODO: for now, return -EPERM looks working fine,
8665 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308666 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8667 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008668 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008669 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8670 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308671 " TDLS Max peer already connected. Request declined."
8672 " Num of peers (%d), Max allowed (%d).",
8673 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
8674 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008675 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008676 }
8677 else
8678 {
8679 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308680 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008681 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008682 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008683 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8684 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
8685 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008686 return -EPERM;
8687 }
8688 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008689 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05308690 wlan_hdd_tdls_set_link_status(pAdapter,
8691 mac,
8692 eTDLS_LINK_CONNECTING,
8693 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008694
Jeff Johnsond75fe012013-04-06 10:53:06 -07008695 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308696 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008697 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008699 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008700 if(StaParams->htcap_present)
8701 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008703 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008705 "ht_capa->extended_capabilities: %0x",
8706 StaParams->HTCap.extendedHtCapInfo);
8707 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008709 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308710 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008711 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008712 if(StaParams->vhtcap_present)
8713 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008715 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
8716 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
8717 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
8718 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008719 {
8720 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008722 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008724 "[%d]: %x ", i, StaParams->supported_rates[i]);
8725 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07008726 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308727 else if ((1 == update) && (NULL == StaParams))
8728 {
8729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8730 "%s : update is true, but staParams is NULL. Error!", __func__);
8731 return -EPERM;
8732 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008733
8734 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
8735
8736 if (!update)
8737 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308738 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008739 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308740 if (ret != eHAL_STATUS_SUCCESS) {
8741 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to add TDLS peer STA"));
8742 return -EPERM;
8743 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008744 }
8745 else
8746 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308747 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008748 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308749 if (ret != eHAL_STATUS_SUCCESS) {
8750 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
8751 return -EPERM;
8752 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008753 }
8754
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308755 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008756 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
8757
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308758 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008759 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008760 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308761 "%s: timeout waiting for tdls add station indication %ld",
8762 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008763 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008764 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308765
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008766 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
8767 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008769 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008770 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008771 }
8772
8773 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008774
8775error:
Atul Mittal115287b2014-07-08 13:26:33 +05308776 wlan_hdd_tdls_set_link_status(pAdapter,
8777 mac,
8778 eTDLS_LINK_IDLE,
8779 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008780 return -EPERM;
8781
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008782}
8783#endif
8784
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308785static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008786 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308787#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
8788 const u8 *mac,
8789#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008790 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308791#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008792 struct station_parameters *params)
8793{
8794 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308795 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308796 hdd_context_t *pHddCtx;
8797 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008798 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308799 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008800#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008801 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008802 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308803 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008804#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008805
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308806 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308807
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308808 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308809 if ((NULL == pAdapter))
8810 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308811 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308812 "invalid adapter ");
8813 return -EINVAL;
8814 }
8815
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308816 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8817 TRACE_CODE_HDD_CHANGE_STATION,
8818 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05308819 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308820
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308821 ret = wlan_hdd_validate_context(pHddCtx);
8822 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05308823 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308824 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308825 }
8826
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308827 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8828
8829 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008830 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308831 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8832 "invalid HDD station context");
8833 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008834 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008835 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
8836
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008837 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8838 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07008839 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008840 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07008841 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308842 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07008843 WLANTL_STA_AUTHENTICATED);
8844
Gopichand Nakkala29149562013-05-10 21:43:41 +05308845 if (status != VOS_STATUS_SUCCESS)
8846 {
8847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8848 "%s: Not able to change TL state to AUTHENTICATED", __func__);
8849 return -EINVAL;
8850 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008851 }
8852 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07008853 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8854 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308855#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008856 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8857 StaParams.capability = params->capability;
8858 StaParams.uapsd_queues = params->uapsd_queues;
8859 StaParams.max_sp = params->max_sp;
8860
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308861 /* Convert (first channel , number of channels) tuple to
8862 * the total list of channels. This goes with the assumption
8863 * that if the first channel is < 14, then the next channels
8864 * are an incremental of 1 else an incremental of 4 till the number
8865 * of channels.
8866 */
8867 if (0 != params->supported_channels_len) {
8868 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
8869 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
8870 {
8871 int wifi_chan_index;
8872 StaParams.supported_channels[j] = params->supported_channels[i];
8873 wifi_chan_index =
8874 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
8875 no_of_channels = params->supported_channels[i+1];
8876 for(k=1; k <= no_of_channels; k++)
8877 {
8878 StaParams.supported_channels[j+1] =
8879 StaParams.supported_channels[j] + wifi_chan_index;
8880 j+=1;
8881 }
8882 }
8883 StaParams.supported_channels_len = j;
8884 }
8885 vos_mem_copy(StaParams.supported_oper_classes,
8886 params->supported_oper_classes,
8887 params->supported_oper_classes_len);
8888 StaParams.supported_oper_classes_len =
8889 params->supported_oper_classes_len;
8890
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008891 if (0 != params->ext_capab_len)
8892 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
8893 sizeof(StaParams.extn_capability));
8894
8895 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008896 {
8897 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008898 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008899 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008900
8901 StaParams.supported_rates_len = params->supported_rates_len;
8902
8903 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
8904 * The supported_rates array , for all the structures propogating till Add Sta
8905 * to the firmware has to be modified , if the supplicant (ieee80211) is
8906 * modified to send more rates.
8907 */
8908
8909 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
8910 */
8911 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
8912 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
8913
8914 if (0 != StaParams.supported_rates_len) {
8915 int i = 0;
8916 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
8917 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008919 "Supported Rates with Length %d", StaParams.supported_rates_len);
8920 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008922 "[%d]: %0x", i, StaParams.supported_rates[i]);
8923 }
8924
8925 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008926 {
8927 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008928 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008929 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008930
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008931 if (0 != params->ext_capab_len ) {
8932 /*Define A Macro : TODO Sunil*/
8933 if ((1<<4) & StaParams.extn_capability[3]) {
8934 isBufSta = 1;
8935 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308936 /* TDLS Channel Switching Support */
8937 if ((1<<6) & StaParams.extn_capability[3]) {
8938 isOffChannelSupported = 1;
8939 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008940 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308941 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
8942 &StaParams, isBufSta,
8943 isOffChannelSupported);
8944
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308945 if (VOS_STATUS_SUCCESS != status) {
8946 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8947 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
8948 return -EINVAL;
8949 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008950 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
8951
8952 if (VOS_STATUS_SUCCESS != status) {
8953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8954 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
8955 return -EINVAL;
8956 }
8957 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008958#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05308959 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008960 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008961 return status;
8962}
8963
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308964#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
8965static int wlan_hdd_change_station(struct wiphy *wiphy,
8966 struct net_device *dev,
8967 const u8 *mac,
8968 struct station_parameters *params)
8969#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308970static int wlan_hdd_change_station(struct wiphy *wiphy,
8971 struct net_device *dev,
8972 u8 *mac,
8973 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308974#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308975{
8976 int ret;
8977
8978 vos_ssr_protect(__func__);
8979 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
8980 vos_ssr_unprotect(__func__);
8981
8982 return ret;
8983}
8984
Jeff Johnson295189b2012-06-20 16:38:30 -07008985/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308986 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008987 * This function is used to initialize the key information
8988 */
8989#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308990static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008991 struct net_device *ndev,
8992 u8 key_index, bool pairwise,
8993 const u8 *mac_addr,
8994 struct key_params *params
8995 )
8996#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308997static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008998 struct net_device *ndev,
8999 u8 key_index, const u8 *mac_addr,
9000 struct key_params *params
9001 )
9002#endif
9003{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009004 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07009005 tCsrRoamSetKey setKey;
9006 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309007 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009008 v_U32_t roamId= 0xFF;
9009 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009010 hdd_hostapd_state_t *pHostapdState;
9011 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009012 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309013 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009014
9015 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309016
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309017 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9018 TRACE_CODE_HDD_CFG80211_ADD_KEY,
9019 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309020 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9021 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309022 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009023 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309024 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009025 }
9026
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309027 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9028 __func__, hdd_device_modetoString(pAdapter->device_mode),
9029 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009030
9031 if (CSR_MAX_NUM_KEY <= key_index)
9032 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009033 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009034 key_index);
9035
9036 return -EINVAL;
9037 }
9038
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009039 if (CSR_MAX_KEY_LEN < params->key_len)
9040 {
9041 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
9042 params->key_len);
9043
9044 return -EINVAL;
9045 }
9046
9047 hddLog(VOS_TRACE_LEVEL_INFO,
9048 "%s: called with key index = %d & key length %d",
9049 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009050
9051 /*extract key idx, key len and key*/
9052 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9053 setKey.keyId = key_index;
9054 setKey.keyLength = params->key_len;
9055 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
9056
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009057 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009058 {
9059 case WLAN_CIPHER_SUITE_WEP40:
9060 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
9061 break;
9062
9063 case WLAN_CIPHER_SUITE_WEP104:
9064 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
9065 break;
9066
9067 case WLAN_CIPHER_SUITE_TKIP:
9068 {
9069 u8 *pKey = &setKey.Key[0];
9070 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
9071
9072 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
9073
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009074 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07009075
9076 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009077 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009078 |--------------|----------|----------|
9079 <---16bytes---><--8bytes--><--8bytes-->
9080
9081 */
9082 /*Sme expects the 32 bytes key to be in the below order
9083
9084 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009085 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009086 |--------------|----------|----------|
9087 <---16bytes---><--8bytes--><--8bytes-->
9088 */
9089 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009090 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07009091
9092 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009093 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009094
9095 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009096 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009097
9098
9099 break;
9100 }
9101
9102 case WLAN_CIPHER_SUITE_CCMP:
9103 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
9104 break;
9105
9106#ifdef FEATURE_WLAN_WAPI
9107 case WLAN_CIPHER_SUITE_SMS4:
9108 {
9109 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9110 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
9111 params->key, params->key_len);
9112 return 0;
9113 }
9114#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009115
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009116#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009117 case WLAN_CIPHER_SUITE_KRK:
9118 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
9119 break;
9120#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009121
9122#ifdef WLAN_FEATURE_11W
9123 case WLAN_CIPHER_SUITE_AES_CMAC:
9124 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07009125 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07009126#endif
9127
Jeff Johnson295189b2012-06-20 16:38:30 -07009128 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009129 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009130 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309131 status = -EOPNOTSUPP;
9132 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009133 }
9134
9135 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
9136 __func__, setKey.encType);
9137
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009138 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07009139#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9140 (!pairwise)
9141#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009142 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07009143#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009144 )
9145 {
9146 /* set group key*/
9147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9148 "%s- %d: setting Broadcast key",
9149 __func__, __LINE__);
9150 setKey.keyDirection = eSIR_RX_ONLY;
9151 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9152 }
9153 else
9154 {
9155 /* set pairwise key*/
9156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9157 "%s- %d: setting pairwise key",
9158 __func__, __LINE__);
9159 setKey.keyDirection = eSIR_TX_RX;
9160 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9161 }
9162 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
9163 {
9164 setKey.keyDirection = eSIR_TX_RX;
9165 /*Set the group key*/
9166 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9167 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07009168
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009169 if ( 0 != status )
9170 {
9171 hddLog(VOS_TRACE_LEVEL_ERROR,
9172 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309173 status = -EINVAL;
9174 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009175 }
9176 /*Save the keys here and call sme_RoamSetKey for setting
9177 the PTK after peer joins the IBSS network*/
9178 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
9179 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309180 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009181 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05309182 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
9183 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
9184 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009185 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009186 if( pHostapdState->bssState == BSS_START )
9187 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009188 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9189 vos_status = wlan_hdd_check_ula_done(pAdapter);
9190
9191 if ( vos_status != VOS_STATUS_SUCCESS )
9192 {
9193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9194 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9195 __LINE__, vos_status );
9196
9197 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9198
9199 status = -EINVAL;
9200 goto end;
9201 }
9202
Jeff Johnson295189b2012-06-20 16:38:30 -07009203 status = WLANSAP_SetKeySta( pVosContext, &setKey);
9204
9205 if ( status != eHAL_STATUS_SUCCESS )
9206 {
9207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9208 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9209 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309210 status = -EINVAL;
9211 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009212 }
9213 }
9214
9215 /* Saving WEP keys */
9216 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
9217 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
9218 {
9219 //Save the wep key in ap context. Issue setkey after the BSS is started.
9220 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9221 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
9222 }
9223 else
9224 {
9225 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009226 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009227 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
9228 }
9229 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009230 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
9231 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009232 {
9233 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9234 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9235
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309236#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9237 if (!pairwise)
9238#else
9239 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9240#endif
9241 {
9242 /* set group key*/
9243 if (pHddStaCtx->roam_info.deferKeyComplete)
9244 {
9245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9246 "%s- %d: Perform Set key Complete",
9247 __func__, __LINE__);
9248 hdd_PerformRoamSetKeyComplete(pAdapter);
9249 }
9250 }
9251
Jeff Johnson295189b2012-06-20 16:38:30 -07009252 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
9253
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08009254 pWextState->roamProfile.Keys.defaultIndex = key_index;
9255
9256
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009257 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009258 params->key, params->key_len);
9259
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309260
Jeff Johnson295189b2012-06-20 16:38:30 -07009261 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9262
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309263 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009264 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309265 __func__, setKey.peerMac[0], setKey.peerMac[1],
9266 setKey.peerMac[2], setKey.peerMac[3],
9267 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009268 setKey.keyDirection);
9269
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009270 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +05309271
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009272 if ( vos_status != VOS_STATUS_SUCCESS )
9273 {
9274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009275 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9276 __LINE__, vos_status );
9277
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009278 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009279
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009280 status = -EINVAL;
9281 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009282
9283 }
9284
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009285#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309286 /* The supplicant may attempt to set the PTK once pre-authentication
9287 is done. Save the key in the UMAC and include it in the ADD BSS
9288 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009289 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309290 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009291 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309292 hddLog(VOS_TRACE_LEVEL_INFO_MED,
9293 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309294 status = 0;
9295 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309296 }
9297 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
9298 {
9299 hddLog(VOS_TRACE_LEVEL_ERROR,
9300 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309301 status = -EINVAL;
9302 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009303 }
9304#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07009305
9306 /* issue set key request to SME*/
9307 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9308 pAdapter->sessionId, &setKey, &roamId );
9309
9310 if ( 0 != status )
9311 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309312 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009313 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
9314 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309315 status = -EINVAL;
9316 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009317 }
9318
9319
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309320 /* in case of IBSS as there was no information available about WEP keys during
9321 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07009322 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309323 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
9324 !( ( IW_AUTH_KEY_MGMT_802_1X
9325 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07009326 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
9327 )
9328 &&
9329 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
9330 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
9331 )
9332 )
9333 {
9334 setKey.keyDirection = eSIR_RX_ONLY;
9335 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9336
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309337 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009338 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309339 __func__, setKey.peerMac[0], setKey.peerMac[1],
9340 setKey.peerMac[2], setKey.peerMac[3],
9341 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009342 setKey.keyDirection);
9343
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309344 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009345 pAdapter->sessionId, &setKey, &roamId );
9346
9347 if ( 0 != status )
9348 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309349 hddLog(VOS_TRACE_LEVEL_ERROR,
9350 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009351 __func__, status);
9352 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309353 status = -EINVAL;
9354 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009355 }
9356 }
9357 }
9358
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309359end:
9360 /* Need to clear any trace of key value in the memory.
9361 * Thus zero out the memory even though it is local
9362 * variable.
9363 */
9364 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309365 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309366 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009367}
9368
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309369#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9370static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9371 struct net_device *ndev,
9372 u8 key_index, bool pairwise,
9373 const u8 *mac_addr,
9374 struct key_params *params
9375 )
9376#else
9377static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9378 struct net_device *ndev,
9379 u8 key_index, const u8 *mac_addr,
9380 struct key_params *params
9381 )
9382#endif
9383{
9384 int ret;
9385 vos_ssr_protect(__func__);
9386#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9387 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
9388 mac_addr, params);
9389#else
9390 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
9391 params);
9392#endif
9393 vos_ssr_unprotect(__func__);
9394
9395 return ret;
9396}
9397
Jeff Johnson295189b2012-06-20 16:38:30 -07009398/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309399 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009400 * This function is used to get the key information
9401 */
9402#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309403static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309404 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009405 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309406 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009407 const u8 *mac_addr, void *cookie,
9408 void (*callback)(void *cookie, struct key_params*)
9409 )
9410#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309411static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309412 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009413 struct net_device *ndev,
9414 u8 key_index, const u8 *mac_addr, void *cookie,
9415 void (*callback)(void *cookie, struct key_params*)
9416 )
9417#endif
9418{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309419 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309420 hdd_wext_state_t *pWextState = NULL;
9421 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009422 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309423 hdd_context_t *pHddCtx;
9424 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009425
9426 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309427
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309428 if (NULL == pAdapter)
9429 {
9430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9431 "%s: HDD adapter is Null", __func__);
9432 return -ENODEV;
9433 }
9434
9435 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9436 ret = wlan_hdd_validate_context(pHddCtx);
9437 if (0 != ret)
9438 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309439 return ret;
9440 }
9441
9442 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9443 pRoamProfile = &(pWextState->roamProfile);
9444
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309445 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9446 __func__, hdd_device_modetoString(pAdapter->device_mode),
9447 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309448
Jeff Johnson295189b2012-06-20 16:38:30 -07009449 memset(&params, 0, sizeof(params));
9450
9451 if (CSR_MAX_NUM_KEY <= key_index)
9452 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309453 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07009454 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309455 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009456
9457 switch(pRoamProfile->EncryptionType.encryptionType[0])
9458 {
9459 case eCSR_ENCRYPT_TYPE_NONE:
9460 params.cipher = IW_AUTH_CIPHER_NONE;
9461 break;
9462
9463 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
9464 case eCSR_ENCRYPT_TYPE_WEP40:
9465 params.cipher = WLAN_CIPHER_SUITE_WEP40;
9466 break;
9467
9468 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
9469 case eCSR_ENCRYPT_TYPE_WEP104:
9470 params.cipher = WLAN_CIPHER_SUITE_WEP104;
9471 break;
9472
9473 case eCSR_ENCRYPT_TYPE_TKIP:
9474 params.cipher = WLAN_CIPHER_SUITE_TKIP;
9475 break;
9476
9477 case eCSR_ENCRYPT_TYPE_AES:
9478 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
9479 break;
9480
9481 default:
9482 params.cipher = IW_AUTH_CIPHER_NONE;
9483 break;
9484 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309485
c_hpothuaaf19692014-05-17 17:01:48 +05309486 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9487 TRACE_CODE_HDD_CFG80211_GET_KEY,
9488 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309489
Jeff Johnson295189b2012-06-20 16:38:30 -07009490 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
9491 params.seq_len = 0;
9492 params.seq = NULL;
9493 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
9494 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309495 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009496 return 0;
9497}
9498
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309499#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9500static int wlan_hdd_cfg80211_get_key(
9501 struct wiphy *wiphy,
9502 struct net_device *ndev,
9503 u8 key_index, bool pairwise,
9504 const u8 *mac_addr, void *cookie,
9505 void (*callback)(void *cookie, struct key_params*)
9506 )
9507#else
9508static int wlan_hdd_cfg80211_get_key(
9509 struct wiphy *wiphy,
9510 struct net_device *ndev,
9511 u8 key_index, const u8 *mac_addr, void *cookie,
9512 void (*callback)(void *cookie, struct key_params*)
9513 )
9514#endif
9515{
9516 int ret;
9517
9518 vos_ssr_protect(__func__);
9519#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9520 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
9521 mac_addr, cookie, callback);
9522#else
9523 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
9524 callback);
9525#endif
9526 vos_ssr_unprotect(__func__);
9527
9528 return ret;
9529}
9530
Jeff Johnson295189b2012-06-20 16:38:30 -07009531/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309532 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009533 * This function is used to delete the key information
9534 */
9535#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309536static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009537 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309538 u8 key_index,
9539 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009540 const u8 *mac_addr
9541 )
9542#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309543static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009544 struct net_device *ndev,
9545 u8 key_index,
9546 const u8 *mac_addr
9547 )
9548#endif
9549{
9550 int status = 0;
9551
9552 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309553 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009554 //it is observed that this is invalidating peer
9555 //key index whenever re-key is done. This is affecting data link.
9556 //It should be ok to ignore del_key.
9557#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309558 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
9559 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009560 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
9561 tCsrRoamSetKey setKey;
9562 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309563
Jeff Johnson295189b2012-06-20 16:38:30 -07009564 ENTER();
9565
9566 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
9567 __func__,pAdapter->device_mode);
9568
9569 if (CSR_MAX_NUM_KEY <= key_index)
9570 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309571 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009572 key_index);
9573
9574 return -EINVAL;
9575 }
9576
9577 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9578 setKey.keyId = key_index;
9579
9580 if (mac_addr)
9581 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9582 else
9583 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
9584
9585 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
9586
9587 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309589 )
9590 {
9591
9592 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07009593 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9594 if( pHostapdState->bssState == BSS_START)
9595 {
9596 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309597
Jeff Johnson295189b2012-06-20 16:38:30 -07009598 if ( status != eHAL_STATUS_SUCCESS )
9599 {
9600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9601 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9602 __LINE__, status );
9603 }
9604 }
9605 }
9606 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309607 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07009608 )
9609 {
9610 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9611
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309612 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9613
9614 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009615 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309616 __func__, setKey.peerMac[0], setKey.peerMac[1],
9617 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07009618 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309619 if(pAdapter->sessionCtx.station.conn_info.connState ==
9620 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07009621 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309622 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009623 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309624
Jeff Johnson295189b2012-06-20 16:38:30 -07009625 if ( 0 != status )
9626 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309627 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009628 "%s: sme_RoamSetKey failure, returned %d",
9629 __func__, status);
9630 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9631 return -EINVAL;
9632 }
9633 }
9634 }
9635#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009636 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009637 return status;
9638}
9639
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309640#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9641static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9642 struct net_device *ndev,
9643 u8 key_index,
9644 bool pairwise,
9645 const u8 *mac_addr
9646 )
9647#else
9648static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9649 struct net_device *ndev,
9650 u8 key_index,
9651 const u8 *mac_addr
9652 )
9653#endif
9654{
9655 int ret;
9656
9657 vos_ssr_protect(__func__);
9658#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9659 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
9660 mac_addr);
9661#else
9662 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
9663#endif
9664 vos_ssr_unprotect(__func__);
9665
9666 return ret;
9667}
9668
Jeff Johnson295189b2012-06-20 16:38:30 -07009669/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309670 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009671 * This function is used to set the default tx key index
9672 */
9673#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309674static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009675 struct net_device *ndev,
9676 u8 key_index,
9677 bool unicast, bool multicast)
9678#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309679static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009680 struct net_device *ndev,
9681 u8 key_index)
9682#endif
9683{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309684 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309685 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309686 hdd_wext_state_t *pWextState;
9687 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309688 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009689
9690 ENTER();
9691
Gopichand Nakkala29149562013-05-10 21:43:41 +05309692 if ((NULL == pAdapter))
9693 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309695 "invalid adapter");
9696 return -EINVAL;
9697 }
9698
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309699 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9700 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
9701 pAdapter->sessionId, key_index));
9702
Gopichand Nakkala29149562013-05-10 21:43:41 +05309703 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9704 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9705
9706 if ((NULL == pWextState) || (NULL == pHddStaCtx))
9707 {
9708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9709 "invalid Wext state or HDD context");
9710 return -EINVAL;
9711 }
9712
Arif Hussain6d2a3322013-11-17 19:50:10 -08009713 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009714 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309715
Jeff Johnson295189b2012-06-20 16:38:30 -07009716 if (CSR_MAX_NUM_KEY <= key_index)
9717 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309718 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009719 key_index);
9720
9721 return -EINVAL;
9722 }
9723
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309724 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9725 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309726 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009727 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309728 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009729 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309730
Jeff Johnson295189b2012-06-20 16:38:30 -07009731 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07009732 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309733 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009734 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309735 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08009736 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309737 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08009738 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07009739 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309740 {
9741 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07009742 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309743
Jeff Johnson295189b2012-06-20 16:38:30 -07009744 tCsrRoamSetKey setKey;
9745 v_U32_t roamId= 0xFF;
9746 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309747
9748 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009749 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309750
Jeff Johnson295189b2012-06-20 16:38:30 -07009751 Keys->defaultIndex = (u8)key_index;
9752 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9753 setKey.keyId = key_index;
9754 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309755
9756 vos_mem_copy(&setKey.Key[0],
9757 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009758 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309759
Gopichand Nakkala29149562013-05-10 21:43:41 +05309760 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309761
9762 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07009763 &pHddStaCtx->conn_info.bssId[0],
9764 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309765
Gopichand Nakkala29149562013-05-10 21:43:41 +05309766 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
9767 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
9768 eCSR_ENCRYPT_TYPE_WEP104)
9769 {
9770 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
9771 even though ap is configured for WEP-40 encryption. In this canse the key length
9772 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
9773 type(104) and switching encryption type to 40*/
9774 pWextState->roamProfile.EncryptionType.encryptionType[0] =
9775 eCSR_ENCRYPT_TYPE_WEP40;
9776 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
9777 eCSR_ENCRYPT_TYPE_WEP40;
9778 }
9779
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309780 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07009781 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309782
Jeff Johnson295189b2012-06-20 16:38:30 -07009783 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309784 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009785 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309786
Jeff Johnson295189b2012-06-20 16:38:30 -07009787 if ( 0 != status )
9788 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309789 hddLog(VOS_TRACE_LEVEL_ERROR,
9790 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009791 status);
9792 return -EINVAL;
9793 }
9794 }
9795 }
9796
9797 /* In SoftAp mode setting key direction for default mode */
9798 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
9799 {
9800 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
9801 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
9802 (eCSR_ENCRYPT_TYPE_AES !=
9803 pWextState->roamProfile.EncryptionType.encryptionType[0])
9804 )
9805 {
9806 /* Saving key direction for default key index to TX default */
9807 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9808 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
9809 }
9810 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309811 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009812 return status;
9813}
9814
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309815#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9816static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9817 struct net_device *ndev,
9818 u8 key_index,
9819 bool unicast, bool multicast)
9820#else
9821static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9822 struct net_device *ndev,
9823 u8 key_index)
9824#endif
9825{
9826 int ret;
9827 vos_ssr_protect(__func__);
9828#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9829 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
9830 multicast);
9831#else
9832 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
9833#endif
9834 vos_ssr_unprotect(__func__);
9835
9836 return ret;
9837}
9838
Jeff Johnson295189b2012-06-20 16:38:30 -07009839/*
9840 * FUNCTION: wlan_hdd_cfg80211_inform_bss
9841 * This function is used to inform the BSS details to nl80211 interface.
9842 */
9843static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
9844 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
9845{
9846 struct net_device *dev = pAdapter->dev;
9847 struct wireless_dev *wdev = dev->ieee80211_ptr;
9848 struct wiphy *wiphy = wdev->wiphy;
9849 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
9850 int chan_no;
9851 int ie_length;
9852 const char *ie;
9853 unsigned int freq;
9854 struct ieee80211_channel *chan;
9855 int rssi = 0;
9856 struct cfg80211_bss *bss = NULL;
9857
Jeff Johnson295189b2012-06-20 16:38:30 -07009858 if( NULL == pBssDesc )
9859 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009860 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009861 return bss;
9862 }
9863
9864 chan_no = pBssDesc->channelId;
9865 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
9866 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
9867
9868 if( NULL == ie )
9869 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009870 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009871 return bss;
9872 }
9873
9874#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9875 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9876 {
9877 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9878 }
9879 else
9880 {
9881 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9882 }
9883#else
9884 freq = ieee80211_channel_to_frequency(chan_no);
9885#endif
9886
9887 chan = __ieee80211_get_channel(wiphy, freq);
9888
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05309889 if (!chan) {
9890 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
9891 return NULL;
9892 }
9893
Abhishek Singhaee43942014-06-16 18:55:47 +05309894 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07009895
Abhishek Singhaee43942014-06-16 18:55:47 +05309896 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309897 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07009898 pBssDesc->capabilityInfo,
9899 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05309900 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07009901}
9902
9903
9904
9905/*
9906 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
9907 * This function is used to inform the BSS details to nl80211 interface.
9908 */
9909struct cfg80211_bss*
9910wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
9911 tSirBssDescription *bss_desc
9912 )
9913{
9914 /*
9915 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
9916 already exists in bss data base of cfg80211 for that particular BSS ID.
9917 Using cfg80211_inform_bss_frame to update the bss entry instead of
9918 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
9919 now there is no possibility to get the mgmt(probe response) frame from PE,
9920 converting bss_desc to ieee80211_mgmt(probe response) and passing to
9921 cfg80211_inform_bss_frame.
9922 */
9923 struct net_device *dev = pAdapter->dev;
9924 struct wireless_dev *wdev = dev->ieee80211_ptr;
9925 struct wiphy *wiphy = wdev->wiphy;
9926 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009927#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9928 qcom_ie_age *qie_age = NULL;
9929 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
9930#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009931 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009932#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009933 const char *ie =
9934 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
9935 unsigned int freq;
9936 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309937 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009938 struct cfg80211_bss *bss_status = NULL;
9939 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
9940 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07009941 hdd_context_t *pHddCtx;
9942 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07009943#ifdef WLAN_OPEN_SOURCE
9944 struct timespec ts;
9945#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009946
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309947
Wilson Yangf80a0542013-10-07 13:02:37 -07009948 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9949 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -07009950 if (0 != status)
9951 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009952 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009953 }
9954
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309955 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07009956 if (!mgmt)
9957 {
9958 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9959 "%s: memory allocation failed ", __func__);
9960 return NULL;
9961 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009962
Jeff Johnson295189b2012-06-20 16:38:30 -07009963 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07009964
9965#ifdef WLAN_OPEN_SOURCE
9966 /* Android does not want the timestamp from the frame.
9967 Instead it wants a monotonic increasing value */
9968 get_monotonic_boottime(&ts);
9969 mgmt->u.probe_resp.timestamp =
9970 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
9971#else
9972 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009973 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
9974 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07009975
9976#endif
9977
Jeff Johnson295189b2012-06-20 16:38:30 -07009978 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
9979 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009980
9981#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9982 /* GPS Requirement: need age ie per entry. Using vendor specific. */
9983 /* Assuming this is the last IE, copy at the end */
9984 ie_length -=sizeof(qcom_ie_age);
9985 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
9986 qie_age->element_id = QCOM_VENDOR_IE_ID;
9987 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
9988 qie_age->oui_1 = QCOM_OUI1;
9989 qie_age->oui_2 = QCOM_OUI2;
9990 qie_age->oui_3 = QCOM_OUI3;
9991 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
9992 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
9993#endif
9994
Jeff Johnson295189b2012-06-20 16:38:30 -07009995 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05309996 if (bss_desc->fProbeRsp)
9997 {
9998 mgmt->frame_control |=
9999 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
10000 }
10001 else
10002 {
10003 mgmt->frame_control |=
10004 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
10005 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010006
10007#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010008 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010009 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
10010 {
10011 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10012 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010013 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010014 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
10015
10016 {
10017 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10018 }
10019 else
10020 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010021 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
10022 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070010023 kfree(mgmt);
10024 return NULL;
10025 }
10026#else
10027 freq = ieee80211_channel_to_frequency(chan_no);
10028#endif
10029 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010030 /*when the band is changed on the fly using the GUI, three things are done
10031 * 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)
10032 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
10033 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
10034 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
10035 * and discards the channels correponding to previous band and calls back with zero bss results.
10036 * 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
10037 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
10038 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
10039 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
10040 * So drop the bss and continue to next bss.
10041 */
10042 if(chan == NULL)
10043 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010044 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070010045 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010046 return NULL;
10047 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053010048 /*To keep the rssi icon of the connected AP in the scan window
10049 *and the rssi icon of the wireless networks in sync
10050 * */
10051 if (( eConnectionState_Associated ==
10052 pAdapter->sessionCtx.station.conn_info.connState ) &&
10053 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
10054 pAdapter->sessionCtx.station.conn_info.bssId,
10055 WNI_CFG_BSSID_LEN)) &&
10056 (pHddCtx->hdd_wlan_suspended == FALSE))
10057 {
10058 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
10059 rssi = (pAdapter->rssi * 100);
10060 }
10061 else
10062 {
10063 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
10064 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010065
Nirav Shah20ac06f2013-12-12 18:14:06 +053010066 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053010067 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
10068 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053010069
Jeff Johnson295189b2012-06-20 16:38:30 -070010070 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
10071 frame_len, rssi, GFP_KERNEL);
10072 kfree(mgmt);
10073 return bss_status;
10074}
10075
10076/*
10077 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
10078 * This function is used to update the BSS data base of CFG8011
10079 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010080struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010081 tCsrRoamInfo *pRoamInfo
10082 )
10083{
10084 tCsrRoamConnectedProfile roamProfile;
10085 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10086 struct cfg80211_bss *bss = NULL;
10087
10088 ENTER();
10089
10090 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
10091 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
10092
10093 if (NULL != roamProfile.pBssDesc)
10094 {
Girish Gowlif4b68022014-08-28 23:18:57 +053010095 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10096 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070010097
10098 if (NULL == bss)
10099 {
10100 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
10101 __func__);
10102 }
10103
10104 sme_RoamFreeConnectProfile(hHal, &roamProfile);
10105 }
10106 else
10107 {
10108 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
10109 __func__);
10110 }
10111 return bss;
10112}
10113
10114/*
10115 * FUNCTION: wlan_hdd_cfg80211_update_bss
10116 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010117static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
10118 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070010119 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010120{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010121 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010122 tCsrScanResultInfo *pScanResult;
10123 eHalStatus status = 0;
10124 tScanResultHandle pResult;
10125 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010126 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010127 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070010128 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010129
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010130 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10131 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
10132 NO_SESSION, pAdapter->sessionId));
10133
Wilson Yangf80a0542013-10-07 13:02:37 -070010134 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10135
10136 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070010137 {
Wilson Yangf80a0542013-10-07 13:02:37 -070010138 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10139 "%s:LOGP in Progress. Ignore!!!",__func__);
10140 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010141 }
10142
Wilson Yangf80a0542013-10-07 13:02:37 -070010143
10144 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053010145 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070010146 {
10147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10148 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
10149 return VOS_STATUS_E_PERM;
10150 }
10151
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010152 if (pAdapter->request != NULL)
10153 {
10154 if ((pAdapter->request->n_ssids == 1)
10155 && (pAdapter->request->ssids != NULL)
10156 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
10157 is_p2p_scan = true;
10158 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010159 /*
10160 * start getting scan results and populate cgf80211 BSS database
10161 */
10162 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
10163
10164 /* no scan results */
10165 if (NULL == pResult)
10166 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010167 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
10168 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053010169 wlan_hdd_get_frame_logs(pAdapter,
10170 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070010171 return status;
10172 }
10173
10174 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
10175
10176 while (pScanResult)
10177 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010178 /*
10179 * cfg80211_inform_bss() is not updating ie field of bss entry, if
10180 * entry already exists in bss data base of cfg80211 for that
10181 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
10182 * bss entry instead of cfg80211_inform_bss, But this call expects
10183 * mgmt packet as input. As of now there is no possibility to get
10184 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070010185 * ieee80211_mgmt(probe response) and passing to c
10186 * fg80211_inform_bss_frame.
10187 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010188 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
10189 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
10190 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010191 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10192 continue; //Skip the non p2p bss entries
10193 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010194 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10195 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010196
Jeff Johnson295189b2012-06-20 16:38:30 -070010197
10198 if (NULL == bss_status)
10199 {
10200 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010201 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010202 }
10203 else
10204 {
Yue Maf49ba872013-08-19 12:04:25 -070010205 cfg80211_put_bss(
10206#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
10207 wiphy,
10208#endif
10209 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010210 }
10211
10212 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10213 }
10214
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010215 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010216 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010217 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010218}
10219
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010220void
10221hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
10222{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010223 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080010224 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010225} /****** end hddPrintMacAddr() ******/
10226
10227void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010228hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010229{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010230 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010231 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010232 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
10233 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
10234 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010235} /****** end hddPrintPmkId() ******/
10236
10237//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
10238//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
10239
10240//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
10241//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
10242
10243#define dump_bssid(bssid) \
10244 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010245 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
10246 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010247 }
10248
10249#define dump_pmkid(pMac, pmkid) \
10250 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010251 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
10252 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010253 }
10254
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070010255#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010256/*
10257 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
10258 * This function is used to notify the supplicant of a new PMKSA candidate.
10259 */
10260int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010261 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010262 int index, bool preauth )
10263{
Jeff Johnsone7245742012-09-05 17:12:55 -070010264#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010265 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010266 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010267
10268 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070010269 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010270
10271 if( NULL == pRoamInfo )
10272 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010273 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010274 return -EINVAL;
10275 }
10276
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010277 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
10278 {
10279 dump_bssid(pRoamInfo->bssid);
10280 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010281 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010282 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010283#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010284 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010285}
10286#endif //FEATURE_WLAN_LFR
10287
Yue Maef608272013-04-08 23:09:17 -070010288#ifdef FEATURE_WLAN_LFR_METRICS
10289/*
10290 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
10291 * 802.11r/LFR metrics reporting function to report preauth initiation
10292 *
10293 */
10294#define MAX_LFR_METRICS_EVENT_LENGTH 100
10295VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
10296 tCsrRoamInfo *pRoamInfo)
10297{
10298 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10299 union iwreq_data wrqu;
10300
10301 ENTER();
10302
10303 if (NULL == pAdapter)
10304 {
10305 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10306 return VOS_STATUS_E_FAILURE;
10307 }
10308
10309 /* create the event */
10310 memset(&wrqu, 0, sizeof(wrqu));
10311 memset(metrics_notification, 0, sizeof(metrics_notification));
10312
10313 wrqu.data.pointer = metrics_notification;
10314 wrqu.data.length = scnprintf(metrics_notification,
10315 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
10316 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10317
10318 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10319
10320 EXIT();
10321
10322 return VOS_STATUS_SUCCESS;
10323}
10324
10325/*
10326 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
10327 * 802.11r/LFR metrics reporting function to report preauth completion
10328 * or failure
10329 */
10330VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
10331 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
10332{
10333 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10334 union iwreq_data wrqu;
10335
10336 ENTER();
10337
10338 if (NULL == pAdapter)
10339 {
10340 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10341 return VOS_STATUS_E_FAILURE;
10342 }
10343
10344 /* create the event */
10345 memset(&wrqu, 0, sizeof(wrqu));
10346 memset(metrics_notification, 0, sizeof(metrics_notification));
10347
10348 scnprintf(metrics_notification, sizeof(metrics_notification),
10349 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
10350 MAC_ADDR_ARRAY(pRoamInfo->bssid));
10351
10352 if (1 == preauth_status)
10353 strncat(metrics_notification, " TRUE", 5);
10354 else
10355 strncat(metrics_notification, " FALSE", 6);
10356
10357 wrqu.data.pointer = metrics_notification;
10358 wrqu.data.length = strlen(metrics_notification);
10359
10360 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10361
10362 EXIT();
10363
10364 return VOS_STATUS_SUCCESS;
10365}
10366
10367/*
10368 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
10369 * 802.11r/LFR metrics reporting function to report handover initiation
10370 *
10371 */
10372VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
10373 tCsrRoamInfo *pRoamInfo)
10374{
10375 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10376 union iwreq_data wrqu;
10377
10378 ENTER();
10379
10380 if (NULL == pAdapter)
10381 {
10382 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10383 return VOS_STATUS_E_FAILURE;
10384 }
10385
10386 /* create the event */
10387 memset(&wrqu, 0, sizeof(wrqu));
10388 memset(metrics_notification, 0, sizeof(metrics_notification));
10389
10390 wrqu.data.pointer = metrics_notification;
10391 wrqu.data.length = scnprintf(metrics_notification,
10392 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
10393 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10394
10395 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10396
10397 EXIT();
10398
10399 return VOS_STATUS_SUCCESS;
10400}
10401#endif
10402
Jeff Johnson295189b2012-06-20 16:38:30 -070010403/*
10404 * FUNCTION: hdd_cfg80211_scan_done_callback
10405 * scanning callback function, called after finishing scan
10406 *
10407 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010408static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070010409 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
10410{
10411 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010412 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070010413 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010414 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010415 struct cfg80211_scan_request *req = NULL;
10416 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010417 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010418 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010419 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010420 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010421
10422 ENTER();
10423
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010424 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053010425 if (NULL == pHddCtx) {
10426 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010427 goto allow_suspend;
10428 }
10429
10430 pScanInfo = &pHddCtx->scan_info;
10431
Jeff Johnson295189b2012-06-20 16:38:30 -070010432 hddLog(VOS_TRACE_LEVEL_INFO,
10433 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080010434 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010435 __func__, halHandle, pContext, (int) scanId, (int) status);
10436
Kiet Lamac06e2c2013-10-23 16:25:07 +053010437 pScanInfo->mScanPendingCounter = 0;
10438
Jeff Johnson295189b2012-06-20 16:38:30 -070010439 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010440 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070010441 &pScanInfo->scan_req_completion_event,
10442 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010443 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070010444 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010445 hddLog(VOS_TRACE_LEVEL_ERROR,
10446 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070010447 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010448 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010449 }
10450
Yue Maef608272013-04-08 23:09:17 -070010451 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010452 {
10453 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010454 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010455 }
10456
10457 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010458 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070010459 {
10460 hddLog(VOS_TRACE_LEVEL_INFO,
10461 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010462 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070010463 (int) scanId);
10464 }
10465
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010466 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010467 pAdapter);
10468
10469 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010470 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010471
10472
10473 /* If any client wait scan result through WEXT
10474 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010475 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070010476 {
10477 /* The other scan request waiting for current scan finish
10478 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010479 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010480 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010481 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070010482 }
10483 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010484 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010485 {
10486 struct net_device *dev = pAdapter->dev;
10487 union iwreq_data wrqu;
10488 int we_event;
10489 char *msg;
10490
10491 memset(&wrqu, '\0', sizeof(wrqu));
10492 we_event = SIOCGIWSCAN;
10493 msg = NULL;
10494 wireless_send_event(dev, we_event, &wrqu, msg);
10495 }
10496 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010497 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010498
10499 /* Get the Scan Req */
10500 req = pAdapter->request;
10501
10502 if (!req)
10503 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010504 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010505 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010506 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010507 }
10508
Jeff Johnson295189b2012-06-20 16:38:30 -070010509 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070010510 /* Scan is no longer pending */
10511 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010512
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010513 /* last_scan_timestamp is used to decide if new scan
10514 * is needed or not on station interface. If last station
10515 * scan time and new station scan time is less then
10516 * last_scan_timestamp ; driver will return cached scan.
10517 */
10518 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
10519 {
10520 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
10521
10522 if ( req->n_channels )
10523 {
10524 for (i = 0; i < req->n_channels ; i++ )
10525 {
10526 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
10527 }
10528 /* store no of channel scanned */
10529 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
10530 }
10531
10532 }
10533
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070010534 /*
10535 * cfg80211_scan_done informing NL80211 about completion
10536 * of scanning
10537 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010538 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
10539 {
10540 aborted = true;
10541 }
10542 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080010543 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010544
Siddharth Bhal76972212014-10-15 16:22:51 +053010545 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
10546 /* Generate new random mac addr for next scan */
10547 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
10548 hdd_processSpoofMacAddrRequest(pHddCtx);
10549 }
10550
Jeff Johnsone7245742012-09-05 17:12:55 -070010551allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010552 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010553 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010554
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010555 /* Acquire wakelock to handle the case where APP's tries to suspend
10556 * immediatly after the driver gets connect request(i.e after scan)
10557 * from supplicant, this result in app's is suspending and not able
10558 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010559 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010560
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010561#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010562 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010563#endif
10564
Jeff Johnson295189b2012-06-20 16:38:30 -070010565 EXIT();
10566 return 0;
10567}
10568
10569/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053010570 * FUNCTION: hdd_isConnectionInProgress
10571 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010572 *
10573 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010574v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010575{
10576 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10577 hdd_station_ctx_t *pHddStaCtx = NULL;
10578 hdd_adapter_t *pAdapter = NULL;
10579 VOS_STATUS status = 0;
10580 v_U8_t staId = 0;
10581 v_U8_t *staMac = NULL;
10582
c_hpothu9b781ba2013-12-30 20:57:45 +053010583 if (TRUE == pHddCtx->btCoexModeSet)
10584 {
10585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053010586 FL("BTCoex Mode operation in progress"));
10587 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053010588 }
10589
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010590 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10591
10592 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10593 {
10594 pAdapter = pAdapterNode->pAdapter;
10595
10596 if( pAdapter )
10597 {
10598 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010599 "%s: Adapter with device mode %s (%d) exists",
10600 __func__, hdd_device_modetoString(pAdapter->device_mode),
10601 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010602 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053010603 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10604 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
10605 (eConnectionState_Connecting ==
10606 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
10607 {
10608 hddLog(VOS_TRACE_LEVEL_ERROR,
10609 "%s: %p(%d) Connection is in progress", __func__,
10610 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10611 return VOS_TRUE;
10612 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010613 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053010614 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010615 {
10616 hddLog(VOS_TRACE_LEVEL_ERROR,
10617 "%s: %p(%d) Reassociation is in progress", __func__,
10618 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10619 return VOS_TRUE;
10620 }
10621 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010622 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10623 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010624 {
10625 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10626 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010627 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010628 {
10629 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
10630 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010631 "%s: client " MAC_ADDRESS_STR
10632 " is in the middle of WPS/EAPOL exchange.", __func__,
10633 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010634 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010635 }
10636 }
10637 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
10638 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
10639 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010640 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10641 ptSapContext pSapCtx = NULL;
10642 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10643 if(pSapCtx == NULL){
10644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10645 FL("psapCtx is NULL"));
10646 return VOS_FALSE;
10647 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010648 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
10649 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010650 if ((pSapCtx->aStaInfo[staId].isUsed) &&
10651 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010652 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010653 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010654
10655 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010656 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
10657 "middle of WPS/EAPOL exchange.", __func__,
10658 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010659 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010660 }
10661 }
10662 }
10663 }
10664 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10665 pAdapterNode = pNext;
10666 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053010667 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010668}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010669
10670/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010671 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070010672 * this scan respond to scan trigger and update cfg80211 scan database
10673 * later, scan dump command can be used to recieve scan results
10674 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010675int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010676#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10677 struct net_device *dev,
10678#endif
10679 struct cfg80211_scan_request *request)
10680{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010681 hdd_adapter_t *pAdapter = NULL;
10682 hdd_context_t *pHddCtx = NULL;
10683 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010684 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010685 tCsrScanRequest scanRequest;
10686 tANI_U8 *channelList = NULL, i;
10687 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010688 int status;
10689 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010690 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010691 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053010692 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010693 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053010694 v_S7_t rssi=0;
10695 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010696
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010697#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
10698 struct net_device *dev = NULL;
10699 if (NULL == request)
10700 {
10701 hddLog(VOS_TRACE_LEVEL_ERROR,
10702 "%s: scan req param null", __func__);
10703 return -EINVAL;
10704 }
10705 dev = request->wdev->netdev;
10706#endif
10707
10708 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
10709 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
10710 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10711
Jeff Johnson295189b2012-06-20 16:38:30 -070010712 ENTER();
10713
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010714 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10715 __func__, hdd_device_modetoString(pAdapter->device_mode),
10716 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010717
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010718 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010719 if (0 != status)
10720 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010721 return status;
10722 }
10723
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010724 if (NULL == pwextBuf)
10725 {
10726 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
10727 __func__);
10728 return -EIO;
10729 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010730 cfg_param = pHddCtx->cfg_ini;
10731 pScanInfo = &pHddCtx->scan_info;
10732
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053010733 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10734 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
10735 {
10736 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
10737 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
10738 }
10739
Jeff Johnson295189b2012-06-20 16:38:30 -070010740#ifdef WLAN_BTAMP_FEATURE
10741 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010742 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070010743 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010744 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010745 "%s: No scanning when AMP is on", __func__);
10746 return -EOPNOTSUPP;
10747 }
10748#endif
10749 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010750 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010751 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010752 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010753 "%s: Not scanning on device_mode = %s (%d)",
10754 __func__, hdd_device_modetoString(pAdapter->device_mode),
10755 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010756 return -EOPNOTSUPP;
10757 }
10758
10759 if (TRUE == pScanInfo->mScanPending)
10760 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010761 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
10762 {
10763 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
10764 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010765 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010766 }
10767
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010768 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070010769 //Channel and action frame is pending
10770 //Otherwise Cancel Remain On Channel and allow Scan
10771 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010772 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070010773 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010774 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010775 return -EBUSY;
10776 }
10777
Jeff Johnson295189b2012-06-20 16:38:30 -070010778 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
10779 {
10780 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080010781 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010782 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010783 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010784 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
10785 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010786 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010787 "%s: MAX TM Level Scan not allowed", __func__);
10788 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010789 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010790 }
10791 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
10792
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010793 /* Check if scan is allowed at this point of time.
10794 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010795 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010796 {
10797 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
10798 return -EBUSY;
10799 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010800
Jeff Johnson295189b2012-06-20 16:38:30 -070010801 vos_mem_zero( &scanRequest, sizeof(scanRequest));
10802
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010803 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
10804 * Becasue of this, driver is assuming that this is not wildcard scan and so
10805 * is not aging out the scan results.
10806 */
10807 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010808 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010809 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010810 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010811
10812 if ((request->ssids) && (0 < request->n_ssids))
10813 {
10814 tCsrSSIDInfo *SsidInfo;
10815 int j;
10816 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
10817 /* Allocate num_ssid tCsrSSIDInfo structure */
10818 SsidInfo = scanRequest.SSIDs.SSIDList =
10819 ( tCsrSSIDInfo *)vos_mem_malloc(
10820 request->n_ssids*sizeof(tCsrSSIDInfo));
10821
10822 if(NULL == scanRequest.SSIDs.SSIDList)
10823 {
10824 hddLog(VOS_TRACE_LEVEL_ERROR,
10825 "%s: memory alloc failed SSIDInfo buffer", __func__);
10826 return -ENOMEM;
10827 }
10828
10829 /* copy all the ssid's and their length */
10830 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
10831 {
10832 /* get the ssid length */
10833 SsidInfo->SSID.length = request->ssids[j].ssid_len;
10834 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
10835 SsidInfo->SSID.length);
10836 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
10837 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
10838 j, SsidInfo->SSID.ssId);
10839 }
10840 /* set the scan type to active */
10841 scanRequest.scanType = eSIR_ACTIVE_SCAN;
10842 }
10843 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070010844 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010845 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10846 TRACE_CODE_HDD_CFG80211_SCAN,
10847 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070010848 /* set the scan type to active */
10849 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010850 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010851 else
10852 {
10853 /*Set the scan type to default type, in this case it is ACTIVE*/
10854 scanRequest.scanType = pScanInfo->scan_mode;
10855 }
10856 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
10857 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070010858
10859 /* set BSSType to default type */
10860 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
10861
10862 /*TODO: scan the requested channels only*/
10863
10864 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010865 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070010866 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010867 hddLog(VOS_TRACE_LEVEL_WARN,
10868 "No of Scan Channels exceeded limit: %d", request->n_channels);
10869 request->n_channels = MAX_CHANNEL;
10870 }
10871
10872 hddLog(VOS_TRACE_LEVEL_INFO,
10873 "No of Scan Channels: %d", request->n_channels);
10874
10875
10876 if( request->n_channels )
10877 {
10878 char chList [(request->n_channels*5)+1];
10879 int len;
10880 channelList = vos_mem_malloc( request->n_channels );
10881 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053010882 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010883 hddLog(VOS_TRACE_LEVEL_ERROR,
10884 "%s: memory alloc failed channelList", __func__);
10885 status = -ENOMEM;
10886 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053010887 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010888
10889 for( i = 0, len = 0; i < request->n_channels ; i++ )
10890 {
10891 channelList[i] = request->channels[i]->hw_value;
10892 len += snprintf(chList+len, 5, "%d ", channelList[i]);
10893 }
10894
Nirav Shah20ac06f2013-12-12 18:14:06 +053010895 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010896 "Channel-List: %s ", chList);
10897 }
c_hpothu53512302014-04-15 18:49:53 +053010898
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010899 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
10900 scanRequest.ChannelInfo.ChannelList = channelList;
10901
10902 /* set requestType to full scan */
10903 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10904
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010905 /* if there is back to back scan happening in driver with in
10906 * nDeferScanTimeInterval interval driver should defer new scan request
10907 * and should provide last cached scan results instead of new channel list.
10908 * This rule is not applicable if scan is p2p scan.
10909 * This condition will work only in case when last request no of channels
10910 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053010911 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053010912 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010913 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010914
Sushant Kaushik86592172015-04-27 16:35:03 +053010915 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
10916 /* if wps ie is NULL , then only defer scan */
10917 if ( pWpsIe == NULL &&
10918 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053010919 {
10920 if ( pScanInfo->last_scan_timestamp !=0 &&
10921 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
10922 {
10923 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
10924 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
10925 vos_mem_compare(pScanInfo->last_scan_channelList,
10926 channelList, pScanInfo->last_scan_numChannels))
10927 {
10928 hddLog(VOS_TRACE_LEVEL_WARN,
10929 " New and old station scan time differ is less then %u",
10930 pHddCtx->cfg_ini->nDeferScanTimeInterval);
10931
10932 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010933 pAdapter);
10934
Agarwal Ashish57e84372014-12-05 18:26:53 +053010935 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010936 "Return old cached scan as all channels and no of channels are same");
10937
Agarwal Ashish57e84372014-12-05 18:26:53 +053010938 if (0 > ret)
10939 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010940
Agarwal Ashish57e84372014-12-05 18:26:53 +053010941 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010942
10943 status = eHAL_STATUS_SUCCESS;
10944 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053010945 }
10946 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010947 }
10948
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010949 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10950 * search (Flush on both full scan and social scan but not on single
10951 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10952 */
10953
10954 /* Supplicant does single channel scan after 8-way handshake
10955 * and in that case driver shoudnt flush scan results. If
10956 * driver flushes the scan results here and unfortunately if
10957 * the AP doesnt respond to our probe req then association
10958 * fails which is not desired
10959 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010960 if ((request->n_ssids == 1)
10961 && (request->ssids != NULL)
10962 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
10963 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010964
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010965 if( is_p2p_scan ||
10966 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010967 {
10968 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
10969 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
10970 pAdapter->sessionId );
10971 }
10972
10973 if( request->ie_len )
10974 {
10975 /* save this for future association (join requires this) */
10976 /*TODO: Array needs to be converted to dynamic allocation,
10977 * as multiple ie.s can be sent in cfg80211_scan_request structure
10978 * CR 597966
10979 */
10980 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
10981 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
10982 pScanInfo->scanAddIE.length = request->ie_len;
10983
10984 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10985 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10986 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010987 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053010988 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070010989 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010990 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
10991 memcpy( pwextBuf->roamProfile.addIEScan,
10992 request->ie, request->ie_len);
10993 }
10994 else
10995 {
10996 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
10997 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070010998 }
10999
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011000 }
11001 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
11002 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
11003
11004 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
11005 request->ie_len);
11006 if (pP2pIe != NULL)
11007 {
11008#ifdef WLAN_FEATURE_P2P_DEBUG
11009 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
11010 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
11011 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053011012 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011013 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
11014 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11015 "Go nego completed to Connection is started");
11016 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11017 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053011018 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011019 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
11020 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011021 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011022 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
11023 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11024 "Disconnected state to Connection is started");
11025 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11026 "for 4way Handshake");
11027 }
11028#endif
11029
11030 /* no_cck will be set during p2p find to disable 11b rates */
11031 if(TRUE == request->no_cck)
11032 {
11033 hddLog(VOS_TRACE_LEVEL_INFO,
11034 "%s: This is a P2P Search", __func__);
11035 scanRequest.p2pSearch = 1;
11036
11037 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053011038 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011039 /* set requestType to P2P Discovery */
11040 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
11041 }
11042
11043 /*
11044 Skip Dfs Channel in case of P2P Search
11045 if it is set in ini file
11046 */
11047 if(cfg_param->skipDfsChnlInP2pSearch)
11048 {
11049 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011050 }
11051 else
11052 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011053 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011054 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011055
Agarwal Ashish4f616132013-12-30 23:32:50 +053011056 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011057 }
11058 }
11059
11060 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
11061
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011062#ifdef FEATURE_WLAN_TDLS
11063 /* if tdls disagree scan right now, return immediately.
11064 tdls will schedule the scan when scan is allowed. (return SUCCESS)
11065 or will reject the scan if any TDLS is in progress. (return -EBUSY)
11066 */
11067 status = wlan_hdd_tdls_scan_callback (pAdapter,
11068 wiphy,
11069#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11070 dev,
11071#endif
11072 request);
11073 if(status <= 0)
11074 {
11075 if(!status)
11076 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
11077 "scan rejected %d", __func__, status);
11078 else
11079 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
11080 __func__, status);
11081
11082 return status;
11083 }
11084#endif
11085
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011086 /* acquire the wakelock to avoid the apps suspend during the scan. To
11087 * address the following issues.
11088 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
11089 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
11090 * for long time, this result in apps running at full power for long time.
11091 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
11092 * be stuck in full power because of resume BMPS
11093 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011094 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011095
Nirav Shah20ac06f2013-12-12 18:14:06 +053011096 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11097 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011098 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
11099 scanRequest.requestType, scanRequest.scanType,
11100 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053011101 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
11102
Siddharth Bhal76972212014-10-15 16:22:51 +053011103 if (pHddCtx->spoofMacAddr.isEnabled)
11104 {
11105 hddLog(VOS_TRACE_LEVEL_INFO,
11106 "%s: MAC Spoofing enabled for current scan", __func__);
11107 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
11108 * to fill TxBds for probe request during current scan
11109 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011110 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053011111 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011112
11113 if(status != VOS_STATUS_SUCCESS)
11114 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011115 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011116 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053011117#ifdef FEATURE_WLAN_TDLS
11118 wlan_hdd_tdls_scan_done_callback(pAdapter);
11119#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011120 goto free_mem;
11121 }
Siddharth Bhal76972212014-10-15 16:22:51 +053011122 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053011123 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070011124 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011125 pAdapter->sessionId, &scanRequest, &scanId,
11126 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070011127
Jeff Johnson295189b2012-06-20 16:38:30 -070011128 if (eHAL_STATUS_SUCCESS != status)
11129 {
11130 hddLog(VOS_TRACE_LEVEL_ERROR,
11131 "%s: sme_ScanRequest returned error %d", __func__, status);
11132 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011133 if(eHAL_STATUS_RESOURCES == status)
11134 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011135 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
11136 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011137 status = -EBUSY;
11138 } else {
11139 status = -EIO;
11140 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011141 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011142
11143#ifdef FEATURE_WLAN_TDLS
11144 wlan_hdd_tdls_scan_done_callback(pAdapter);
11145#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011146 goto free_mem;
11147 }
11148
11149 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011150 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011151 pAdapter->request = request;
11152 pScanInfo->scanId = scanId;
11153
11154 complete(&pScanInfo->scan_req_completion_event);
11155
11156free_mem:
11157 if( scanRequest.SSIDs.SSIDList )
11158 {
11159 vos_mem_free(scanRequest.SSIDs.SSIDList);
11160 }
11161
11162 if( channelList )
11163 vos_mem_free( channelList );
11164
11165 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011166 return status;
11167}
11168
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011169int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
11170#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11171 struct net_device *dev,
11172#endif
11173 struct cfg80211_scan_request *request)
11174{
11175 int ret;
11176
11177 vos_ssr_protect(__func__);
11178 ret = __wlan_hdd_cfg80211_scan(wiphy,
11179#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11180 dev,
11181#endif
11182 request);
11183 vos_ssr_unprotect(__func__);
11184
11185 return ret;
11186}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011187
11188void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
11189{
11190 v_U8_t iniDot11Mode =
11191 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
11192 eHddDot11Mode hddDot11Mode = iniDot11Mode;
11193
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011194 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
11195 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011196 switch ( iniDot11Mode )
11197 {
11198 case eHDD_DOT11_MODE_AUTO:
11199 case eHDD_DOT11_MODE_11ac:
11200 case eHDD_DOT11_MODE_11ac_ONLY:
11201#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053011202 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
11203 sme_IsFeatureSupportedByFW(DOT11AC) )
11204 hddDot11Mode = eHDD_DOT11_MODE_11ac;
11205 else
11206 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011207#else
11208 hddDot11Mode = eHDD_DOT11_MODE_11n;
11209#endif
11210 break;
11211 case eHDD_DOT11_MODE_11n:
11212 case eHDD_DOT11_MODE_11n_ONLY:
11213 hddDot11Mode = eHDD_DOT11_MODE_11n;
11214 break;
11215 default:
11216 hddDot11Mode = iniDot11Mode;
11217 break;
11218 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011219#ifdef WLAN_FEATURE_AP_HT40_24G
11220 if (operationChannel > SIR_11B_CHANNEL_END)
11221#endif
11222 {
11223 /* This call decides required channel bonding mode */
11224 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011225 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
11226 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011227 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011228}
11229
Jeff Johnson295189b2012-06-20 16:38:30 -070011230/*
11231 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011232 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011233 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011234int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011235 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070011236{
11237 int status = 0;
11238 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080011239 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011240 v_U32_t roamId;
11241 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070011242 eCsrAuthType RSNAuthType;
11243
11244 ENTER();
11245
11246 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080011247 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11248
11249 status = wlan_hdd_validate_context(pHddCtx);
11250 if (status)
11251 {
Yue Mae36e3552014-03-05 17:06:20 -080011252 return status;
11253 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011254
Jeff Johnson295189b2012-06-20 16:38:30 -070011255 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
11256 {
11257 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
11258 return -EINVAL;
11259 }
11260
11261 pRoamProfile = &pWextState->roamProfile;
11262
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011263 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070011264 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011265 hdd_station_ctx_t *pHddStaCtx;
11266 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011267
Siddharth Bhalda0d1622015-04-24 15:47:49 +053011268 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
11269
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011270 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070011271 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
11272 {
11273 /*QoS not enabled in cfg file*/
11274 pRoamProfile->uapsd_mask = 0;
11275 }
11276 else
11277 {
11278 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011279 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070011280 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
11281 }
11282
11283 pRoamProfile->SSIDs.numOfSSIDs = 1;
11284 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
11285 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011286 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070011287 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
11288 ssid, ssid_len);
11289
11290 if (bssid)
11291 {
11292 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
11293 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
11294 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011295 /* Save BSSID in seperate variable as well, as RoamProfile
11296 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070011297 case of join failure we should send valid BSSID to supplicant
11298 */
11299 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
11300 WNI_CFG_BSSID_LEN);
11301 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070011302 else
11303 {
11304 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
11305 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011306
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011307 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
11308 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011309 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
11310 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011311 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011312 /*set gen ie*/
11313 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
11314 /*set auth*/
11315 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
11316 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011317#ifdef FEATURE_WLAN_WAPI
11318 if (pAdapter->wapi_info.nWapiMode)
11319 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011320 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011321 switch (pAdapter->wapi_info.wapiAuthMode)
11322 {
11323 case WAPI_AUTH_MODE_PSK:
11324 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011325 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011326 pAdapter->wapi_info.wapiAuthMode);
11327 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
11328 break;
11329 }
11330 case WAPI_AUTH_MODE_CERT:
11331 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011332 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011333 pAdapter->wapi_info.wapiAuthMode);
11334 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
11335 break;
11336 }
11337 } // End of switch
11338 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
11339 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
11340 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011341 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011342 pRoamProfile->AuthType.numEntries = 1;
11343 pRoamProfile->EncryptionType.numEntries = 1;
11344 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11345 pRoamProfile->mcEncryptionType.numEntries = 1;
11346 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11347 }
11348 }
11349#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011350#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011351 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011352 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11353 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
11354 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011355 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
11356 sizeof (tSirGtkOffloadParams));
11357 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011358 }
11359#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011360 pRoamProfile->csrPersona = pAdapter->device_mode;
11361
Jeff Johnson32d95a32012-09-10 13:15:23 -070011362 if( operatingChannel )
11363 {
11364 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
11365 pRoamProfile->ChannelInfo.numOfChannels = 1;
11366 }
Chet Lanctot186b5732013-03-18 10:26:30 -070011367 else
11368 {
11369 pRoamProfile->ChannelInfo.ChannelList = NULL;
11370 pRoamProfile->ChannelInfo.numOfChannels = 0;
11371 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011372 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
11373 {
11374 hdd_select_cbmode(pAdapter,operatingChannel);
11375 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011376
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011377 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
11378 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011379 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011380 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011381 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
11382 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011383 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11384 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053011385 {
11386 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11387 "%s: Set HDD connState to eConnectionState_Connecting",
11388 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011389 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
11390 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053011391 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011392 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011393 pAdapter->sessionId, pRoamProfile, &roamId);
11394
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011395 if ((eHAL_STATUS_SUCCESS != status) &&
11396 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11397 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011398
11399 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011400 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
11401 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
11402 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011403 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011404 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011405 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011406
11407 pRoamProfile->ChannelInfo.ChannelList = NULL;
11408 pRoamProfile->ChannelInfo.numOfChannels = 0;
11409
Jeff Johnson295189b2012-06-20 16:38:30 -070011410 }
11411 else
11412 {
11413 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
11414 return -EINVAL;
11415 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011416 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011417 return status;
11418}
11419
11420/*
11421 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
11422 * This function is used to set the authentication type (OPEN/SHARED).
11423 *
11424 */
11425static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
11426 enum nl80211_auth_type auth_type)
11427{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011428 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011429 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11430
11431 ENTER();
11432
11433 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011434 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070011435 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011436 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011437 hddLog(VOS_TRACE_LEVEL_INFO,
11438 "%s: set authentication type to AUTOSWITCH", __func__);
11439 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
11440 break;
11441
11442 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011443#ifdef WLAN_FEATURE_VOWIFI_11R
11444 case NL80211_AUTHTYPE_FT:
11445#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011446 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011447 "%s: set authentication type to OPEN", __func__);
11448 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11449 break;
11450
11451 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011452 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011453 "%s: set authentication type to SHARED", __func__);
11454 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
11455 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011456#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011457 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011458 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011459 "%s: set authentication type to CCKM WPA", __func__);
11460 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
11461 break;
11462#endif
11463
11464
11465 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011466 hddLog(VOS_TRACE_LEVEL_ERROR,
11467 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011468 auth_type);
11469 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
11470 return -EINVAL;
11471 }
11472
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011473 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011474 pHddStaCtx->conn_info.authType;
11475 return 0;
11476}
11477
11478/*
11479 * FUNCTION: wlan_hdd_set_akm_suite
11480 * This function is used to set the key mgmt type(PSK/8021x).
11481 *
11482 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011483static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011484 u32 key_mgmt
11485 )
11486{
11487 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11488 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053011489 /* Should be in ieee802_11_defs.h */
11490#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
11491#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070011492 /*set key mgmt type*/
11493 switch(key_mgmt)
11494 {
11495 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053011496 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011497#ifdef WLAN_FEATURE_VOWIFI_11R
11498 case WLAN_AKM_SUITE_FT_PSK:
11499#endif
11500 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070011501 __func__);
11502 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
11503 break;
11504
11505 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053011506 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011507#ifdef WLAN_FEATURE_VOWIFI_11R
11508 case WLAN_AKM_SUITE_FT_8021X:
11509#endif
11510 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070011511 __func__);
11512 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11513 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011514#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011515#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
11516#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
11517 case WLAN_AKM_SUITE_CCKM:
11518 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
11519 __func__);
11520 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
11521 break;
11522#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070011523#ifndef WLAN_AKM_SUITE_OSEN
11524#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
11525 case WLAN_AKM_SUITE_OSEN:
11526 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
11527 __func__);
11528 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11529 break;
11530#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011531
11532 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011533 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011534 __func__, key_mgmt);
11535 return -EINVAL;
11536
11537 }
11538 return 0;
11539}
11540
11541/*
11542 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011543 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070011544 * (NONE/WEP40/WEP104/TKIP/CCMP).
11545 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011546static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
11547 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070011548 bool ucast
11549 )
11550{
11551 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011552 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011553 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11554
11555 ENTER();
11556
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011557 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011558 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011559 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070011560 __func__, cipher);
11561 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11562 }
11563 else
11564 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011565
Jeff Johnson295189b2012-06-20 16:38:30 -070011566 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011567 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011568 {
11569 case IW_AUTH_CIPHER_NONE:
11570 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11571 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011572
Jeff Johnson295189b2012-06-20 16:38:30 -070011573 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011574 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070011575 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011576
Jeff Johnson295189b2012-06-20 16:38:30 -070011577 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011578 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070011579 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011580
Jeff Johnson295189b2012-06-20 16:38:30 -070011581 case WLAN_CIPHER_SUITE_TKIP:
11582 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
11583 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011584
Jeff Johnson295189b2012-06-20 16:38:30 -070011585 case WLAN_CIPHER_SUITE_CCMP:
11586 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11587 break;
11588#ifdef FEATURE_WLAN_WAPI
11589 case WLAN_CIPHER_SUITE_SMS4:
11590 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
11591 break;
11592#endif
11593
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011594#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011595 case WLAN_CIPHER_SUITE_KRK:
11596 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
11597 break;
11598#endif
11599 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011600 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011601 __func__, cipher);
11602 return -EOPNOTSUPP;
11603 }
11604 }
11605
11606 if (ucast)
11607 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011608 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011609 __func__, encryptionType);
11610 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11611 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011612 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011613 encryptionType;
11614 }
11615 else
11616 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011617 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011618 __func__, encryptionType);
11619 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
11620 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
11621 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
11622 }
11623
11624 return 0;
11625}
11626
11627
11628/*
11629 * FUNCTION: wlan_hdd_cfg80211_set_ie
11630 * This function is used to parse WPA/RSN IE's.
11631 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011632int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011633#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11634 const u8 *ie,
11635#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011636 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011637#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011638 size_t ie_len
11639 )
11640{
11641 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011642#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11643 const u8 *genie = ie;
11644#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011645 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011646#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011647 v_U16_t remLen = ie_len;
11648#ifdef FEATURE_WLAN_WAPI
11649 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
11650 u16 *tmp;
11651 v_U16_t akmsuiteCount;
11652 int *akmlist;
11653#endif
11654 ENTER();
11655
11656 /* clear previous assocAddIE */
11657 pWextState->assocAddIE.length = 0;
11658 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011659 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011660
11661 while (remLen >= 2)
11662 {
11663 v_U16_t eLen = 0;
11664 v_U8_t elementId;
11665 elementId = *genie++;
11666 eLen = *genie++;
11667 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011668
Arif Hussain6d2a3322013-11-17 19:50:10 -080011669 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070011670 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011671
11672 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070011673 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011674 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011675 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 -070011676 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011677 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011678 "%s: Invalid WPA IE", __func__);
11679 return -EINVAL;
11680 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011681 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070011682 {
11683 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011684 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011685 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011686
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011687 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011688 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011689 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
11690 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011691 VOS_ASSERT(0);
11692 return -ENOMEM;
11693 }
11694 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11695 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11696 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011697
Jeff Johnson295189b2012-06-20 16:38:30 -070011698 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
11699 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11700 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11701 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011702 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
11703 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011704 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
11705 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11706 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
11707 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
11708 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
11709 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011710 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053011711 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011712 {
11713 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011714 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011715 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011716
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011717 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011718 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011719 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11720 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011721 VOS_ASSERT(0);
11722 return -ENOMEM;
11723 }
11724 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11725 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11726 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011727
Jeff Johnson295189b2012-06-20 16:38:30 -070011728 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11729 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11730 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011731#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011732 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
11733 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011734 /*Consider WFD IE, only for P2P Client */
11735 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11736 {
11737 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011738 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011739 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011740
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011741 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011742 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011743 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11744 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011745 VOS_ASSERT(0);
11746 return -ENOMEM;
11747 }
11748 // WFD IE is saved to Additional IE ; it should be accumulated to handle
11749 // WPS IE + P2P IE + WFD IE
11750 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11751 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011752
Jeff Johnson295189b2012-06-20 16:38:30 -070011753 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11754 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11755 }
11756#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011757 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011758 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011759 HS20_OUI_TYPE_SIZE)) )
11760 {
11761 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011762 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011763 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011764
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011765 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011766 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011767 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11768 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011769 VOS_ASSERT(0);
11770 return -ENOMEM;
11771 }
11772 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11773 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011774
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011775 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11776 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11777 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011778 /* Appending OSEN Information Element in Assiciation Request */
11779 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
11780 OSEN_OUI_TYPE_SIZE)) )
11781 {
11782 v_U16_t curAddIELen = pWextState->assocAddIE.length;
11783 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
11784 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011785
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011786 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011787 {
11788 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11789 "Need bigger buffer space");
11790 VOS_ASSERT(0);
11791 return -ENOMEM;
11792 }
11793 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11794 pWextState->assocAddIE.length += eLen + 2;
11795
11796 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
11797 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11798 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11799 }
11800
Abhishek Singh4322e622015-06-10 15:42:54 +053011801 /* Update only for WPA IE */
11802 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
11803 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070011804
11805 /* populating as ADDIE in beacon frames */
11806 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011807 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070011808 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
11809 {
11810 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11811 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
11812 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11813 {
11814 hddLog(LOGE,
11815 "Coldn't pass "
11816 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
11817 }
11818 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
11819 else
11820 hddLog(LOGE,
11821 "Could not pass on "
11822 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
11823
11824 /* IBSS mode doesn't contain params->proberesp_ies still
11825 beaconIE's need to be populated in probe response frames */
11826 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
11827 {
11828 u16 rem_probe_resp_ie_len = eLen + 2;
11829 u8 probe_rsp_ie_len[3] = {0};
11830 u8 counter = 0;
11831
11832 /* Check Probe Resp Length if it is greater then 255 then
11833 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
11834 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
11835 not able Store More then 255 bytes into One Variable */
11836
11837 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
11838 {
11839 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
11840 {
11841 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
11842 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
11843 }
11844 else
11845 {
11846 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
11847 rem_probe_resp_ie_len = 0;
11848 }
11849 }
11850
11851 rem_probe_resp_ie_len = 0;
11852
11853 if (probe_rsp_ie_len[0] > 0)
11854 {
11855 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11856 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
11857 (tANI_U8*)(genie - 2),
11858 probe_rsp_ie_len[0], NULL,
11859 eANI_BOOLEAN_FALSE)
11860 == eHAL_STATUS_FAILURE)
11861 {
11862 hddLog(LOGE,
11863 "Could not pass"
11864 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
11865 }
11866 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
11867 }
11868
11869 if (probe_rsp_ie_len[1] > 0)
11870 {
11871 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11872 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
11873 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11874 probe_rsp_ie_len[1], NULL,
11875 eANI_BOOLEAN_FALSE)
11876 == eHAL_STATUS_FAILURE)
11877 {
11878 hddLog(LOGE,
11879 "Could not pass"
11880 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
11881 }
11882 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
11883 }
11884
11885 if (probe_rsp_ie_len[2] > 0)
11886 {
11887 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11888 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
11889 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11890 probe_rsp_ie_len[2], NULL,
11891 eANI_BOOLEAN_FALSE)
11892 == eHAL_STATUS_FAILURE)
11893 {
11894 hddLog(LOGE,
11895 "Could not pass"
11896 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
11897 }
11898 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
11899 }
11900
11901 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11902 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
11903 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11904 {
11905 hddLog(LOGE,
11906 "Could not pass"
11907 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
11908 }
11909 }
11910 else
11911 {
11912 // Reset WNI_CFG_PROBE_RSP Flags
11913 wlan_hdd_reset_prob_rspies(pAdapter);
11914
11915 hddLog(VOS_TRACE_LEVEL_INFO,
11916 "%s: No Probe Response IE received in set beacon",
11917 __func__);
11918 }
11919 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011920 break;
11921 case DOT11F_EID_RSN:
11922 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
11923 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11924 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
11925 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
11926 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
11927 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053011928
11929 /* Appending Extended Capabilities with Interworking bit set
11930 * in Assoc Req.
11931 *
11932 * In assoc req this EXT Cap will only be taken into account if
11933 * interworkingService bit is set to 1. Currently
11934 * driver is only interested in interworkingService capability
11935 * from supplicant. If in future any other EXT Cap info is
11936 * required from supplicat, it needs to be handled while
11937 * sending Assoc Req in LIM.
11938 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011939 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011940 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011941 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011942 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011943 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011944
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011945 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011946 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011947 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11948 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011949 VOS_ASSERT(0);
11950 return -ENOMEM;
11951 }
11952 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11953 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011954
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011955 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11956 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11957 break;
11958 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011959#ifdef FEATURE_WLAN_WAPI
11960 case WLAN_EID_WAPI:
11961 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011962 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011963 pAdapter->wapi_info.nWapiMode);
11964 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011965 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070011966 akmsuiteCount = WPA_GET_LE16(tmp);
11967 tmp = tmp + 1;
11968 akmlist = (int *)(tmp);
11969 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
11970 {
11971 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
11972 }
11973 else
11974 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011975 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070011976 VOS_ASSERT(0);
11977 return -EINVAL;
11978 }
11979
11980 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
11981 {
11982 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011983 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011984 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011985 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011986 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011987 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011988 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011989 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011990 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
11991 }
11992 break;
11993#endif
11994 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011995 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011996 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011997 /* when Unknown IE is received we should break and continue
11998 * to the next IE in the buffer instead we were returning
11999 * so changing this to break */
12000 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070012001 }
12002 genie += eLen;
12003 remLen -= eLen;
12004 }
12005 EXIT();
12006 return 0;
12007}
12008
12009/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012010 * FUNCTION: hdd_isWPAIEPresent
12011 * Parse the received IE to find the WPA IE
12012 *
12013 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012014static bool hdd_isWPAIEPresent(
12015#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
12016 const u8 *ie,
12017#else
12018 u8 *ie,
12019#endif
12020 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012021{
12022 v_U8_t eLen = 0;
12023 v_U16_t remLen = ie_len;
12024 v_U8_t elementId = 0;
12025
12026 while (remLen >= 2)
12027 {
12028 elementId = *ie++;
12029 eLen = *ie++;
12030 remLen -= 2;
12031 if (eLen > remLen)
12032 {
12033 hddLog(VOS_TRACE_LEVEL_ERROR,
12034 "%s: IE length is wrong %d", __func__, eLen);
12035 return FALSE;
12036 }
12037 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
12038 {
12039 /* OUI - 0x00 0X50 0XF2
12040 WPA Information Element - 0x01
12041 WPA version - 0x01*/
12042 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
12043 return TRUE;
12044 }
12045 ie += eLen;
12046 remLen -= eLen;
12047 }
12048 return FALSE;
12049}
12050
12051/*
Jeff Johnson295189b2012-06-20 16:38:30 -070012052 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012053 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012054 * parameters during connect operation.
12055 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012056int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012057 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012058 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012059{
12060 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012061 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012062 ENTER();
12063
12064 /*set wpa version*/
12065 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
12066
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012067 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012068 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053012069 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012070 {
12071 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12072 }
12073 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
12074 {
12075 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12076 }
12077 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012078
12079 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012080 pWextState->wpaVersion);
12081
12082 /*set authentication type*/
12083 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
12084
12085 if (0 > status)
12086 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012087 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012088 "%s: failed to set authentication type ", __func__);
12089 return status;
12090 }
12091
12092 /*set key mgmt type*/
12093 if (req->crypto.n_akm_suites)
12094 {
12095 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
12096 if (0 > status)
12097 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012098 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070012099 __func__);
12100 return status;
12101 }
12102 }
12103
12104 /*set pairwise cipher type*/
12105 if (req->crypto.n_ciphers_pairwise)
12106 {
12107 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
12108 req->crypto.ciphers_pairwise[0], true);
12109 if (0 > status)
12110 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012111 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012112 "%s: failed to set unicast cipher type", __func__);
12113 return status;
12114 }
12115 }
12116 else
12117 {
12118 /*Reset previous cipher suite to none*/
12119 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
12120 if (0 > status)
12121 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012122 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012123 "%s: failed to set unicast cipher type", __func__);
12124 return status;
12125 }
12126 }
12127
12128 /*set group cipher type*/
12129 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
12130 false);
12131
12132 if (0 > status)
12133 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012134 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070012135 __func__);
12136 return status;
12137 }
12138
Chet Lanctot186b5732013-03-18 10:26:30 -070012139#ifdef WLAN_FEATURE_11W
12140 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
12141#endif
12142
Jeff Johnson295189b2012-06-20 16:38:30 -070012143 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
12144 if (req->ie_len)
12145 {
12146 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
12147 if ( 0 > status)
12148 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012149 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012150 __func__);
12151 return status;
12152 }
12153 }
12154
12155 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012156 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012157 {
12158 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
12159 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
12160 )
12161 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012162 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070012163 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
12164 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012165 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012166 __func__);
12167 return -EOPNOTSUPP;
12168 }
12169 else
12170 {
12171 u8 key_len = req->key_len;
12172 u8 key_idx = req->key_idx;
12173
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012174 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012175 && (CSR_MAX_NUM_KEY > key_idx)
12176 )
12177 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012178 hddLog(VOS_TRACE_LEVEL_INFO,
12179 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012180 __func__, key_idx, key_len);
12181 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012182 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012183 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012184 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012185 (u8)key_len;
12186 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
12187 }
12188 }
12189 }
12190 }
12191
12192 return status;
12193}
12194
12195/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012196 * FUNCTION: wlan_hdd_try_disconnect
12197 * This function is used to disconnect from previous
12198 * connection
12199 */
12200static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
12201{
12202 long ret = 0;
12203 hdd_station_ctx_t *pHddStaCtx;
12204 eMib_dot11DesiredBssType connectedBssType;
12205
12206 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12207
12208 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
12209
12210 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
12211 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
12212 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
12213 {
12214 /* Issue disconnect to CSR */
12215 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12216 if( eHAL_STATUS_SUCCESS ==
12217 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12218 pAdapter->sessionId,
12219 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12220 {
12221 ret = wait_for_completion_interruptible_timeout(
12222 &pAdapter->disconnect_comp_var,
12223 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12224 if (0 >= ret)
12225 {
12226 hddLog(LOGE, FL("Failed to receive disconnect event"));
12227 return -EALREADY;
12228 }
12229 }
12230 }
12231 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
12232 {
12233 ret = wait_for_completion_interruptible_timeout(
12234 &pAdapter->disconnect_comp_var,
12235 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12236 if (0 >= ret)
12237 {
12238 hddLog(LOGE, FL("Failed to receive disconnect event"));
12239 return -EALREADY;
12240 }
12241 }
12242
12243 return 0;
12244}
12245
12246/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053012247 * FUNCTION: __wlan_hdd_cfg80211_connect
12248 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070012249 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012250static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012251 struct net_device *ndev,
12252 struct cfg80211_connect_params *req
12253 )
12254{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012255 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012256 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012257 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053012258 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012259
12260 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012261
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012262 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12263 TRACE_CODE_HDD_CFG80211_CONNECT,
12264 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012265 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012266 "%s: device_mode = %s (%d)", __func__,
12267 hdd_device_modetoString(pAdapter->device_mode),
12268 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012269
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012270 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012271 if (!pHddCtx)
12272 {
12273 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12274 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053012275 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012276 }
12277
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012278 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012279 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012280 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012281 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012282 }
12283
Agarwal Ashish51325b52014-06-16 16:50:49 +053012284 if (vos_max_concurrent_connections_reached()) {
12285 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12286 return -ECONNREFUSED;
12287 }
12288
Jeff Johnson295189b2012-06-20 16:38:30 -070012289#ifdef WLAN_BTAMP_FEATURE
12290 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012291 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070012292 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012293 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012294 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012295 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070012296 }
12297#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012298
12299 //If Device Mode is Station Concurrent Sessions Exit BMps
12300 //P2P Mode will be taken care in Open/close adapter
12301 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012302 (vos_concurrent_open_sessions_running())) {
12303 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
12304 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012305 }
12306
12307 /*Try disconnecting if already in connected state*/
12308 status = wlan_hdd_try_disconnect(pAdapter);
12309 if ( 0 > status)
12310 {
12311 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12312 " connection"));
12313 return -EALREADY;
12314 }
12315
Jeff Johnson295189b2012-06-20 16:38:30 -070012316 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012317 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070012318
12319 if ( 0 > status)
12320 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012321 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070012322 __func__);
12323 return status;
12324 }
Mohit Khanna765234a2012-09-11 15:08:35 -070012325 if ( req->channel )
12326 {
12327 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
12328 req->ssid_len, req->bssid,
12329 req->channel->hw_value);
12330 }
12331 else
12332 {
12333 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012334 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070012335 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012336
Sushant Kaushikd7083982015-03-18 14:33:24 +053012337 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012338 {
12339 //ReEnable BMPS if disabled
12340 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
12341 (NULL != pHddCtx))
12342 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012343 if (pHddCtx->hdd_wlan_suspended)
12344 {
12345 hdd_set_pwrparams(pHddCtx);
12346 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012347 //ReEnable Bmps and Imps back
12348 hdd_enable_bmps_imps(pHddCtx);
12349 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053012350 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070012351 return status;
12352 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012353 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012354 EXIT();
12355 return status;
12356}
12357
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012358static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
12359 struct net_device *ndev,
12360 struct cfg80211_connect_params *req)
12361{
12362 int ret;
12363 vos_ssr_protect(__func__);
12364 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
12365 vos_ssr_unprotect(__func__);
12366
12367 return ret;
12368}
Jeff Johnson295189b2012-06-20 16:38:30 -070012369
12370/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012371 * FUNCTION: wlan_hdd_disconnect
12372 * This function is used to issue a disconnect request to SME
12373 */
12374int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
12375{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012376 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012377 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012378 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012379 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012380
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012381 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012382
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012383 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012384 if (0 != status)
12385 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012386 return status;
12387 }
12388
Sushant Kaushikb4834d22015-07-15 15:29:05 +053012389 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
12390 {
12391 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
12392 pAdapter->sessionId);
12393 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012394 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012395
Agarwal Ashish47d18112014-08-04 19:55:07 +053012396 /* Need to apply spin lock before decreasing active sessions
12397 * as there can be chance for double decrement if context switch
12398 * Calls hdd_DisConnectHandler.
12399 */
12400
12401 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012402 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
12403 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012404 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
12405 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053012406 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
12407 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012408
Abhishek Singhf4669da2014-05-26 15:07:49 +053012409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053012410 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
12411
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012412 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012413
Mihir Shete182a0b22014-08-18 16:08:48 +053012414 /*
12415 * stop tx queues before deleting STA/BSS context from the firmware.
12416 * tx has to be disabled because the firmware can get busy dropping
12417 * the tx frames after BSS/STA has been deleted and will not send
12418 * back a response resulting in WDI timeout
12419 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053012420 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053012421 netif_tx_disable(pAdapter->dev);
12422 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012423
Mihir Shete182a0b22014-08-18 16:08:48 +053012424 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012425 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12426 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012427 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
12428 {
12429 hddLog(VOS_TRACE_LEVEL_INFO,
12430 FL("status = %d, already disconnected"),
12431 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012432
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012433 }
12434 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012435 {
12436 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012437 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012438 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012439 result = -EINVAL;
12440 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012441 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012442 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012443 &pAdapter->disconnect_comp_var,
12444 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012445 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012446 {
12447 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012448 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012449 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012450 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012451 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012452 {
12453 hddLog(VOS_TRACE_LEVEL_ERROR,
12454 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012455 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012456 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012457disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012458 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12459 FL("Set HDD connState to eConnectionState_NotConnected"));
12460 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
12461
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012462 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012463 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012464}
12465
12466
12467/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012468 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070012469 * This function is used to issue a disconnect request to SME
12470 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012471static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012472 struct net_device *dev,
12473 u16 reason
12474 )
12475{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012476 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012477 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012478 tCsrRoamProfile *pRoamProfile;
12479 hdd_station_ctx_t *pHddStaCtx;
12480 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012481#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012482 tANI_U8 staIdx;
12483#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012484
Jeff Johnson295189b2012-06-20 16:38:30 -070012485 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012486
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012487 if (!pAdapter) {
12488 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
12489 return -EINVAL;
12490 }
12491
12492 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12493 if (!pHddStaCtx) {
12494 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
12495 return -EINVAL;
12496 }
12497
12498 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12499 status = wlan_hdd_validate_context(pHddCtx);
12500 if (0 != status)
12501 {
12502 return status;
12503 }
12504
12505 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
12506
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012507 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12508 TRACE_CODE_HDD_CFG80211_DISCONNECT,
12509 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012510 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
12511 __func__, hdd_device_modetoString(pAdapter->device_mode),
12512 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012513
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012514 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
12515 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070012516
Jeff Johnson295189b2012-06-20 16:38:30 -070012517 if (NULL != pRoamProfile)
12518 {
12519 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012520 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
12521 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070012522 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012523 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070012524 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012525 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012526 switch(reason)
12527 {
12528 case WLAN_REASON_MIC_FAILURE:
12529 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
12530 break;
12531
12532 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
12533 case WLAN_REASON_DISASSOC_AP_BUSY:
12534 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
12535 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
12536 break;
12537
12538 case WLAN_REASON_PREV_AUTH_NOT_VALID:
12539 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053012540 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070012541 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
12542 break;
12543
Jeff Johnson295189b2012-06-20 16:38:30 -070012544 default:
12545 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
12546 break;
12547 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012548 pScanInfo = &pHddCtx->scan_info;
12549 if (pScanInfo->mScanPending)
12550 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012551 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012552 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012553 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012554 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012555 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012556
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012557#ifdef FEATURE_WLAN_TDLS
12558 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012559 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012560 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012561 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
12562 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012563 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012564 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012565 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012567 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012568 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012569 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012570 status = sme_DeleteTdlsPeerSta(
12571 WLAN_HDD_GET_HAL_CTX(pAdapter),
12572 pAdapter->sessionId,
12573 mac);
12574 if (status != eHAL_STATUS_SUCCESS) {
12575 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
12576 return -EPERM;
12577 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012578 }
12579 }
12580#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012581 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012582 status = wlan_hdd_disconnect(pAdapter, reasonCode);
12583 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070012584 {
12585 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012586 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012587 __func__, (int)status );
12588 return -EINVAL;
12589 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012590 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012591 else
12592 {
12593 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
12594 "called while in %d state", __func__,
12595 pHddStaCtx->conn_info.connState);
12596 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012597 }
12598 else
12599 {
12600 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
12601 }
12602
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012603 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012604 return status;
12605}
12606
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012607static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
12608 struct net_device *dev,
12609 u16 reason
12610 )
12611{
12612 int ret;
12613 vos_ssr_protect(__func__);
12614 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
12615 vos_ssr_unprotect(__func__);
12616
12617 return ret;
12618}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012619
Jeff Johnson295189b2012-06-20 16:38:30 -070012620/*
12621 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012622 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012623 * settings in IBSS mode.
12624 */
12625static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012626 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012627 struct cfg80211_ibss_params *params
12628 )
12629{
12630 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012631 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012632 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12633 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012634
Jeff Johnson295189b2012-06-20 16:38:30 -070012635 ENTER();
12636
12637 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070012638 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070012639
12640 if (params->ie_len && ( NULL != params->ie) )
12641 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012642 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12643 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012644 {
12645 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12646 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12647 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012648 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012649 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012650 tDot11fIEWPA dot11WPAIE;
12651 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012652 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012653
Wilson Yang00256342013-10-10 23:13:38 -070012654 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012655 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12656 params->ie_len, DOT11F_EID_WPA);
12657 if ( NULL != ie )
12658 {
12659 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12660 // Unpack the WPA IE
12661 //Skip past the EID byte and length byte - and four byte WiFi OUI
12662 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
12663 &ie[2+4],
12664 ie[1] - 4,
12665 &dot11WPAIE);
12666 /*Extract the multicast cipher, the encType for unicast
12667 cipher for wpa-none is none*/
12668 encryptionType =
12669 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
12670 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012671 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012672
Jeff Johnson295189b2012-06-20 16:38:30 -070012673 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
12674
12675 if (0 > status)
12676 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012677 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012678 __func__);
12679 return status;
12680 }
12681 }
12682
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012683 pWextState->roamProfile.AuthType.authType[0] =
12684 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012685 eCSR_AUTH_TYPE_OPEN_SYSTEM;
12686
12687 if (params->privacy)
12688 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012689 /* Security enabled IBSS, At this time there is no information available
12690 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070012691 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012692 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070012693 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012694 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070012695 *enable privacy bit in beacons */
12696
12697 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12698 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012699 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
12700 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070012701 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12702 pWextState->roamProfile.EncryptionType.numEntries = 1;
12703 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070012704 return status;
12705}
12706
12707/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012708 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012709 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012710 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012711static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012712 struct net_device *dev,
12713 struct cfg80211_ibss_params *params
12714 )
12715{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012716 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012717 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12718 tCsrRoamProfile *pRoamProfile;
12719 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012720 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12721 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012722 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070012723
12724 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012725
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012726 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12727 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
12728 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012729 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012730 "%s: device_mode = %s (%d)", __func__,
12731 hdd_device_modetoString(pAdapter->device_mode),
12732 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012733
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012734 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012735 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012736 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012737 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012738 }
12739
12740 if (NULL == pWextState)
12741 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012742 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012743 __func__);
12744 return -EIO;
12745 }
12746
Agarwal Ashish51325b52014-06-16 16:50:49 +053012747 if (vos_max_concurrent_connections_reached()) {
12748 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12749 return -ECONNREFUSED;
12750 }
12751
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012752 /*Try disconnecting if already in connected state*/
12753 status = wlan_hdd_try_disconnect(pAdapter);
12754 if ( 0 > status)
12755 {
12756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12757 " IBSS connection"));
12758 return -EALREADY;
12759 }
12760
Jeff Johnson295189b2012-06-20 16:38:30 -070012761 pRoamProfile = &pWextState->roamProfile;
12762
12763 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
12764 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012765 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012766 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012767 return -EINVAL;
12768 }
12769
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012770 /* BSSID is provided by upper layers hence no need to AUTO generate */
12771 if (NULL != params->bssid) {
12772 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12773 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
12774 hddLog (VOS_TRACE_LEVEL_ERROR,
12775 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12776 return -EIO;
12777 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012778 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012779 }
krunal sonie9002db2013-11-25 14:24:17 -080012780 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
12781 {
12782 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12783 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
12784 {
12785 hddLog (VOS_TRACE_LEVEL_ERROR,
12786 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12787 return -EIO;
12788 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012789
12790 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080012791 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012792 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080012793 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012794
Jeff Johnson295189b2012-06-20 16:38:30 -070012795 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070012796 if (NULL !=
12797#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12798 params->chandef.chan)
12799#else
12800 params->channel)
12801#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012802 {
12803 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012804 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12805 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
12806 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12807 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012808
12809 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012810 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070012811 ieee80211_frequency_to_channel(
12812#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12813 params->chandef.chan->center_freq);
12814#else
12815 params->channel->center_freq);
12816#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012817
12818 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12819 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070012820 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012821 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
12822 __func__);
12823 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012824 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012825
12826 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012827 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012828 if (channelNum == validChan[indx])
12829 {
12830 break;
12831 }
12832 }
12833 if (indx >= numChans)
12834 {
12835 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012836 __func__, channelNum);
12837 return -EINVAL;
12838 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012839 /* Set the Operational Channel */
12840 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
12841 channelNum);
12842 pRoamProfile->ChannelInfo.numOfChannels = 1;
12843 pHddStaCtx->conn_info.operationChannel = channelNum;
12844 pRoamProfile->ChannelInfo.ChannelList =
12845 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070012846 }
12847
12848 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012849 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070012850 if (status < 0)
12851 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012852 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070012853 __func__);
12854 return status;
12855 }
12856
12857 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012858 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012859 params->ssid_len, params->bssid,
12860 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012861
12862 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012863 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012864
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012865 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012866 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012867}
12868
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012869static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
12870 struct net_device *dev,
12871 struct cfg80211_ibss_params *params
12872 )
12873{
12874 int ret = 0;
12875
12876 vos_ssr_protect(__func__);
12877 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
12878 vos_ssr_unprotect(__func__);
12879
12880 return ret;
12881}
12882
Jeff Johnson295189b2012-06-20 16:38:30 -070012883/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012884 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012885 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012886 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012887static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012888 struct net_device *dev
12889 )
12890{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012891 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012892 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12893 tCsrRoamProfile *pRoamProfile;
12894 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012895 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012896
12897 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012898
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012899 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12900 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
12901 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012902 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012903 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012904 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012905 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012906 }
12907
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012908 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
12909 hdd_device_modetoString(pAdapter->device_mode),
12910 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012911 if (NULL == pWextState)
12912 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012913 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012914 __func__);
12915 return -EIO;
12916 }
12917
12918 pRoamProfile = &pWextState->roamProfile;
12919
12920 /* Issue disconnect only if interface type is set to IBSS */
12921 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
12922 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012923 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070012924 __func__);
12925 return -EINVAL;
12926 }
12927
12928 /* Issue Disconnect request */
12929 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12930 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12931 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
12932
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012933 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012934 return 0;
12935}
12936
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012937static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
12938 struct net_device *dev
12939 )
12940{
12941 int ret = 0;
12942
12943 vos_ssr_protect(__func__);
12944 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
12945 vos_ssr_unprotect(__func__);
12946
12947 return ret;
12948}
12949
Jeff Johnson295189b2012-06-20 16:38:30 -070012950/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012951 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070012952 * This function is used to set the phy parameters
12953 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
12954 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012955static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012956 u32 changed)
12957{
12958 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
12959 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012960 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012961
12962 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012963
12964 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012965 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
12966 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012967
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012968 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012969 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012970 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012971 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012972 }
12973
Jeff Johnson295189b2012-06-20 16:38:30 -070012974 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
12975 {
12976 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
12977 WNI_CFG_RTS_THRESHOLD_STAMAX :
12978 wiphy->rts_threshold;
12979
12980 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012981 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070012982 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012983 hddLog(VOS_TRACE_LEVEL_ERROR,
12984 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012985 __func__, rts_threshold);
12986 return -EINVAL;
12987 }
12988
12989 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
12990 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012991 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012992 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012993 hddLog(VOS_TRACE_LEVEL_ERROR,
12994 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012995 __func__, rts_threshold);
12996 return -EIO;
12997 }
12998
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012999 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013000 rts_threshold);
13001 }
13002
13003 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
13004 {
13005 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
13006 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
13007 wiphy->frag_threshold;
13008
13009 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013010 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013011 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013012 hddLog(VOS_TRACE_LEVEL_ERROR,
13013 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013014 frag_threshold);
13015 return -EINVAL;
13016 }
13017
13018 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
13019 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013020 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013021 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013022 hddLog(VOS_TRACE_LEVEL_ERROR,
13023 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013024 __func__, frag_threshold);
13025 return -EIO;
13026 }
13027
13028 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
13029 frag_threshold);
13030 }
13031
13032 if ((changed & WIPHY_PARAM_RETRY_SHORT)
13033 || (changed & WIPHY_PARAM_RETRY_LONG))
13034 {
13035 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
13036 wiphy->retry_short :
13037 wiphy->retry_long;
13038
13039 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
13040 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
13041 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013042 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013043 __func__, retry_value);
13044 return -EINVAL;
13045 }
13046
13047 if (changed & WIPHY_PARAM_RETRY_SHORT)
13048 {
13049 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
13050 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013051 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013052 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013053 hddLog(VOS_TRACE_LEVEL_ERROR,
13054 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013055 __func__, retry_value);
13056 return -EIO;
13057 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013058 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013059 __func__, retry_value);
13060 }
13061 else if (changed & WIPHY_PARAM_RETRY_SHORT)
13062 {
13063 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
13064 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013065 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013066 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013067 hddLog(VOS_TRACE_LEVEL_ERROR,
13068 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013069 __func__, retry_value);
13070 return -EIO;
13071 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013072 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013073 __func__, retry_value);
13074 }
13075 }
13076
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013077 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013078 return 0;
13079}
13080
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013081static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
13082 u32 changed)
13083{
13084 int ret;
13085
13086 vos_ssr_protect(__func__);
13087 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
13088 vos_ssr_unprotect(__func__);
13089
13090 return ret;
13091}
13092
Jeff Johnson295189b2012-06-20 16:38:30 -070013093/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013094 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013095 * This function is used to set the txpower
13096 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013097static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013098#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13099 struct wireless_dev *wdev,
13100#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013101#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013102 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013103#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013104 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013105#endif
13106 int dbm)
13107{
13108 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013109 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013110 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13111 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013112 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013113
13114 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013115
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013116 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13117 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
13118 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013119 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013120 if (0 != status)
13121 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013122 return status;
13123 }
13124
13125 hHal = pHddCtx->hHal;
13126
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013127 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
13128 dbm, ccmCfgSetCallback,
13129 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013130 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013131 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013132 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
13133 return -EIO;
13134 }
13135
13136 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
13137 dbm);
13138
13139 switch(type)
13140 {
13141 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
13142 /* Fall through */
13143 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
13144 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
13145 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013146 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
13147 __func__);
13148 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013149 }
13150 break;
13151 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013152 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070013153 __func__);
13154 return -EOPNOTSUPP;
13155 break;
13156 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013157 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
13158 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070013159 return -EIO;
13160 }
13161
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013162 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013163 return 0;
13164}
13165
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013166static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
13167#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13168 struct wireless_dev *wdev,
13169#endif
13170#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13171 enum tx_power_setting type,
13172#else
13173 enum nl80211_tx_power_setting type,
13174#endif
13175 int dbm)
13176{
13177 int ret;
13178 vos_ssr_protect(__func__);
13179 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
13180#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13181 wdev,
13182#endif
13183#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13184 type,
13185#else
13186 type,
13187#endif
13188 dbm);
13189 vos_ssr_unprotect(__func__);
13190
13191 return ret;
13192}
13193
Jeff Johnson295189b2012-06-20 16:38:30 -070013194/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013195 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013196 * This function is used to read the txpower
13197 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013198static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013199#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13200 struct wireless_dev *wdev,
13201#endif
13202 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070013203{
13204
13205 hdd_adapter_t *pAdapter;
13206 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013207 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013208
Jeff Johnsone7245742012-09-05 17:12:55 -070013209 ENTER();
13210
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013211 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013212 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013213 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013214 *dbm = 0;
13215 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013216 }
13217
Jeff Johnson295189b2012-06-20 16:38:30 -070013218 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
13219 if (NULL == pAdapter)
13220 {
13221 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
13222 return -ENOENT;
13223 }
13224
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053013225 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13226 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
13227 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013228 wlan_hdd_get_classAstats(pAdapter);
13229 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
13230
Jeff Johnsone7245742012-09-05 17:12:55 -070013231 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013232 return 0;
13233}
13234
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013235static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
13236#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13237 struct wireless_dev *wdev,
13238#endif
13239 int *dbm)
13240{
13241 int ret;
13242
13243 vos_ssr_protect(__func__);
13244 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
13245#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13246 wdev,
13247#endif
13248 dbm);
13249 vos_ssr_unprotect(__func__);
13250
13251 return ret;
13252}
13253
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013254static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013255#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13256 const u8* mac,
13257#else
13258 u8* mac,
13259#endif
13260 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070013261{
13262 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13263 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13264 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053013265 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013266
13267 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
13268 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070013269
13270 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
13271 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
13272 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
13273 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
13274 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
13275 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
13276 tANI_U16 maxRate = 0;
13277 tANI_U16 myRate;
13278 tANI_U16 currentRate = 0;
13279 tANI_U8 maxSpeedMCS = 0;
13280 tANI_U8 maxMCSIdx = 0;
13281 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053013282 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013283 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013284 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013285
Leo Chang6f8870f2013-03-26 18:11:36 -070013286#ifdef WLAN_FEATURE_11AC
13287 tANI_U32 vht_mcs_map;
13288 eDataRate11ACMaxMcs vhtMaxMcs;
13289#endif /* WLAN_FEATURE_11AC */
13290
Jeff Johnsone7245742012-09-05 17:12:55 -070013291 ENTER();
13292
Jeff Johnson295189b2012-06-20 16:38:30 -070013293 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
13294 (0 == ssidlen))
13295 {
13296 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
13297 " Invalid ssidlen, %d", __func__, ssidlen);
13298 /*To keep GUI happy*/
13299 return 0;
13300 }
13301
Mukul Sharma811205f2014-07-09 21:07:30 +053013302 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
13303 {
13304 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13305 "%s: Roaming in progress, so unable to proceed this request", __func__);
13306 return 0;
13307 }
13308
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013309 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013310 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013311 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013312 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013313 }
13314
Jeff Johnson295189b2012-06-20 16:38:30 -070013315
Kiet Lam3b17fc82013-09-27 05:24:08 +053013316 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
13317 sinfo->filled |= STATION_INFO_SIGNAL;
13318
c_hpothu09f19542014-05-30 21:53:31 +053013319 wlan_hdd_get_station_stats(pAdapter);
13320 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
13321
13322 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053013323 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
13324 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053013325 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053013326 {
13327 rate_flags = pAdapter->maxRateFlags;
13328 }
c_hpothu44ff4e02014-05-08 00:13:57 +053013329
Jeff Johnson295189b2012-06-20 16:38:30 -070013330 //convert to the UI units of 100kbps
13331 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
13332
13333#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070013334 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 -070013335 sinfo->signal,
13336 pCfg->reportMaxLinkSpeed,
13337 myRate,
13338 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013339 (int) pCfg->linkSpeedRssiMid,
13340 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070013341 (int) rate_flags,
13342 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013343#endif //LINKSPEED_DEBUG_ENABLED
13344
13345 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
13346 {
13347 // we do not want to necessarily report the current speed
13348 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
13349 {
13350 // report the max possible speed
13351 rssidx = 0;
13352 }
13353 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
13354 {
13355 // report the max possible speed with RSSI scaling
13356 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
13357 {
13358 // report the max possible speed
13359 rssidx = 0;
13360 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013361 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070013362 {
13363 // report middle speed
13364 rssidx = 1;
13365 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013366 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
13367 {
13368 // report middle speed
13369 rssidx = 2;
13370 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013371 else
13372 {
13373 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013374 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070013375 }
13376 }
13377 else
13378 {
13379 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
13380 hddLog(VOS_TRACE_LEVEL_ERROR,
13381 "%s: Invalid value for reportMaxLinkSpeed: %u",
13382 __func__, pCfg->reportMaxLinkSpeed);
13383 rssidx = 0;
13384 }
13385
13386 maxRate = 0;
13387
13388 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013389 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
13390 OperationalRates, &ORLeng))
13391 {
13392 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13393 /*To keep GUI happy*/
13394 return 0;
13395 }
13396
Jeff Johnson295189b2012-06-20 16:38:30 -070013397 for (i = 0; i < ORLeng; i++)
13398 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013399 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013400 {
13401 /* Validate Rate Set */
13402 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
13403 {
13404 currentRate = supported_data_rate[j].supported_rate[rssidx];
13405 break;
13406 }
13407 }
13408 /* Update MAX rate */
13409 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13410 }
13411
13412 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013413 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
13414 ExtendedRates, &ERLeng))
13415 {
13416 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13417 /*To keep GUI happy*/
13418 return 0;
13419 }
13420
Jeff Johnson295189b2012-06-20 16:38:30 -070013421 for (i = 0; i < ERLeng; i++)
13422 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013423 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013424 {
13425 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
13426 {
13427 currentRate = supported_data_rate[j].supported_rate[rssidx];
13428 break;
13429 }
13430 }
13431 /* Update MAX rate */
13432 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13433 }
c_hpothu79aab322014-07-14 21:11:01 +053013434
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013435 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053013436 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013437 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053013438 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070013439 {
c_hpothu79aab322014-07-14 21:11:01 +053013440 if (rate_flags & eHAL_TX_RATE_VHT80)
13441 mode = 2;
13442 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
13443 mode = 1;
13444 else
13445 mode = 0;
13446
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013447 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
13448 MCSRates, &MCSLeng))
13449 {
13450 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13451 /*To keep GUI happy*/
13452 return 0;
13453 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013454 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070013455#ifdef WLAN_FEATURE_11AC
13456 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013457 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070013458 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013459 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013460 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070013461 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070013462 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013463 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013464 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013465 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070013466 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013467 maxMCSIdx = 7;
13468 }
13469 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
13470 {
13471 maxMCSIdx = 8;
13472 }
13473 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
13474 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013475 //VHT20 is supporting 0~8
13476 if (rate_flags & eHAL_TX_RATE_VHT20)
13477 maxMCSIdx = 8;
13478 else
13479 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070013480 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013481
c_hpothu79aab322014-07-14 21:11:01 +053013482 if (0 != rssidx)/*check for scaled */
13483 {
13484 //get middle rate MCS index if rssi=1/2
13485 for (i=0; i <= maxMCSIdx; i++)
13486 {
13487 if (sinfo->signal <= rssiMcsTbl[mode][i])
13488 {
13489 maxMCSIdx = i;
13490 break;
13491 }
13492 }
13493 }
13494
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013495 if (rate_flags & eHAL_TX_RATE_VHT80)
13496 {
13497 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
13498 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
13499 }
13500 else if (rate_flags & eHAL_TX_RATE_VHT40)
13501 {
13502 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
13503 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
13504 }
13505 else if (rate_flags & eHAL_TX_RATE_VHT20)
13506 {
13507 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
13508 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
13509 }
13510
Leo Chang6f8870f2013-03-26 18:11:36 -070013511 maxSpeedMCS = 1;
13512 if (currentRate > maxRate)
13513 {
13514 maxRate = currentRate;
13515 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013516
Leo Chang6f8870f2013-03-26 18:11:36 -070013517 }
13518 else
13519#endif /* WLAN_FEATURE_11AC */
13520 {
13521 if (rate_flags & eHAL_TX_RATE_HT40)
13522 {
13523 rateFlag |= 1;
13524 }
13525 if (rate_flags & eHAL_TX_RATE_SGI)
13526 {
13527 rateFlag |= 2;
13528 }
13529
Girish Gowli01abcee2014-07-31 20:18:55 +053013530 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053013531 if (rssidx == 1 || rssidx == 2)
13532 {
13533 //get middle rate MCS index if rssi=1/2
13534 for (i=0; i <= 7; i++)
13535 {
13536 if (sinfo->signal <= rssiMcsTbl[mode][i])
13537 {
13538 temp = i+1;
13539 break;
13540 }
13541 }
13542 }
c_hpothu79aab322014-07-14 21:11:01 +053013543
13544 for (i = 0; i < MCSLeng; i++)
13545 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013546 for (j = 0; j < temp; j++)
13547 {
13548 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
13549 {
13550 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053013551 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013552 break;
13553 }
13554 }
13555 if ((j < temp) && (currentRate > maxRate))
13556 {
13557 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070013558 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013559 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053013560 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013561 }
13562 }
13563
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013564 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
13565 {
13566 maxRate = myRate;
13567 maxSpeedMCS = 1;
13568 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13569 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013570 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053013571 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070013572 {
13573 maxRate = myRate;
13574 if (rate_flags & eHAL_TX_RATE_LEGACY)
13575 {
13576 maxSpeedMCS = 0;
13577 }
13578 else
13579 {
13580 maxSpeedMCS = 1;
13581 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13582 }
13583 }
13584
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013585 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070013586 {
13587 sinfo->txrate.legacy = maxRate;
13588#ifdef LINKSPEED_DEBUG_ENABLED
13589 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
13590#endif //LINKSPEED_DEBUG_ENABLED
13591 }
13592 else
13593 {
13594 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070013595#ifdef WLAN_FEATURE_11AC
13596 sinfo->txrate.nss = 1;
13597 if (rate_flags & eHAL_TX_RATE_VHT80)
13598 {
13599 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013600 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070013601 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013602 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070013603 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013604 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13605 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13606 }
13607 else if (rate_flags & eHAL_TX_RATE_VHT20)
13608 {
13609 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13610 }
13611#endif /* WLAN_FEATURE_11AC */
13612 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
13613 {
13614 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13615 if (rate_flags & eHAL_TX_RATE_HT40)
13616 {
13617 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13618 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013619 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013620 if (rate_flags & eHAL_TX_RATE_SGI)
13621 {
13622 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13623 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013624
Jeff Johnson295189b2012-06-20 16:38:30 -070013625#ifdef LINKSPEED_DEBUG_ENABLED
13626 pr_info("Reporting MCS rate %d flags %x\n",
13627 sinfo->txrate.mcs,
13628 sinfo->txrate.flags );
13629#endif //LINKSPEED_DEBUG_ENABLED
13630 }
13631 }
13632 else
13633 {
13634 // report current rate instead of max rate
13635
13636 if (rate_flags & eHAL_TX_RATE_LEGACY)
13637 {
13638 //provide to the UI in units of 100kbps
13639 sinfo->txrate.legacy = myRate;
13640#ifdef LINKSPEED_DEBUG_ENABLED
13641 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
13642#endif //LINKSPEED_DEBUG_ENABLED
13643 }
13644 else
13645 {
13646 //must be MCS
13647 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013648#ifdef WLAN_FEATURE_11AC
13649 sinfo->txrate.nss = 1;
13650 if (rate_flags & eHAL_TX_RATE_VHT80)
13651 {
13652 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13653 }
13654 else
13655#endif /* WLAN_FEATURE_11AC */
13656 {
13657 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13658 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013659 if (rate_flags & eHAL_TX_RATE_SGI)
13660 {
13661 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13662 }
13663 if (rate_flags & eHAL_TX_RATE_HT40)
13664 {
13665 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13666 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013667#ifdef WLAN_FEATURE_11AC
13668 else if (rate_flags & eHAL_TX_RATE_VHT80)
13669 {
13670 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
13671 }
13672#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070013673#ifdef LINKSPEED_DEBUG_ENABLED
13674 pr_info("Reporting actual MCS rate %d flags %x\n",
13675 sinfo->txrate.mcs,
13676 sinfo->txrate.flags );
13677#endif //LINKSPEED_DEBUG_ENABLED
13678 }
13679 }
13680 sinfo->filled |= STATION_INFO_TX_BITRATE;
13681
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013682 sinfo->tx_packets =
13683 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
13684 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
13685 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
13686 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
13687
13688 sinfo->tx_retries =
13689 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
13690 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
13691 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
13692 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
13693
13694 sinfo->tx_failed =
13695 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
13696 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
13697 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
13698 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
13699
13700 sinfo->filled |=
13701 STATION_INFO_TX_PACKETS |
13702 STATION_INFO_TX_RETRIES |
13703 STATION_INFO_TX_FAILED;
13704
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013705 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13706 TRACE_CODE_HDD_CFG80211_GET_STA,
13707 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013708 EXIT();
13709 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013710}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013711#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13712static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13713 const u8* mac, struct station_info *sinfo)
13714#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013715static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13716 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013717#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013718{
13719 int ret;
13720
13721 vos_ssr_protect(__func__);
13722 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
13723 vos_ssr_unprotect(__func__);
13724
13725 return ret;
13726}
13727
13728static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070013729 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070013730{
13731 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013732 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013733 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013734 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013735
Jeff Johnsone7245742012-09-05 17:12:55 -070013736 ENTER();
13737
Jeff Johnson295189b2012-06-20 16:38:30 -070013738 if (NULL == pAdapter)
13739 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013740 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013741 return -ENODEV;
13742 }
13743
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013744 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13745 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
13746 pAdapter->sessionId, timeout));
13747
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013748 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013749 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013750 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013751 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013752 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013753 }
13754
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013755 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
13756 (TRUE == pHddCtx->hdd_wlan_suspended) &&
13757 (pHddCtx->cfg_ini->fhostArpOffload) &&
13758 (eConnectionState_Associated ==
13759 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13760 {
Amar Singhald53568e2013-09-26 11:03:45 -070013761
13762 hddLog(VOS_TRACE_LEVEL_INFO,
13763 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053013764 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013765 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13766 {
13767 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013768 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013769 __func__, vos_status);
13770 }
13771 }
13772
Jeff Johnson295189b2012-06-20 16:38:30 -070013773 /**The get power cmd from the supplicant gets updated by the nl only
13774 *on successful execution of the function call
13775 *we are oppositely mapped w.r.t mode in the driver
13776 **/
13777 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
13778
13779 if (VOS_STATUS_E_FAILURE == vos_status)
13780 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13782 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013783 return -EINVAL;
13784 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013785 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013786 return 0;
13787}
13788
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013789static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
13790 struct net_device *dev, bool mode, int timeout)
13791{
13792 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013793
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013794 vos_ssr_protect(__func__);
13795 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
13796 vos_ssr_unprotect(__func__);
13797
13798 return ret;
13799}
Jeff Johnson295189b2012-06-20 16:38:30 -070013800#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013801static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
13802 struct net_device *netdev,
13803 u8 key_index)
13804{
13805 ENTER();
13806 return 0;
13807}
13808
Jeff Johnson295189b2012-06-20 16:38:30 -070013809static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013810 struct net_device *netdev,
13811 u8 key_index)
13812{
13813 int ret;
13814 vos_ssr_protect(__func__);
13815 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
13816 vos_ssr_unprotect(__func__);
13817 return ret;
13818}
13819#endif //LINUX_VERSION_CODE
13820
13821#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13822static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13823 struct net_device *dev,
13824 struct ieee80211_txq_params *params)
13825{
13826 ENTER();
13827 return 0;
13828}
13829#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13830static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13831 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013832{
Jeff Johnsone7245742012-09-05 17:12:55 -070013833 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013834 return 0;
13835}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013836#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070013837
13838#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13839static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013840 struct net_device *dev,
13841 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013842{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013843 int ret;
13844
13845 vos_ssr_protect(__func__);
13846 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
13847 vos_ssr_unprotect(__func__);
13848 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013849}
13850#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13851static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
13852 struct ieee80211_txq_params *params)
13853{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013854 int ret;
13855
13856 vos_ssr_protect(__func__);
13857 ret = __wlan_hdd_set_txq_params(wiphy, params);
13858 vos_ssr_unprotect(__func__);
13859 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013860}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013861#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013862
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013863static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013864 struct net_device *dev,
13865 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070013866{
13867 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013868 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013869 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013870 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013871 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013872 v_CONTEXT_t pVosContext = NULL;
13873 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013874
Jeff Johnsone7245742012-09-05 17:12:55 -070013875 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013876
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013877 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070013878 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013879 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013880 return -EINVAL;
13881 }
13882
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013883 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13884 TRACE_CODE_HDD_CFG80211_DEL_STA,
13885 pAdapter->sessionId, pAdapter->device_mode));
13886
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013887 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13888 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013889 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013890 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013891 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013892 }
13893
Jeff Johnson295189b2012-06-20 16:38:30 -070013894 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013895 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013896 )
13897 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013898 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13899 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13900 if(pSapCtx == NULL){
13901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13902 FL("psapCtx is NULL"));
13903 return -ENOENT;
13904 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013905 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013906 {
13907 v_U16_t i;
13908 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13909 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013910 if ((pSapCtx->aStaInfo[i].isUsed) &&
13911 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070013912 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013913 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013914 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013915 ETHER_ADDR_LEN);
13916
Jeff Johnson295189b2012-06-20 16:38:30 -070013917 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013918 "%s: Delete STA with MAC::"
13919 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013920 __func__,
13921 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
13922 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013923 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013924 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013925 }
13926 }
13927 }
13928 else
13929 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013930
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013931 vos_status = hdd_softap_GetStaId(pAdapter,
13932 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013933 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13934 {
13935 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013936 "%s: Skip this DEL STA as this is not used::"
13937 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013938 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013939 return -ENOENT;
13940 }
13941
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013942 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013943 {
13944 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013945 "%s: Skip this DEL STA as deauth is in progress::"
13946 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013947 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013948 return -ENOENT;
13949 }
13950
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013951 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013952
Jeff Johnson295189b2012-06-20 16:38:30 -070013953 hddLog(VOS_TRACE_LEVEL_INFO,
13954 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013955 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013956 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013957 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013958
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013959 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013960 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13961 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013962 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013963 hddLog(VOS_TRACE_LEVEL_INFO,
13964 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013965 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013966 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013967 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013968 return -ENOENT;
13969 }
13970
Jeff Johnson295189b2012-06-20 16:38:30 -070013971 }
13972 }
13973
13974 EXIT();
13975
13976 return 0;
13977}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013978
13979#ifdef CFG80211_DEL_STA_V2
13980static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13981 struct net_device *dev,
13982 struct station_del_parameters *param)
13983#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013984#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13985static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13986 struct net_device *dev, const u8 *mac)
13987#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013988static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13989 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013990#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013991#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013992{
13993 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013994 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070013995
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013996 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013997
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013998#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013999 if (NULL == param) {
14000 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014001 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014002 return -EINVAL;
14003 }
14004
14005 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
14006 param->subtype, &delStaParams);
14007
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014008#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014009 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014010 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014011#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014012 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
14013
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014014 vos_ssr_unprotect(__func__);
14015
14016 return ret;
14017}
14018
14019static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014020 struct net_device *dev,
14021#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14022 const u8 *mac,
14023#else
14024 u8 *mac,
14025#endif
14026 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014027{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014028 hdd_adapter_t *pAdapter;
14029 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014030 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014031#ifdef FEATURE_WLAN_TDLS
14032 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014033
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014034 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014035
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014036 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14037 if (NULL == pAdapter)
14038 {
14039 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14040 "%s: Adapter is NULL",__func__);
14041 return -EINVAL;
14042 }
14043 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14044 status = wlan_hdd_validate_context(pHddCtx);
14045 if (0 != status)
14046 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014047 return status;
14048 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014049
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014050 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14051 TRACE_CODE_HDD_CFG80211_ADD_STA,
14052 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014053 mask = params->sta_flags_mask;
14054
14055 set = params->sta_flags_set;
14056
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014058 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
14059 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014060
14061 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
14062 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014063 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014064 }
14065 }
14066#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014067 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014068 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014069}
14070
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014071#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14072static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14073 struct net_device *dev, const u8 *mac,
14074 struct station_parameters *params)
14075#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014076static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14077 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014078#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014079{
14080 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014081
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014082 vos_ssr_protect(__func__);
14083 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
14084 vos_ssr_unprotect(__func__);
14085
14086 return ret;
14087}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014088#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070014089
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014090static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070014091 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014092{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014093 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14094 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014095 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014096 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014097 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014098 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070014099
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014100 ENTER();
14101
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014102 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014103 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014104 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014105 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014106 return -EINVAL;
14107 }
14108
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014109 if (!pmksa) {
14110 hddLog(LOGE, FL("pmksa is NULL"));
14111 return -EINVAL;
14112 }
14113
14114 if (!pmksa->bssid || !pmksa->pmkid) {
14115 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
14116 pmksa->bssid, pmksa->pmkid);
14117 return -EINVAL;
14118 }
14119
14120 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
14121 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14122
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014123 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14124 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014125 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014126 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014127 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014128 }
14129
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014130 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014131 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14132
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014133 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
14134 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014135
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014136 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014137 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014138 &pmk_id, 1, FALSE);
14139
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014140 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14141 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
14142 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014143
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014144 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014145 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014146}
14147
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014148static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
14149 struct cfg80211_pmksa *pmksa)
14150{
14151 int ret;
14152
14153 vos_ssr_protect(__func__);
14154 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
14155 vos_ssr_unprotect(__func__);
14156
14157 return ret;
14158}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014159
Wilson Yang6507c4e2013-10-01 20:11:19 -070014160
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014161static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070014162 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014163{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014164 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14165 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014166 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014167 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014168
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014169 ENTER();
14170
Wilson Yang6507c4e2013-10-01 20:11:19 -070014171 /* Validate pAdapter */
14172 if (NULL == pAdapter)
14173 {
14174 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
14175 return -EINVAL;
14176 }
14177
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014178 if (!pmksa) {
14179 hddLog(LOGE, FL("pmksa is NULL"));
14180 return -EINVAL;
14181 }
14182
14183 if (!pmksa->bssid) {
14184 hddLog(LOGE, FL("pmksa->bssid is NULL"));
14185 return -EINVAL;
14186 }
14187
Kiet Lam98c46a12014-10-31 15:34:57 -070014188 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
14189 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14190
Wilson Yang6507c4e2013-10-01 20:11:19 -070014191 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14192 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014193 if (0 != status)
14194 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014195 return status;
14196 }
14197
14198 /*Retrieve halHandle*/
14199 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14200
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014201 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14202 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
14203 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014204 /* Delete the PMKID CSR cache */
14205 if (eHAL_STATUS_SUCCESS !=
14206 sme_RoamDelPMKIDfromCache(halHandle,
14207 pAdapter->sessionId, pmksa->bssid, FALSE)) {
14208 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
14209 MAC_ADDR_ARRAY(pmksa->bssid));
14210 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014211 }
14212
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014213 EXIT();
14214 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014215}
14216
Wilson Yang6507c4e2013-10-01 20:11:19 -070014217
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014218static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
14219 struct cfg80211_pmksa *pmksa)
14220{
14221 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014222
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014223 vos_ssr_protect(__func__);
14224 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
14225 vos_ssr_unprotect(__func__);
14226
14227 return ret;
14228
14229}
14230
14231static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014232{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014233 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14234 tHalHandle halHandle;
14235 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014236 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014237
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014238 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070014239
14240 /* Validate pAdapter */
14241 if (NULL == pAdapter)
14242 {
14243 hddLog(VOS_TRACE_LEVEL_ERROR,
14244 "%s: Invalid Adapter" ,__func__);
14245 return -EINVAL;
14246 }
14247
14248 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14249 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014250 if (0 != status)
14251 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014252 return status;
14253 }
14254
14255 /*Retrieve halHandle*/
14256 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14257
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014258 /* Flush the PMKID cache in CSR */
14259 if (eHAL_STATUS_SUCCESS !=
14260 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
14261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
14262 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014263 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014264 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080014265 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014266}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014267
14268static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
14269{
14270 int ret;
14271
14272 vos_ssr_protect(__func__);
14273 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
14274 vos_ssr_unprotect(__func__);
14275
14276 return ret;
14277}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014278#endif
14279
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014280#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014281static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14282 struct net_device *dev,
14283 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014284{
14285 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14286 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014287 hdd_context_t *pHddCtx;
14288 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014289
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014290 ENTER();
14291
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014292 if (NULL == pAdapter)
14293 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014294 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014295 return -ENODEV;
14296 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014297 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14298 ret = wlan_hdd_validate_context(pHddCtx);
14299 if (0 != ret)
14300 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014301 return ret;
14302 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014303 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014304 if (NULL == pHddStaCtx)
14305 {
14306 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
14307 return -EINVAL;
14308 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014309
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014310 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14311 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
14312 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014313 // Added for debug on reception of Re-assoc Req.
14314 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
14315 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014316 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014317 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080014318 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014319 }
14320
14321#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080014322 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014323 ftie->ie_len);
14324#endif
14325
14326 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014327 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
14328 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014329 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014330
14331 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014332 return 0;
14333}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014334
14335static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14336 struct net_device *dev,
14337 struct cfg80211_update_ft_ies_params *ftie)
14338{
14339 int ret;
14340
14341 vos_ssr_protect(__func__);
14342 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
14343 vos_ssr_unprotect(__func__);
14344
14345 return ret;
14346}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014347#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014348
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014349#ifdef FEATURE_WLAN_SCAN_PNO
14350
14351void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
14352 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
14353{
14354 int ret;
14355 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
14356 hdd_context_t *pHddCtx;
14357
Nirav Shah80830bf2013-12-31 16:35:12 +053014358 ENTER();
14359
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014360 if (NULL == pAdapter)
14361 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014363 "%s: HDD adapter is Null", __func__);
14364 return ;
14365 }
14366
14367 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14368 if (NULL == pHddCtx)
14369 {
14370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14371 "%s: HDD context is Null!!!", __func__);
14372 return ;
14373 }
14374
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014375 spin_lock(&pHddCtx->schedScan_lock);
14376 if (TRUE == pHddCtx->isWiphySuspended)
14377 {
14378 pHddCtx->isSchedScanUpdatePending = TRUE;
14379 spin_unlock(&pHddCtx->schedScan_lock);
14380 hddLog(VOS_TRACE_LEVEL_INFO,
14381 "%s: Update cfg80211 scan database after it resume", __func__);
14382 return ;
14383 }
14384 spin_unlock(&pHddCtx->schedScan_lock);
14385
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014386 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
14387
14388 if (0 > ret)
14389 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
14390
14391 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14393 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014394}
14395
14396/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014397 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014398 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014399 */
14400static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
14401{
14402 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14403 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014404 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014405 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14406 int status = 0;
14407 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
14408
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014409 /* The current firmware design does not allow PNO during any
14410 * active sessions. Hence, determine the active sessions
14411 * and return a failure.
14412 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014413 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
14414 {
14415 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014416 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014417
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014418 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
14419 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
14420 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
14421 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
14422 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053014423 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014424 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014425 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014426 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014427 }
14428 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14429 pAdapterNode = pNext;
14430 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014431 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014432}
14433
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014434void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
14435{
14436 hdd_adapter_t *pAdapter = callbackContext;
14437 hdd_context_t *pHddCtx;
14438
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014439 ENTER();
14440
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014441 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
14442 {
14443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14444 FL("Invalid adapter or adapter has invalid magic"));
14445 return;
14446 }
14447
14448 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14449 if (0 != wlan_hdd_validate_context(pHddCtx))
14450 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014451 return;
14452 }
14453
c_hpothub53c45d2014-08-18 16:53:14 +053014454 if (VOS_STATUS_SUCCESS != status)
14455 {
14456 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014457 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053014458 pHddCtx->isPnoEnable = FALSE;
14459 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014460
14461 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
14462 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014463 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014464}
14465
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014466/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014467 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
14468 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014469 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014470static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014471 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14472{
14473 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014474 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014475 hdd_context_t *pHddCtx;
14476 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014477 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053014478 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
14479 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014480 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14481 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014482 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014483 hdd_config_t *pConfig = NULL;
14484 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014485
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014486 ENTER();
14487
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014488 if (NULL == pAdapter)
14489 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014491 "%s: HDD adapter is Null", __func__);
14492 return -ENODEV;
14493 }
14494
14495 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014496 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014497
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014498 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014499 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014500 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014501 }
14502
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014503 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014504 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14505 if (NULL == hHal)
14506 {
14507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14508 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014509 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014510 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014511 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14512 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
14513 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053014514 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014515 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053014516 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014517 {
14518 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14519 "%s: aborting the existing scan is unsuccessfull", __func__);
14520 return -EBUSY;
14521 }
14522
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014523 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014524 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014526 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014527 return -EBUSY;
14528 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014529
c_hpothu37f21312014-04-09 21:49:54 +053014530 if (TRUE == pHddCtx->isPnoEnable)
14531 {
14532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14533 FL("already PNO is enabled"));
14534 return -EBUSY;
14535 }
c_hpothu225aa7c2014-10-22 17:45:13 +053014536
14537 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
14538 {
14539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14540 "%s: abort ROC failed ", __func__);
14541 return -EBUSY;
14542 }
14543
c_hpothu37f21312014-04-09 21:49:54 +053014544 pHddCtx->isPnoEnable = TRUE;
14545
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014546 pnoRequest.enable = 1; /*Enable PNO */
14547 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014548
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014549 if (( !pnoRequest.ucNetworksCount ) ||
14550 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014551 {
14552 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014553 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014554 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014555 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014556 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014557 goto error;
14558 }
14559
14560 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
14561 {
14562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014563 "%s: Incorrect number of channels %d",
14564 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014565 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014566 goto error;
14567 }
14568
14569 /* Framework provides one set of channels(all)
14570 * common for all saved profile */
14571 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14572 channels_allowed, &num_channels_allowed))
14573 {
14574 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14575 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014576 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014577 goto error;
14578 }
14579 /* Checking each channel against allowed channel list */
14580 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053014581 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014582 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014583 char chList [(request->n_channels*5)+1];
14584 int len;
14585 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014586 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014587 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014588 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014589 if (request->channels[i]->hw_value == channels_allowed[indx])
14590 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014591 if ((!pConfig->enableDFSPnoChnlScan) &&
14592 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
14593 {
14594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14595 "%s : Dropping DFS channel : %d",
14596 __func__,channels_allowed[indx]);
14597 num_ignore_dfs_ch++;
14598 break;
14599 }
14600
Nirav Shah80830bf2013-12-31 16:35:12 +053014601 valid_ch[num_ch++] = request->channels[i]->hw_value;
14602 len += snprintf(chList+len, 5, "%d ",
14603 request->channels[i]->hw_value);
14604 break ;
14605 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014606 }
14607 }
Nirav Shah80830bf2013-12-31 16:35:12 +053014608 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014609
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014610 /*If all channels are DFS and dropped, then ignore the PNO request*/
14611 if (num_ignore_dfs_ch == request->n_channels)
14612 {
14613 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14614 "%s : All requested channels are DFS channels", __func__);
14615 ret = -EINVAL;
14616 goto error;
14617 }
14618 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014619
14620 pnoRequest.aNetworks =
14621 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14622 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014623 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014624 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14625 FL("failed to allocate memory aNetworks %u"),
14626 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14627 goto error;
14628 }
14629 vos_mem_zero(pnoRequest.aNetworks,
14630 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14631
14632 /* Filling per profile params */
14633 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
14634 {
14635 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014636 request->match_sets[i].ssid.ssid_len;
14637
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014638 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
14639 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014640 {
14641 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014642 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014643 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014644 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014645 goto error;
14646 }
14647
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014648 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014649 request->match_sets[i].ssid.ssid,
14650 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14652 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014653 i, pnoRequest.aNetworks[i].ssId.ssId);
14654 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
14655 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
14656 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014657
14658 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014659 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
14660 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014661
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014662 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014663 }
14664
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014665 for (i = 0; i < request->n_ssids; i++)
14666 {
14667 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014668 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014669 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014670 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014671 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014672 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014673 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014674 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014675 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014676 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014677 break;
14678 }
14679 j++;
14680 }
14681 }
14682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14683 "Number of hidden networks being Configured = %d",
14684 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080014686 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014687
14688 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14689 if (pnoRequest.p24GProbeTemplate == NULL)
14690 {
14691 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14692 FL("failed to allocate memory p24GProbeTemplate %u"),
14693 SIR_PNO_MAX_PB_REQ_SIZE);
14694 goto error;
14695 }
14696
14697 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14698 if (pnoRequest.p5GProbeTemplate == NULL)
14699 {
14700 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14701 FL("failed to allocate memory p5GProbeTemplate %u"),
14702 SIR_PNO_MAX_PB_REQ_SIZE);
14703 goto error;
14704 }
14705
14706 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14707 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14708
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053014709 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
14710 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014711 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014712 pnoRequest.us24GProbeTemplateLen = request->ie_len;
14713 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
14714 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014715
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014716 pnoRequest.us5GProbeTemplateLen = request->ie_len;
14717 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
14718 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014719 }
14720
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014721 /* Driver gets only one time interval which is hardcoded in
14722 * supplicant for 10000ms. Taking power consumption into account 6 timers
14723 * will be used, Timervalue is increased exponentially i.e 10,20,40,
14724 * 80,160,320 secs. And number of scan cycle for each timer
14725 * is configurable through INI param gPNOScanTimerRepeatValue.
14726 * If it is set to 0 only one timer will be used and PNO scan cycle
14727 * will be repeated after each interval specified by supplicant
14728 * till PNO is disabled.
14729 */
14730 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014731 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014732 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014733 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014734 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
14735
14736 tempInterval = (request->interval)/1000;
14737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14738 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
14739 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014740 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014741 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014742 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014743 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014744 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014745 tempInterval *= 2;
14746 }
14747 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014748 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014749
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014750 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014751
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014752 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014753 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
14754 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014755 pAdapter->pno_req_status = 0;
14756
Nirav Shah80830bf2013-12-31 16:35:12 +053014757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14758 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014759 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
14760 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053014761
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014762 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014763 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014764 hdd_cfg80211_sched_scan_done_callback, pAdapter);
14765 if (eHAL_STATUS_SUCCESS != status)
14766 {
14767 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014768 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014769 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014770 goto error;
14771 }
14772
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014773 ret = wait_for_completion_timeout(
14774 &pAdapter->pno_comp_var,
14775 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
14776 if (0 >= ret)
14777 {
14778 // Did not receive the response for PNO enable in time.
14779 // Assuming the PNO enable was success.
14780 // Returning error from here, because we timeout, results
14781 // in side effect of Wifi (Wifi Setting) not to work.
14782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14783 FL("Timed out waiting for PNO to be Enabled"));
14784 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014785 }
14786
14787 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053014788 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014789
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014790error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14792 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053014793 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014794 if (pnoRequest.aNetworks)
14795 vos_mem_free(pnoRequest.aNetworks);
14796 if (pnoRequest.p24GProbeTemplate)
14797 vos_mem_free(pnoRequest.p24GProbeTemplate);
14798 if (pnoRequest.p5GProbeTemplate)
14799 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014800
14801 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014802 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014803}
14804
14805/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014806 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
14807 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014808 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014809static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
14810 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14811{
14812 int ret;
14813
14814 vos_ssr_protect(__func__);
14815 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
14816 vos_ssr_unprotect(__func__);
14817
14818 return ret;
14819}
14820
14821/*
14822 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
14823 * Function to disable PNO
14824 */
14825static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014826 struct net_device *dev)
14827{
14828 eHalStatus status = eHAL_STATUS_FAILURE;
14829 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14830 hdd_context_t *pHddCtx;
14831 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014832 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014833 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014834
14835 ENTER();
14836
14837 if (NULL == pAdapter)
14838 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014839 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014840 "%s: HDD adapter is Null", __func__);
14841 return -ENODEV;
14842 }
14843
14844 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014845
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014846 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014847 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014849 "%s: HDD context is Null", __func__);
14850 return -ENODEV;
14851 }
14852
14853 /* The return 0 is intentional when isLogpInProgress and
14854 * isLoadUnloadInProgress. We did observe a crash due to a return of
14855 * failure in sched_scan_stop , especially for a case where the unload
14856 * of the happens at the same time. The function __cfg80211_stop_sched_scan
14857 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
14858 * success. If it returns a failure , then its next invocation due to the
14859 * clean up of the second interface will have the dev pointer corresponding
14860 * to the first one leading to a crash.
14861 */
14862 if (pHddCtx->isLogpInProgress)
14863 {
14864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14865 "%s: LOGP in Progress. Ignore!!!", __func__);
14866 return ret;
14867 }
14868
Mihir Shete18156292014-03-11 15:38:30 +053014869 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014870 {
14871 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14872 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14873 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014874 }
14875
14876 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14877 if (NULL == hHal)
14878 {
14879 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14880 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014881 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014882 }
14883
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014884 pnoRequest.enable = 0; /* Disable PNO */
14885 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014886
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014887 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14888 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
14889 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014890 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014891 pAdapter->sessionId,
14892 NULL, pAdapter);
14893 if (eHAL_STATUS_SUCCESS != status)
14894 {
14895 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14896 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014897 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014898 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014899 }
c_hpothu37f21312014-04-09 21:49:54 +053014900 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014901
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014902error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014904 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014905
14906 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014907 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014908}
14909
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014910/*
14911 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
14912 * NL interface to disable PNO
14913 */
14914static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
14915 struct net_device *dev)
14916{
14917 int ret;
14918
14919 vos_ssr_protect(__func__);
14920 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
14921 vos_ssr_unprotect(__func__);
14922
14923 return ret;
14924}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014925#endif /*FEATURE_WLAN_SCAN_PNO*/
14926
14927
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014928#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014929#if TDLS_MGMT_VERSION2
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014930static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014931 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014932 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
14933#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014934static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014935 u8 *peer, u8 action_code, u8 dialog_token,
14936 u16 status_code, const u8 *buf, size_t len)
14937#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014938{
14939
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014940 hdd_adapter_t *pAdapter;
14941 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014942 u8 peerMac[6];
14943 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070014944 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080014945 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070014946 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014947 int ret;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014948#if !(TDLS_MGMT_VERSION2)
14949 u32 peer_capability = 0;
14950#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014951 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014952
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014953 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14954 if (NULL == pAdapter)
14955 {
14956 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14957 "%s: Adapter is NULL",__func__);
14958 return -EINVAL;
14959 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014960 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14961 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
14962 pAdapter->sessionId, action_code));
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014963 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014964 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014965 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014966 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014967 "Invalid arguments");
14968 return -EINVAL;
14969 }
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014970 if (pHddCtx->isLogpInProgress)
14971 {
14972 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14973 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053014974 wlan_hdd_tdls_set_link_status(pAdapter,
14975 peer,
14976 eTDLS_LINK_IDLE,
14977 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014978 return -EBUSY;
14979 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014980 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
14981 {
14982 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14983 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14984 return -EAGAIN;
14985 }
Hoonki Lee27511902013-03-14 18:19:06 -070014986 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014987 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014988 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070014989 "%s: TDLS mode is disabled OR not enabled in FW."
14990 MAC_ADDRESS_STR " action %d declined.",
14991 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014992 return -ENOTSUPP;
14993 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014994
Hoonki Lee27511902013-03-14 18:19:06 -070014995 /* other than teardown frame, other mgmt frames are not sent if disabled */
14996 if (SIR_MAC_TDLS_TEARDOWN != action_code)
14997 {
14998 /* if tdls_mode is disabled to respond to peer's request */
14999 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
15000 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015001 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015002 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015003 " TDLS mode is disabled. action %d declined.",
15004 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070015005
15006 return -ENOTSUPP;
15007 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053015008
15009 if (vos_max_concurrent_connections_reached())
15010 {
15011 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15012 return -EINVAL;
15013 }
Hoonki Lee27511902013-03-14 18:19:06 -070015014 }
15015
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015016 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
15017 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053015018 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015019 {
15020 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015021 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015022 " TDLS setup is ongoing. action %d declined.",
15023 __func__, MAC_ADDR_ARRAY(peer), action_code);
15024 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015025 }
15026 }
15027
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015028 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
15029 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080015030 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015031 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15032 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015033 {
15034 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
15035 we return error code at 'add_station()'. Hence we have this
15036 check again in addtion to add_station().
15037 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015038 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015039 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015040 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15041 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015042 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
15043 __func__, MAC_ADDR_ARRAY(peer), action_code,
15044 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053015045 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080015046 }
15047 else
15048 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015049 /* maximum reached. tweak to send error code to peer and return
15050 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015051 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15053 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015054 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
15055 __func__, MAC_ADDR_ARRAY(peer), status_code,
15056 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070015057 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015058 /* fall through to send setup resp with failure status
15059 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015060 }
15061 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015062 else
15063 {
15064 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053015065 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015066 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015067 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015068 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015069 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
15070 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015071 return -EPERM;
15072 }
15073 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015074 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015075 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015076
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015077 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015078 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015079 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
15080 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015081
Hoonki Leea34dd892013-02-05 22:56:02 -080015082 /*Except teardown responder will not be used so just make 0*/
15083 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015084 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080015085 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015086
15087 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053015088 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015089
15090 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
15091 responder = pTdlsPeer->is_responder;
15092 else
Hoonki Leea34dd892013-02-05 22:56:02 -080015093 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015095 "%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 -070015096 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
15097 dialog_token, status_code, len);
15098 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080015099 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015100 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015101
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015102 /* For explicit trigger of DIS_REQ come out of BMPS for
15103 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070015104 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015105 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
15106 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070015107 {
15108 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
15109 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015110 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015111 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015112 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
15113 if (status != VOS_STATUS_SUCCESS) {
15114 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
15115 }
Hoonki Lee14621352013-04-16 17:51:19 -070015116 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015117 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
15118 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED)) {
15119 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
15120 }
15121 }
Hoonki Lee14621352013-04-16 17:51:19 -070015122 }
15123
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015124 /* make sure doesn't call send_mgmt() while it is pending */
15125 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
15126 {
15127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015128 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015129 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015130 ret = -EBUSY;
15131 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015132 }
15133
15134 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015135 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
15136
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015137 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053015138 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015139
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015140 if (VOS_STATUS_SUCCESS != status)
15141 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15143 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015144 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015145 ret = -EINVAL;
15146 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015147 }
15148
Hoonki Leed37cbb32013-04-20 00:31:14 -070015149 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
15150 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
15151
15152 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015153 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070015154 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015155 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070015156 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015157 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080015158
15159 if (pHddCtx->isLogpInProgress)
15160 {
15161 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15162 "%s: LOGP in Progress. Ignore!!!", __func__);
15163 return -EAGAIN;
15164 }
15165
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015166 ret = -EINVAL;
15167 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015168 }
15169
Gopichand Nakkala05922802013-03-14 12:23:19 -070015170 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070015171 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015172 ret = max_sta_failed;
15173 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070015174 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015175
Hoonki Leea34dd892013-02-05 22:56:02 -080015176 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
15177 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015178 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE)) {
15179 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15180 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015181 }
15182 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
15183 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015184 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE)) {
15185 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15186 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015187 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015188
15189 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015190
15191tx_failed:
15192 /* add_station will be called before sending TDLS_SETUP_REQ and
15193 * TDLS_SETUP_RSP and as part of add_station driver will enable
15194 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
15195 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
15196 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
15197 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
15198 */
15199
15200 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
15201 (SIR_MAC_TDLS_SETUP_RSP == action_code))
15202 wlan_hdd_tdls_check_bmps(pAdapter);
15203 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015204}
15205
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015206#if TDLS_MGMT_VERSION2
15207static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15208 u8 *peer, u8 action_code, u8 dialog_token,
15209 u16 status_code, u32 peer_capability,
15210 const u8 *buf, size_t len)
15211#else
15212static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15213 u8 *peer, u8 action_code, u8 dialog_token,
15214 u16 status_code, const u8 *buf, size_t len)
15215#endif
15216{
15217 int ret;
15218
15219 vos_ssr_protect(__func__);
15220#if TDLS_MGMT_VERSION2
15221 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
15222 status_code, peer_capability, buf, len);
15223#else
15224 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
15225 status_code, buf, len);
15226#endif
15227 vos_ssr_unprotect(__func__);
15228
15229 return ret;
15230}
Atul Mittal115287b2014-07-08 13:26:33 +053015231
15232int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
15233 u8 *peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015234 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053015235 cfg80211_exttdls_callback callback)
15236{
15237
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015238 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053015239 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015240 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053015241 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15242 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
15243 __func__, MAC_ADDR_ARRAY(peer));
15244
15245 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15246 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15247
15248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015249 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15250 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15251 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015252 return -ENOTSUPP;
15253 }
15254
15255 /* To cater the requirement of establishing the TDLS link
15256 * irrespective of the data traffic , get an entry of TDLS peer.
15257 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015258 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015259 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
15260 if (pTdlsPeer == NULL) {
15261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15262 "%s: peer " MAC_ADDRESS_STR " not existing",
15263 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015264 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015265 return -EINVAL;
15266 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015267 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015268
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015269 /* check FW TDLS Off Channel capability */
15270 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015271 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015272 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015273 {
15274 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
15275 pTdlsPeer->peerParams.global_operating_class =
15276 tdls_peer_params->global_operating_class;
15277 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
15278 pTdlsPeer->peerParams.min_bandwidth_kbps =
15279 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015280 /* check configured channel is valid, non dfs and
15281 * not current operating channel */
15282 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
15283 tdls_peer_params->channel)) &&
15284 (pHddStaCtx) &&
15285 (tdls_peer_params->channel !=
15286 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015287 {
15288 pTdlsPeer->isOffChannelConfigured = TRUE;
15289 }
15290 else
15291 {
15292 pTdlsPeer->isOffChannelConfigured = FALSE;
15293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15294 "%s: Configured Tdls Off Channel is not valid", __func__);
15295
15296 }
15297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015298 "%s: tdls_off_channel %d isOffChannelConfigured %d "
15299 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015300 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015301 pTdlsPeer->isOffChannelConfigured,
15302 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015303 }
15304 else
15305 {
15306 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015307 "%s: TDLS off channel FW capability %d, "
15308 "host capab %d or Invalid TDLS Peer Params", __func__,
15309 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
15310 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015311 }
15312
Atul Mittal115287b2014-07-08 13:26:33 +053015313 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
15314
15315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15316 " %s TDLS Add Force Peer Failed",
15317 __func__);
15318 return -EINVAL;
15319 }
15320 /*EXT TDLS*/
15321
15322 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
15323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15324 " %s TDLS set callback Failed",
15325 __func__);
15326 return -EINVAL;
15327 }
15328
15329 return(0);
15330
15331}
15332
15333int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
15334{
15335
15336 hddTdlsPeer_t *pTdlsPeer;
15337 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15339 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
15340 __func__, MAC_ADDR_ARRAY(peer));
15341
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015342 if (0 != wlan_hdd_validate_context(pHddCtx)) {
15343 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
15344 return -EINVAL;
15345 }
15346
Atul Mittal115287b2014-07-08 13:26:33 +053015347 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15348 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15349
15350 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015351 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15352 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15353 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015354 return -ENOTSUPP;
15355 }
15356
15357
15358 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15359
15360 if ( NULL == pTdlsPeer ) {
15361 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015362 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053015363 __func__, MAC_ADDR_ARRAY(peer));
15364 return -EINVAL;
15365 }
15366 else {
15367 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
15368 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015369 /* if channel switch is configured, reset
15370 the channel for this peer */
15371 if (TRUE == pTdlsPeer->isOffChannelConfigured)
15372 {
15373 pTdlsPeer->peerParams.channel = 0;
15374 pTdlsPeer->isOffChannelConfigured = FALSE;
15375 }
Atul Mittal115287b2014-07-08 13:26:33 +053015376 }
15377
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015378 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
15379 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053015380 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015381 }
Atul Mittal115287b2014-07-08 13:26:33 +053015382
15383 /*EXT TDLS*/
15384
15385 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
15386
15387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15388 " %s TDLS set callback Failed",
15389 __func__);
15390 return -EINVAL;
15391 }
15392 return(0);
15393
15394}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015395static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015396 u8 *peer, enum nl80211_tdls_operation oper)
15397{
15398 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15399 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015400 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015401 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015402
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015403 ENTER();
15404
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015405 if (!pAdapter) {
15406 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15407 return -EINVAL;
15408 }
15409
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015410 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15411 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
15412 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015413 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015414 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070015416 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015417 return -EINVAL;
15418 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015419
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015420 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015421 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015422 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015423 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015424 }
15425
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015426
15427 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015428 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015429 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015431 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
15432 "Cannot process TDLS commands",
15433 pHddCtx->cfg_ini->fEnableTDLSSupport,
15434 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015435 return -ENOTSUPP;
15436 }
15437
15438 switch (oper) {
15439 case NL80211_TDLS_ENABLE_LINK:
15440 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015441 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015442 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015443 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053015444 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015445 tANI_U16 numCurrTdlsPeers = 0;
15446 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015447 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015448
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15450 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
15451 __func__, MAC_ADDR_ARRAY(peer));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015452 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015453 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015454 if ( NULL == pTdlsPeer ) {
15455 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15456 " (oper %d) not exsting. ignored",
15457 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15458 return -EINVAL;
15459 }
15460
15461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15462 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15463 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15464 "NL80211_TDLS_ENABLE_LINK");
15465
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070015466 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
15467 {
15468 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
15469 MAC_ADDRESS_STR " failed",
15470 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
15471 return -EINVAL;
15472 }
15473
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053015474 /* before starting tdls connection, set tdls
15475 * off channel established status to default value */
15476 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015477 /* TDLS Off Channel, Disable tdls channel switch,
15478 when there are more than one tdls link */
15479 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053015480 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015481 {
15482 /* get connected peer and send disable tdls off chan */
15483 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015484 if ((connPeer) &&
15485 (connPeer->isOffChannelSupported == TRUE) &&
15486 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015487 {
15488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15489 "%s: More then one peer connected, Disable "
15490 "TDLS channel switch", __func__);
15491
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015492 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015493 ret = sme_SendTdlsChanSwitchReq(
15494 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015495 pAdapter->sessionId,
15496 connPeer->peerMac,
15497 connPeer->peerParams.channel,
15498 TDLS_OFF_CHANNEL_BW_OFFSET,
15499 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015500 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015501 hddLog(VOS_TRACE_LEVEL_ERROR,
15502 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015503 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015504 }
15505 else
15506 {
15507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15508 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015509 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015510 "isOffChannelConfigured %d",
15511 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015512 (connPeer ? (connPeer->isOffChannelSupported)
15513 : -1),
15514 (connPeer ? (connPeer->isOffChannelConfigured)
15515 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015516 }
15517 }
15518
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015519 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015520 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015521 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053015522
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015523 if (0 != wlan_hdd_tdls_get_link_establish_params(
15524 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015525 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015526 return -EINVAL;
15527 }
15528 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015529
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015530 ret = sme_SendTdlsLinkEstablishParams(
15531 WLAN_HDD_GET_HAL_CTX(pAdapter),
15532 pAdapter->sessionId, peer,
15533 &tdlsLinkEstablishParams);
15534 if (ret != VOS_STATUS_SUCCESS) {
15535 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
15536 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015537 /* Send TDLS peer UAPSD capabilities to the firmware and
15538 * register with the TL on after the response for this operation
15539 * is received .
15540 */
15541 ret = wait_for_completion_interruptible_timeout(
15542 &pAdapter->tdls_link_establish_req_comp,
15543 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
15544 if (ret <= 0)
15545 {
15546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015547 FL("Link Establish Request Failed Status %ld"),
15548 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015549 return -EINVAL;
15550 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015551 }
Atul Mittal115287b2014-07-08 13:26:33 +053015552 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15553 eTDLS_LINK_CONNECTED,
15554 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015555 staDesc.ucSTAId = pTdlsPeer->staId;
15556 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015557 ret = WLANTL_UpdateTdlsSTAClient(
15558 pHddCtx->pvosContext,
15559 &staDesc);
15560 if (ret != VOS_STATUS_SUCCESS) {
15561 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
15562 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053015563
Gopichand Nakkala471708b2013-06-04 20:03:01 +053015564 /* Mark TDLS client Authenticated .*/
15565 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
15566 pTdlsPeer->staId,
15567 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015568 if (VOS_STATUS_SUCCESS == status)
15569 {
Hoonki Lee14621352013-04-16 17:51:19 -070015570 if (pTdlsPeer->is_responder == 0)
15571 {
15572 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
15573
15574 wlan_hdd_tdls_timer_restart(pAdapter,
15575 &pTdlsPeer->initiatorWaitTimeoutTimer,
15576 WAIT_TIME_TDLS_INITIATOR);
15577 /* suspend initiator TX until it receives direct packet from the
15578 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015579 ret = WLANTL_SuspendDataTx(
15580 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15581 &staId, NULL);
15582 if (ret != VOS_STATUS_SUCCESS) {
15583 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
15584 }
Hoonki Lee14621352013-04-16 17:51:19 -070015585 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015586
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015587 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015588 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015589 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015590 suppChannelLen =
15591 tdlsLinkEstablishParams.supportedChannelsLen;
15592
15593 if ((suppChannelLen > 0) &&
15594 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
15595 {
15596 tANI_U8 suppPeerChannel = 0;
15597 int i = 0;
15598 for (i = 0U; i < suppChannelLen; i++)
15599 {
15600 suppPeerChannel =
15601 tdlsLinkEstablishParams.supportedChannels[i];
15602
15603 pTdlsPeer->isOffChannelSupported = FALSE;
15604 if (suppPeerChannel ==
15605 pTdlsPeer->peerParams.channel)
15606 {
15607 pTdlsPeer->isOffChannelSupported = TRUE;
15608 break;
15609 }
15610 }
15611 }
15612 else
15613 {
15614 pTdlsPeer->isOffChannelSupported = FALSE;
15615 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015616 }
15617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15618 "%s: TDLS channel switch request for channel "
15619 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015620 "%d isOffChannelSupported %d", __func__,
15621 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015622 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015623 suppChannelLen,
15624 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015625
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015626 /* TDLS Off Channel, Enable tdls channel switch,
15627 when their is only one tdls link and it supports */
15628 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15629 if ((numCurrTdlsPeers == 1) &&
15630 (TRUE == pTdlsPeer->isOffChannelSupported) &&
15631 (TRUE == pTdlsPeer->isOffChannelConfigured))
15632 {
15633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15634 "%s: Send TDLS channel switch request for channel %d",
15635 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015636
15637 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015638 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
15639 pAdapter->sessionId,
15640 pTdlsPeer->peerMac,
15641 pTdlsPeer->peerParams.channel,
15642 TDLS_OFF_CHANNEL_BW_OFFSET,
15643 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015644 if (ret != VOS_STATUS_SUCCESS) {
15645 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
15646 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015647 }
15648 else
15649 {
15650 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15651 "%s: TDLS channel switch request not sent"
15652 " numCurrTdlsPeers %d "
15653 "isOffChannelSupported %d "
15654 "isOffChannelConfigured %d",
15655 __func__, numCurrTdlsPeers,
15656 pTdlsPeer->isOffChannelSupported,
15657 pTdlsPeer->isOffChannelConfigured);
15658 }
15659
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015660 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015661 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015662
15663 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015664 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
15665 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015666 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015667 int ac;
15668 uint8 ucAc[4] = { WLANTL_AC_VO,
15669 WLANTL_AC_VI,
15670 WLANTL_AC_BK,
15671 WLANTL_AC_BE };
15672 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
15673 for(ac=0; ac < 4; ac++)
15674 {
15675 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15676 pTdlsPeer->staId, ucAc[ac],
15677 tlTid[ac], tlTid[ac], 0, 0,
15678 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015679 if (status != VOS_STATUS_SUCCESS) {
15680 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
15681 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015682 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015683 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015684 }
15685
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015686 }
15687 break;
15688 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080015689 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015690 tANI_U16 numCurrTdlsPeers = 0;
15691 hddTdlsPeer_t *connPeer = NULL;
15692
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15694 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
15695 __func__, MAC_ADDR_ARRAY(peer));
15696
Sunil Dutt41de4e22013-11-14 18:09:02 +053015697 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15698
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015699
Sunil Dutt41de4e22013-11-14 18:09:02 +053015700 if ( NULL == pTdlsPeer ) {
15701 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15702 " (oper %d) not exsting. ignored",
15703 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15704 return -EINVAL;
15705 }
15706
15707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15708 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15709 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15710 "NL80211_TDLS_DISABLE_LINK");
15711
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015712 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080015713 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015714 long status;
15715
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053015716 /* set tdls off channel status to false for this peer */
15717 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053015718 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15719 eTDLS_LINK_TEARING,
15720 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
15721 eTDLS_LINK_UNSPECIFIED:
15722 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015723 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
15724
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015725 status = sme_DeleteTdlsPeerSta(
15726 WLAN_HDD_GET_HAL_CTX(pAdapter),
15727 pAdapter->sessionId, peer );
15728 if (status != VOS_STATUS_SUCCESS) {
15729 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15730 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015731
15732 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
15733 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053015734 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053015735 eTDLS_LINK_IDLE,
15736 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015737 if (status <= 0)
15738 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015739 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15740 "%s: Del station failed status %ld",
15741 __func__, status);
15742 return -EPERM;
15743 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015744
15745 /* TDLS Off Channel, Enable tdls channel switch,
15746 when their is only one tdls link and it supports */
15747 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15748 if (numCurrTdlsPeers == 1)
15749 {
15750 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
15751 if ((connPeer) &&
15752 (connPeer->isOffChannelSupported == TRUE) &&
15753 (connPeer->isOffChannelConfigured == TRUE))
15754 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015755 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015756 status = sme_SendTdlsChanSwitchReq(
15757 WLAN_HDD_GET_HAL_CTX(pAdapter),
15758 pAdapter->sessionId,
15759 connPeer->peerMac,
15760 connPeer->peerParams.channel,
15761 TDLS_OFF_CHANNEL_BW_OFFSET,
15762 TDLS_CHANNEL_SWITCH_ENABLE);
15763 if (status != VOS_STATUS_SUCCESS) {
15764 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
15765 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015766 }
15767 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15768 "%s: TDLS channel switch "
15769 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015770 "isOffChannelConfigured %d "
15771 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015772 __func__,
15773 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015774 (connPeer ? connPeer->isOffChannelConfigured : -1),
15775 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015776 }
15777 else
15778 {
15779 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15780 "%s: TDLS channel switch request not sent "
15781 "numCurrTdlsPeers %d ",
15782 __func__, numCurrTdlsPeers);
15783 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015784 }
15785 else
15786 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015787 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15788 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080015789 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015790 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015791 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015792 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015793 {
Atul Mittal115287b2014-07-08 13:26:33 +053015794 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015795
Atul Mittal115287b2014-07-08 13:26:33 +053015796 if (0 != status)
15797 {
15798 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015799 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053015800 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015801 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053015802 break;
15803 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015804 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015805 {
Atul Mittal115287b2014-07-08 13:26:33 +053015806 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
15807 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015808 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053015809 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015810
Atul Mittal115287b2014-07-08 13:26:33 +053015811 if (0 != status)
15812 {
15813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015814 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053015815 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053015816 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053015817 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015818 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015819 case NL80211_TDLS_DISCOVERY_REQ:
15820 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015821 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015822 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015823 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015824 return -ENOTSUPP;
15825 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15827 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015828 return -ENOTSUPP;
15829 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015830
15831 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015832 return 0;
15833}
Chilam NG571c65a2013-01-19 12:27:36 +053015834
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015835static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
15836 u8 *peer, enum nl80211_tdls_operation oper)
15837{
15838 int ret;
15839
15840 vos_ssr_protect(__func__);
15841 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
15842 vos_ssr_unprotect(__func__);
15843
15844 return ret;
15845}
15846
Chilam NG571c65a2013-01-19 12:27:36 +053015847int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
15848 struct net_device *dev, u8 *peer)
15849{
Arif Hussaina7c8e412013-11-20 11:06:42 -080015850 hddLog(VOS_TRACE_LEVEL_INFO,
15851 "tdls send discover req: "MAC_ADDRESS_STR,
15852 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053015853
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015854#if TDLS_MGMT_VERSION2
15855 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15856 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15857#else
Chilam NG571c65a2013-01-19 12:27:36 +053015858 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15859 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015860#endif
Chilam NG571c65a2013-01-19 12:27:36 +053015861}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015862#endif
15863
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015864#ifdef WLAN_FEATURE_GTK_OFFLOAD
15865/*
15866 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
15867 * Callback rountine called upon receiving response for
15868 * get offload info
15869 */
15870void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
15871 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
15872{
15873
15874 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015875 tANI_U8 tempReplayCounter[8];
15876 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015877
15878 ENTER();
15879
15880 if (NULL == pAdapter)
15881 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053015882 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015883 "%s: HDD adapter is Null", __func__);
15884 return ;
15885 }
15886
15887 if (NULL == pGtkOffloadGetInfoRsp)
15888 {
15889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15890 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
15891 return ;
15892 }
15893
15894 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
15895 {
15896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15897 "%s: wlan Failed to get replay counter value",
15898 __func__);
15899 return ;
15900 }
15901
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015902 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15903 /* Update replay counter */
15904 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
15905 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15906
15907 {
15908 /* changing from little to big endian since supplicant
15909 * works on big endian format
15910 */
15911 int i;
15912 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15913
15914 for (i = 0; i < 8; i++)
15915 {
15916 tempReplayCounter[7-i] = (tANI_U8)p[i];
15917 }
15918 }
15919
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015920 /* Update replay counter to NL */
15921 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015922 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015923}
15924
15925/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015926 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015927 * This function is used to offload GTK rekeying job to the firmware.
15928 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015929int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015930 struct cfg80211_gtk_rekey_data *data)
15931{
15932 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15933 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15934 hdd_station_ctx_t *pHddStaCtx;
15935 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015936 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015937 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015938 eHalStatus status = eHAL_STATUS_FAILURE;
15939
15940 ENTER();
15941
15942 if (NULL == pAdapter)
15943 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015944 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015945 "%s: HDD adapter is Null", __func__);
15946 return -ENODEV;
15947 }
15948
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015949 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15950 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
15951 pAdapter->sessionId, pAdapter->device_mode));
15952
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015953 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015954 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015955 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015956 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015957 }
15958
15959 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15960 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15961 if (NULL == hHal)
15962 {
15963 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15964 "%s: HAL context is Null!!!", __func__);
15965 return -EAGAIN;
15966 }
15967
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015968 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
15969 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
15970 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
15971 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015972 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015973 {
15974 /* changing from big to little endian since driver
15975 * works on little endian format
15976 */
15977 tANI_U8 *p =
15978 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
15979 int i;
15980
15981 for (i = 0; i < 8; i++)
15982 {
15983 p[7-i] = data->replay_ctr[i];
15984 }
15985 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015986
15987 if (TRUE == pHddCtx->hdd_wlan_suspended)
15988 {
15989 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015990 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
15991 sizeof (tSirGtkOffloadParams));
15992 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015993 pAdapter->sessionId);
15994
15995 if (eHAL_STATUS_SUCCESS != status)
15996 {
15997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15998 "%s: sme_SetGTKOffload failed, returned %d",
15999 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016000
16001 /* Need to clear any trace of key value in the memory.
16002 * Thus zero out the memory even though it is local
16003 * variable.
16004 */
16005 vos_mem_zero(&hddGtkOffloadReqParams,
16006 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016007 return status;
16008 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16010 "%s: sme_SetGTKOffload successfull", __func__);
16011 }
16012 else
16013 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16015 "%s: wlan not suspended GTKOffload request is stored",
16016 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016017 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016018
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016019 /* Need to clear any trace of key value in the memory.
16020 * Thus zero out the memory even though it is local
16021 * variable.
16022 */
16023 vos_mem_zero(&hddGtkOffloadReqParams,
16024 sizeof(hddGtkOffloadReqParams));
16025
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016026 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016027 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016028}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016029
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016030int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
16031 struct cfg80211_gtk_rekey_data *data)
16032{
16033 int ret;
16034
16035 vos_ssr_protect(__func__);
16036 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
16037 vos_ssr_unprotect(__func__);
16038
16039 return ret;
16040}
16041#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016042/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016043 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016044 * This function is used to set access control policy
16045 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016046static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16047 struct net_device *dev,
16048 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016049{
16050 int i;
16051 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16052 hdd_hostapd_state_t *pHostapdState;
16053 tsap_Config_t *pConfig;
16054 v_CONTEXT_t pVosContext = NULL;
16055 hdd_context_t *pHddCtx;
16056 int status;
16057
16058 ENTER();
16059
16060 if (NULL == pAdapter)
16061 {
16062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16063 "%s: HDD adapter is Null", __func__);
16064 return -ENODEV;
16065 }
16066
16067 if (NULL == params)
16068 {
16069 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16070 "%s: params is Null", __func__);
16071 return -EINVAL;
16072 }
16073
16074 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16075 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016076 if (0 != status)
16077 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016078 return status;
16079 }
16080
16081 pVosContext = pHddCtx->pvosContext;
16082 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
16083
16084 if (NULL == pHostapdState)
16085 {
16086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16087 "%s: pHostapdState is Null", __func__);
16088 return -EINVAL;
16089 }
16090
16091 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
16092 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016093 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16094 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
16095 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016096
16097 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
16098 {
16099 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
16100
16101 /* default value */
16102 pConfig->num_accept_mac = 0;
16103 pConfig->num_deny_mac = 0;
16104
16105 /**
16106 * access control policy
16107 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
16108 * listed in hostapd.deny file.
16109 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
16110 * listed in hostapd.accept file.
16111 */
16112 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
16113 {
16114 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
16115 }
16116 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
16117 {
16118 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
16119 }
16120 else
16121 {
16122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16123 "%s:Acl Policy : %d is not supported",
16124 __func__, params->acl_policy);
16125 return -ENOTSUPP;
16126 }
16127
16128 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
16129 {
16130 pConfig->num_accept_mac = params->n_acl_entries;
16131 for (i = 0; i < params->n_acl_entries; i++)
16132 {
16133 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16134 "** Add ACL MAC entry %i in WhiletList :"
16135 MAC_ADDRESS_STR, i,
16136 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16137
16138 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
16139 sizeof(qcmacaddr));
16140 }
16141 }
16142 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
16143 {
16144 pConfig->num_deny_mac = params->n_acl_entries;
16145 for (i = 0; i < params->n_acl_entries; i++)
16146 {
16147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16148 "** Add ACL MAC entry %i in BlackList :"
16149 MAC_ADDRESS_STR, i,
16150 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16151
16152 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
16153 sizeof(qcmacaddr));
16154 }
16155 }
16156
16157 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
16158 {
16159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16160 "%s: SAP Set Mac Acl fail", __func__);
16161 return -EINVAL;
16162 }
16163 }
16164 else
16165 {
16166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016167 "%s: Invalid device_mode = %s (%d)",
16168 __func__, hdd_device_modetoString(pAdapter->device_mode),
16169 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016170 return -EINVAL;
16171 }
16172
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016173 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016174 return 0;
16175}
16176
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016177static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16178 struct net_device *dev,
16179 const struct cfg80211_acl_data *params)
16180{
16181 int ret;
16182 vos_ssr_protect(__func__);
16183 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
16184 vos_ssr_unprotect(__func__);
16185
16186 return ret;
16187}
16188
Leo Chang9056f462013-08-01 19:21:11 -070016189#ifdef WLAN_NL80211_TESTMODE
16190#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070016191void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070016192(
16193 void *pAdapter,
16194 void *indCont
16195)
16196{
Leo Changd9df8aa2013-09-26 13:32:26 -070016197 tSirLPHBInd *lphbInd;
16198 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053016199 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070016200
16201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016202 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070016203
c_hpothu73f35e62014-04-18 13:40:08 +053016204 if (pAdapter == NULL)
16205 {
16206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16207 "%s: pAdapter is NULL\n",__func__);
16208 return;
16209 }
16210
Leo Chang9056f462013-08-01 19:21:11 -070016211 if (NULL == indCont)
16212 {
16213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016214 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070016215 return;
16216 }
16217
c_hpothu73f35e62014-04-18 13:40:08 +053016218 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070016219 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070016220 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053016221 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070016222 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070016223 GFP_ATOMIC);
16224 if (!skb)
16225 {
16226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16227 "LPHB timeout, NL buffer alloc fail");
16228 return;
16229 }
16230
Leo Changac3ba772013-10-07 09:47:04 -070016231 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070016232 {
16233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16234 "WLAN_HDD_TM_ATTR_CMD put fail");
16235 goto nla_put_failure;
16236 }
Leo Changac3ba772013-10-07 09:47:04 -070016237 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070016238 {
16239 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16240 "WLAN_HDD_TM_ATTR_TYPE put fail");
16241 goto nla_put_failure;
16242 }
Leo Changac3ba772013-10-07 09:47:04 -070016243 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070016244 sizeof(tSirLPHBInd), lphbInd))
16245 {
16246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16247 "WLAN_HDD_TM_ATTR_DATA put fail");
16248 goto nla_put_failure;
16249 }
Leo Chang9056f462013-08-01 19:21:11 -070016250 cfg80211_testmode_event(skb, GFP_ATOMIC);
16251 return;
16252
16253nla_put_failure:
16254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16255 "NLA Put fail");
16256 kfree_skb(skb);
16257
16258 return;
16259}
16260#endif /* FEATURE_WLAN_LPHB */
16261
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016262static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070016263{
16264 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
16265 int err = 0;
16266#ifdef FEATURE_WLAN_LPHB
16267 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070016268 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016269
16270 ENTER();
16271
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016272 err = wlan_hdd_validate_context(pHddCtx);
16273 if (0 != err)
16274 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016275 return err;
16276 }
Leo Chang9056f462013-08-01 19:21:11 -070016277#endif /* FEATURE_WLAN_LPHB */
16278
16279 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
16280 if (err)
16281 {
16282 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16283 "%s Testmode INV ATTR", __func__);
16284 return err;
16285 }
16286
16287 if (!tb[WLAN_HDD_TM_ATTR_CMD])
16288 {
16289 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16290 "%s Testmode INV CMD", __func__);
16291 return -EINVAL;
16292 }
16293
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016294 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16295 TRACE_CODE_HDD_CFG80211_TESTMODE,
16296 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070016297 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
16298 {
16299#ifdef FEATURE_WLAN_LPHB
16300 /* Low Power Heartbeat configuration request */
16301 case WLAN_HDD_TM_CMD_WLAN_HB:
16302 {
16303 int buf_len;
16304 void *buf;
16305 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080016306 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070016307
16308 if (!tb[WLAN_HDD_TM_ATTR_DATA])
16309 {
16310 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16311 "%s Testmode INV DATA", __func__);
16312 return -EINVAL;
16313 }
16314
16315 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
16316 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080016317
16318 hb_params_temp =(tSirLPHBReq *)buf;
16319 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
16320 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
16321 return -EINVAL;
16322
Leo Chang9056f462013-08-01 19:21:11 -070016323 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
16324 if (NULL == hb_params)
16325 {
16326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16327 "%s Request Buffer Alloc Fail", __func__);
16328 return -EINVAL;
16329 }
16330
16331 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070016332 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
16333 hb_params,
16334 wlan_hdd_cfg80211_lphb_ind_handler);
16335 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070016336 {
Leo Changd9df8aa2013-09-26 13:32:26 -070016337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16338 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070016339 vos_mem_free(hb_params);
16340 }
Leo Chang9056f462013-08-01 19:21:11 -070016341 return 0;
16342 }
16343#endif /* FEATURE_WLAN_LPHB */
16344 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016345 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16346 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070016347 return -EOPNOTSUPP;
16348 }
16349
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016350 EXIT();
16351 return err;
Leo Chang9056f462013-08-01 19:21:11 -070016352}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016353
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053016354static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
16355#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
16356 struct wireless_dev *wdev,
16357#endif
16358 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016359{
16360 int ret;
16361
16362 vos_ssr_protect(__func__);
16363 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
16364 vos_ssr_unprotect(__func__);
16365
16366 return ret;
16367}
Leo Chang9056f462013-08-01 19:21:11 -070016368#endif /* CONFIG_NL80211_TESTMODE */
16369
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016370static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016371 struct net_device *dev,
16372 int idx, struct survey_info *survey)
16373{
16374 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16375 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053016376 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016377 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053016378 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016379 v_S7_t snr,rssi;
16380 int status, i, j, filled = 0;
16381
16382 ENTER();
16383
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016384 if (NULL == pAdapter)
16385 {
16386 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16387 "%s: HDD adapter is Null", __func__);
16388 return -ENODEV;
16389 }
16390
16391 if (NULL == wiphy)
16392 {
16393 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16394 "%s: wiphy is Null", __func__);
16395 return -ENODEV;
16396 }
16397
16398 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16399 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016400 if (0 != status)
16401 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016402 return status;
16403 }
16404
Mihir Sheted9072e02013-08-21 17:02:29 +053016405 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16406
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016407 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053016408 0 != pAdapter->survey_idx ||
16409 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016410 {
16411 /* The survey dump ops when implemented completely is expected to
16412 * return a survey of all channels and the ops is called by the
16413 * kernel with incremental values of the argument 'idx' till it
16414 * returns -ENONET. But we can only support the survey for the
16415 * operating channel for now. survey_idx is used to track
16416 * that the ops is called only once and then return -ENONET for
16417 * the next iteration
16418 */
16419 pAdapter->survey_idx = 0;
16420 return -ENONET;
16421 }
16422
Mukul Sharma9d5233b2015-06-11 20:28:20 +053016423 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16424 {
16425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16426 "%s: Roaming in progress, hence return ", __func__);
16427 return -ENONET;
16428 }
16429
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016430 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16431
16432 wlan_hdd_get_snr(pAdapter, &snr);
16433 wlan_hdd_get_rssi(pAdapter, &rssi);
16434
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016435 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16436 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
16437 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016438 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
16439 hdd_wlan_get_freq(channel, &freq);
16440
16441
16442 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
16443 {
16444 if (NULL == wiphy->bands[i])
16445 {
16446 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
16447 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
16448 continue;
16449 }
16450
16451 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
16452 {
16453 struct ieee80211_supported_band *band = wiphy->bands[i];
16454
16455 if (band->channels[j].center_freq == (v_U16_t)freq)
16456 {
16457 survey->channel = &band->channels[j];
16458 /* The Rx BDs contain SNR values in dB for the received frames
16459 * while the supplicant expects noise. So we calculate and
16460 * return the value of noise (dBm)
16461 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
16462 */
16463 survey->noise = rssi - snr;
16464 survey->filled = SURVEY_INFO_NOISE_DBM;
16465 filled = 1;
16466 }
16467 }
16468 }
16469
16470 if (filled)
16471 pAdapter->survey_idx = 1;
16472 else
16473 {
16474 pAdapter->survey_idx = 0;
16475 return -ENONET;
16476 }
16477
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016478 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016479 return 0;
16480}
16481
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016482static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
16483 struct net_device *dev,
16484 int idx, struct survey_info *survey)
16485{
16486 int ret;
16487
16488 vos_ssr_protect(__func__);
16489 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
16490 vos_ssr_unprotect(__func__);
16491
16492 return ret;
16493}
16494
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016495/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016496 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016497 * this is called when cfg80211 driver resume
16498 * driver updates latest sched_scan scan result(if any) to cfg80211 database
16499 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016500int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016501{
16502 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16503 hdd_adapter_t *pAdapter;
16504 hdd_adapter_list_node_t *pAdapterNode, *pNext;
16505 VOS_STATUS status = VOS_STATUS_SUCCESS;
16506
16507 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016508
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016509 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016510 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016511 return 0;
16512 }
16513
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016514 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
16515 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016516 spin_lock(&pHddCtx->schedScan_lock);
16517 pHddCtx->isWiphySuspended = FALSE;
16518 if (TRUE != pHddCtx->isSchedScanUpdatePending)
16519 {
16520 spin_unlock(&pHddCtx->schedScan_lock);
16521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16522 "%s: Return resume is not due to PNO indication", __func__);
16523 return 0;
16524 }
16525 // Reset flag to avoid updatating cfg80211 data old results again
16526 pHddCtx->isSchedScanUpdatePending = FALSE;
16527 spin_unlock(&pHddCtx->schedScan_lock);
16528
16529 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
16530
16531 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
16532 {
16533 pAdapter = pAdapterNode->pAdapter;
16534 if ( (NULL != pAdapter) &&
16535 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
16536 {
16537 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016538 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16540 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016541 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016542 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016543 {
16544 /* Acquire wakelock to handle the case where APP's tries to
16545 * suspend immediately after updating the scan results. Whis
16546 * results in app's is in suspended state and not able to
16547 * process the connect request to AP
16548 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053016549 hdd_prevent_suspend_timeout(2000,
16550 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016551 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016552 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016553
16554 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16555 "%s : cfg80211 scan result database updated", __func__);
16556
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016557 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016558 return 0;
16559
16560 }
16561 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16562 pAdapterNode = pNext;
16563 }
16564
16565 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16566 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016567 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016568 return 0;
16569}
16570
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016571int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
16572{
16573 int ret;
16574
16575 vos_ssr_protect(__func__);
16576 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
16577 vos_ssr_unprotect(__func__);
16578
16579 return ret;
16580}
16581
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016582/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016583 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016584 * this is called when cfg80211 driver suspends
16585 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016586int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016587 struct cfg80211_wowlan *wow)
16588{
16589 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016590 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016591
16592 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016593
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016594 ret = wlan_hdd_validate_context(pHddCtx);
16595 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016596 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016597 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016598 }
16599
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016600
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016601 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16602 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
16603 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016604 pHddCtx->isWiphySuspended = TRUE;
16605
16606 EXIT();
16607
16608 return 0;
16609}
16610
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016611int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
16612 struct cfg80211_wowlan *wow)
16613{
16614 int ret;
16615
16616 vos_ssr_protect(__func__);
16617 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
16618 vos_ssr_unprotect(__func__);
16619
16620 return ret;
16621}
Jeff Johnson295189b2012-06-20 16:38:30 -070016622/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016623static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070016624{
16625 .add_virtual_intf = wlan_hdd_add_virtual_intf,
16626 .del_virtual_intf = wlan_hdd_del_virtual_intf,
16627 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
16628 .change_station = wlan_hdd_change_station,
16629#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
16630 .add_beacon = wlan_hdd_cfg80211_add_beacon,
16631 .del_beacon = wlan_hdd_cfg80211_del_beacon,
16632 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016633#else
16634 .start_ap = wlan_hdd_cfg80211_start_ap,
16635 .change_beacon = wlan_hdd_cfg80211_change_beacon,
16636 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070016637#endif
16638 .change_bss = wlan_hdd_cfg80211_change_bss,
16639 .add_key = wlan_hdd_cfg80211_add_key,
16640 .get_key = wlan_hdd_cfg80211_get_key,
16641 .del_key = wlan_hdd_cfg80211_del_key,
16642 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016643#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070016644 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016645#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016646 .scan = wlan_hdd_cfg80211_scan,
16647 .connect = wlan_hdd_cfg80211_connect,
16648 .disconnect = wlan_hdd_cfg80211_disconnect,
16649 .join_ibss = wlan_hdd_cfg80211_join_ibss,
16650 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
16651 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
16652 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
16653 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070016654 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
16655 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053016656 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070016657#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16658 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
16659 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
16660 .set_txq_params = wlan_hdd_set_txq_params,
16661#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016662 .get_station = wlan_hdd_cfg80211_get_station,
16663 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
16664 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016665 .add_station = wlan_hdd_cfg80211_add_station,
16666#ifdef FEATURE_WLAN_LFR
16667 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
16668 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
16669 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
16670#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016671#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
16672 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
16673#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016674#ifdef FEATURE_WLAN_TDLS
16675 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
16676 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
16677#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016678#ifdef WLAN_FEATURE_GTK_OFFLOAD
16679 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
16680#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016681#ifdef FEATURE_WLAN_SCAN_PNO
16682 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
16683 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
16684#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016685 .resume = wlan_hdd_cfg80211_resume_wlan,
16686 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016687 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070016688#ifdef WLAN_NL80211_TESTMODE
16689 .testmode_cmd = wlan_hdd_cfg80211_testmode,
16690#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016691 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070016692};
16693