blob: 4ad664b0a29cdf42442d4cbbe1682f2e218825e9 [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,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301077 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1078 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1079 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301080 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1081 pWifiIfaceStat->beaconRx) ||
1082 nla_put_u32(vendor_event,
1083 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1084 pWifiIfaceStat->mgmtRx) ||
1085 nla_put_u32(vendor_event,
1086 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1087 pWifiIfaceStat->mgmtActionRx) ||
1088 nla_put_u32(vendor_event,
1089 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1090 pWifiIfaceStat->mgmtActionTx) ||
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_MGMT,
1093 pWifiIfaceStat->rssiMgmt) ||
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_DATA,
1096 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301097 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301098 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1099 pWifiIfaceStat->rssiAck))
1100 {
1101 hddLog(VOS_TRACE_LEVEL_ERROR,
1102 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301103 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301104 return FALSE;
1105 }
1106
1107 wmmInfo = nla_nest_start(vendor_event,
1108 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301109 if(!wmmInfo)
1110 {
1111 vos_mem_free(pWifiIfaceStatTL);
1112 return FALSE;
1113 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301114 for (i = 0; i < WIFI_AC_MAX; i++)
1115 {
1116 struct nlattr *wmmStats;
1117 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301118 if(!wmmStats)
1119 {
1120 vos_mem_free(pWifiIfaceStatTL);
1121 return FALSE;
1122 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301123 if (FALSE == put_wifi_wmm_ac_stat(
1124 &pWifiIfaceStat->AccessclassStats[i],
1125 vendor_event))
1126 {
1127 hddLog(VOS_TRACE_LEVEL_ERROR,
1128 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301129 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301130 return FALSE;
1131 }
1132
1133 nla_nest_end(vendor_event, wmmStats);
1134 }
1135 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301136 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301137 return TRUE;
1138}
1139
1140static tSirWifiInterfaceMode
1141 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1142{
1143 switch (deviceMode)
1144 {
1145 case WLAN_HDD_INFRA_STATION:
1146 return WIFI_INTERFACE_STA;
1147 case WLAN_HDD_SOFTAP:
1148 return WIFI_INTERFACE_SOFTAP;
1149 case WLAN_HDD_P2P_CLIENT:
1150 return WIFI_INTERFACE_P2P_CLIENT;
1151 case WLAN_HDD_P2P_GO:
1152 return WIFI_INTERFACE_P2P_GO;
1153 case WLAN_HDD_IBSS:
1154 return WIFI_INTERFACE_IBSS;
1155 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301156 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301157 }
1158}
1159
1160static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1161 tpSirWifiInterfaceInfo pInfo)
1162{
1163 v_U8_t *staMac = NULL;
1164 hdd_station_ctx_t *pHddStaCtx;
1165 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1166 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1167
1168 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1169
1170 vos_mem_copy(pInfo->macAddr,
1171 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1172
1173 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1174 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1175 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1176 {
1177 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1178 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1179 {
1180 pInfo->state = WIFI_DISCONNECTED;
1181 }
1182 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1183 {
1184 hddLog(VOS_TRACE_LEVEL_ERROR,
1185 "%s: Session ID %d, Connection is in progress", __func__,
1186 pAdapter->sessionId);
1187 pInfo->state = WIFI_ASSOCIATING;
1188 }
1189 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1190 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1191 {
1192 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1193 hddLog(VOS_TRACE_LEVEL_ERROR,
1194 "%s: client " MAC_ADDRESS_STR
1195 " is in the middle of WPS/EAPOL exchange.", __func__,
1196 MAC_ADDR_ARRAY(staMac));
1197 pInfo->state = WIFI_AUTHENTICATING;
1198 }
1199 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1200 {
1201 pInfo->state = WIFI_ASSOCIATED;
1202 vos_mem_copy(pInfo->bssid,
1203 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1204 vos_mem_copy(pInfo->ssid,
1205 pHddStaCtx->conn_info.SSID.SSID.ssId,
1206 pHddStaCtx->conn_info.SSID.SSID.length);
1207 //NULL Terminate the string.
1208 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1209 }
1210 }
1211 vos_mem_copy(pInfo->countryStr,
1212 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1213
1214 vos_mem_copy(pInfo->apCountryStr,
1215 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1216
1217 return TRUE;
1218}
1219
1220/*
1221 * hdd_link_layer_process_peer_stats () - This function is called after
1222 * receiving Link Layer Peer statistics from FW.This function converts
1223 * the firmware data to the NL data and sends the same to the kernel/upper
1224 * layers.
1225 */
1226static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1227 v_VOID_t *pData)
1228{
1229 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1230 tpSirWifiRateStat pWifiRateStat;
1231 tpSirWifiPeerStat pWifiPeerStat;
1232 tpSirWifiPeerInfo pWifiPeerInfo;
1233 struct nlattr *peerInfo;
1234 struct sk_buff *vendor_event;
1235 int status, i;
1236
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301237 ENTER();
1238
Sunil Duttc69bccb2014-05-26 21:30:20 +05301239 status = wlan_hdd_validate_context(pHddCtx);
1240 if (0 != status)
1241 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301242 return;
1243 }
1244
1245 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1246
1247 hddLog(VOS_TRACE_LEVEL_INFO,
1248 "LL_STATS_PEER_ALL : numPeers %u",
1249 pWifiPeerStat->numPeers);
1250 {
1251 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1252 {
1253 pWifiPeerInfo = (tpSirWifiPeerInfo)
1254 ((uint8 *)pWifiPeerStat->peerInfo +
1255 ( i * sizeof(tSirWifiPeerInfo)));
1256
Dasari Srinivas1be0c4e2014-10-19 13:03:41 +05301257 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) {
1258 pWifiPeerInfo->type = WIFI_PEER_AP;
1259 }
1260 if (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) {
1261 pWifiPeerInfo->type = WIFI_PEER_P2P_GO;
1262 }
1263
Sunil Duttc69bccb2014-05-26 21:30:20 +05301264 hddLog(VOS_TRACE_LEVEL_INFO,
1265 " %d) LL_STATS Channel Stats "
1266 " Peer Type %u "
1267 " peerMacAddress %pM "
1268 " capabilities 0x%x "
1269 " numRate %u ",
1270 i,
1271 pWifiPeerInfo->type,
1272 pWifiPeerInfo->peerMacAddress,
1273 pWifiPeerInfo->capabilities,
1274 pWifiPeerInfo->numRate);
1275 {
1276 int j;
1277 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1278 {
1279 pWifiRateStat = (tpSirWifiRateStat)
1280 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1281 ( j * sizeof(tSirWifiRateStat)));
1282
1283 hddLog(VOS_TRACE_LEVEL_INFO,
1284 " peer Rate Stats "
1285 " preamble %u "
1286 " nss %u "
1287 " bw %u "
1288 " rateMcsIdx %u "
1289 " reserved %u "
1290 " bitrate %u "
1291 " txMpdu %u "
1292 " rxMpdu %u "
1293 " mpduLost %u "
1294 " retries %u "
1295 " retriesShort %u "
1296 " retriesLong %u",
1297 pWifiRateStat->rate.preamble,
1298 pWifiRateStat->rate.nss,
1299 pWifiRateStat->rate.bw,
1300 pWifiRateStat->rate.rateMcsIdx,
1301 pWifiRateStat->rate.reserved,
1302 pWifiRateStat->rate.bitrate,
1303 pWifiRateStat->txMpdu,
1304 pWifiRateStat->rxMpdu,
1305 pWifiRateStat->mpduLost,
1306 pWifiRateStat->retries,
1307 pWifiRateStat->retriesShort,
1308 pWifiRateStat->retriesLong);
1309 }
1310 }
1311 }
1312 }
1313
1314 /*
1315 * Allocate a size of 4096 for the peer stats comprising
1316 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1317 * sizeof (tSirWifiRateStat).Each field is put with an
1318 * NL attribute.The size of 4096 is considered assuming
1319 * that number of rates shall not exceed beyond 50 with
1320 * the sizeof (tSirWifiRateStat) being 32.
1321 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301322 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1323 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301324 if (!vendor_event)
1325 {
1326 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301327 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301328 __func__);
1329 return;
1330 }
1331 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301332 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1333 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1334 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301335 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1336 pWifiPeerStat->numPeers))
1337 {
1338 hddLog(VOS_TRACE_LEVEL_ERROR,
1339 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1340 kfree_skb(vendor_event);
1341 return;
1342 }
1343
1344 peerInfo = nla_nest_start(vendor_event,
1345 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301346 if(!peerInfo)
1347 {
1348 hddLog(VOS_TRACE_LEVEL_ERROR,
1349 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1350 __func__);
1351 kfree_skb(vendor_event);
1352 return;
1353 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301354
1355 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1356 pWifiPeerStat->peerInfo);
1357
1358 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1359 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301360 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301361 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301362
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301363 if(!peers)
1364 {
1365 hddLog(VOS_TRACE_LEVEL_ERROR,
1366 "%s: peer stats put fail",
1367 __func__);
1368 kfree_skb(vendor_event);
1369 return;
1370 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301371 if (FALSE == put_wifi_peer_info(
1372 pWifiPeerInfo, vendor_event))
1373 {
1374 hddLog(VOS_TRACE_LEVEL_ERROR,
1375 "%s: put_wifi_peer_info put fail", __func__);
1376 kfree_skb(vendor_event);
1377 return;
1378 }
1379
1380 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1381 pWifiPeerStat->peerInfo +
1382 (i * sizeof(tSirWifiPeerInfo)) +
1383 (numRate * sizeof (tSirWifiRateStat)));
1384 nla_nest_end(vendor_event, peers);
1385 }
1386 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301387 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301388 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 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301419 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1420 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301421 if (!vendor_event)
1422 {
1423 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301424 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301425 return;
1426 }
1427
1428 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1429
Dino Mycle3b9536d2014-07-09 22:05:24 +05301430
1431 if (FALSE == hdd_get_interface_info( pAdapter,
1432 &pWifiIfaceStat->info))
1433 {
1434 hddLog(VOS_TRACE_LEVEL_ERROR,
1435 FL("hdd_get_interface_info get fail") );
1436 kfree_skb(vendor_event);
1437 return;
1438 }
1439
1440 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1441 vendor_event))
1442 {
1443 hddLog(VOS_TRACE_LEVEL_ERROR,
1444 FL("put_wifi_iface_stats fail") );
1445 kfree_skb(vendor_event);
1446 return;
1447 }
1448
Sunil Duttc69bccb2014-05-26 21:30:20 +05301449 hddLog(VOS_TRACE_LEVEL_INFO,
1450 "WMI_LINK_STATS_IFACE Data");
1451
1452 hddLog(VOS_TRACE_LEVEL_INFO,
1453 "LL_STATS_IFACE: "
1454 " Mode %u "
1455 " MAC %pM "
1456 " State %u "
1457 " Roaming %u "
1458 " capabilities 0x%x "
1459 " SSID %s "
1460 " BSSID %pM",
1461 pWifiIfaceStat->info.mode,
1462 pWifiIfaceStat->info.macAddr,
1463 pWifiIfaceStat->info.state,
1464 pWifiIfaceStat->info.roaming,
1465 pWifiIfaceStat->info.capabilities,
1466 pWifiIfaceStat->info.ssid,
1467 pWifiIfaceStat->info.bssid);
1468
1469 hddLog(VOS_TRACE_LEVEL_INFO,
1470 " AP country str: %c%c%c",
1471 pWifiIfaceStat->info.apCountryStr[0],
1472 pWifiIfaceStat->info.apCountryStr[1],
1473 pWifiIfaceStat->info.apCountryStr[2]);
1474
1475
1476 hddLog(VOS_TRACE_LEVEL_INFO,
1477 " Country Str Association: %c%c%c",
1478 pWifiIfaceStat->info.countryStr[0],
1479 pWifiIfaceStat->info.countryStr[1],
1480 pWifiIfaceStat->info.countryStr[2]);
1481
1482 hddLog(VOS_TRACE_LEVEL_INFO,
1483 " beaconRx %u "
1484 " mgmtRx %u "
1485 " mgmtActionRx %u "
1486 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301487 " rssiMgmt %d "
1488 " rssiData %d "
1489 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301490 pWifiIfaceStat->beaconRx,
1491 pWifiIfaceStat->mgmtRx,
1492 pWifiIfaceStat->mgmtActionRx,
1493 pWifiIfaceStat->mgmtActionTx,
1494 pWifiIfaceStat->rssiMgmt,
1495 pWifiIfaceStat->rssiData,
1496 pWifiIfaceStat->rssiAck );
1497
1498
1499 {
1500 int i;
1501 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1502 {
1503 hddLog(VOS_TRACE_LEVEL_INFO,
1504
1505 " %d) LL_STATS IFACE: "
1506 " ac: %u txMpdu: %u "
1507 " rxMpdu: %u txMcast: %u "
1508 " rxMcast: %u rxAmpdu: %u "
1509 " txAmpdu: %u mpduLost: %u "
1510 " retries: %u retriesShort: %u "
1511 " retriesLong: %u contentionTimeMin: %u "
1512 " contentionTimeMax: %u contentionTimeAvg: %u "
1513 " contentionNumSamples: %u",
1514 i,
1515 pWifiIfaceStat->AccessclassStats[i].ac,
1516 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1517 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1518 pWifiIfaceStat->AccessclassStats[i].txMcast,
1519 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1520 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1521 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1522 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1523 pWifiIfaceStat->AccessclassStats[i].retries,
1524 pWifiIfaceStat->
1525 AccessclassStats[i].retriesShort,
1526 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1527 pWifiIfaceStat->
1528 AccessclassStats[i].contentionTimeMin,
1529 pWifiIfaceStat->
1530 AccessclassStats[i].contentionTimeMax,
1531 pWifiIfaceStat->
1532 AccessclassStats[i].contentionTimeAvg,
1533 pWifiIfaceStat->
1534 AccessclassStats[i].contentionNumSamples);
1535
1536 }
1537 }
1538
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301539 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301540
1541 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301542}
1543
1544/*
1545 * hdd_link_layer_process_radio_stats () - This function is called after
1546 * receiving Link Layer Radio statistics from FW.This function converts
1547 * the firmware data to the NL data and sends the same to the kernel/upper
1548 * layers.
1549 */
1550static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1551 v_VOID_t *pData)
1552{
1553 int status, i;
1554 tpSirWifiRadioStat pWifiRadioStat;
1555 tpSirWifiChannelStats pWifiChannelStats;
1556 struct sk_buff *vendor_event;
1557 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1558 struct nlattr *chList;
1559
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301560 ENTER();
1561
Sunil Duttc69bccb2014-05-26 21:30:20 +05301562 status = wlan_hdd_validate_context(pHddCtx);
1563 if (0 != status)
1564 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301565 return;
1566 }
1567 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1568
1569 hddLog(VOS_TRACE_LEVEL_INFO,
1570 "LL_STATS_RADIO"
1571 " radio is %d onTime is %u "
1572 " txTime is %u rxTime is %u "
1573 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301574 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301575 " onTimePnoScan is %u onTimeHs20 is %u "
1576 " numChannels is %u",
1577 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1578 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1579 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301580 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301581 pWifiRadioStat->onTimeRoamScan,
1582 pWifiRadioStat->onTimePnoScan,
1583 pWifiRadioStat->onTimeHs20,
1584 pWifiRadioStat->numChannels);
1585 /*
1586 * Allocate a size of 4096 for the Radio stats comprising
1587 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1588 * (tSirWifiChannelStats).Each channel data is put with an
1589 * NL attribute.The size of 4096 is considered assuming that
1590 * number of channels shall not exceed beyond 60 with the
1591 * sizeof (tSirWifiChannelStats) being 24 bytes.
1592 */
1593
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301594 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1595 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301596 if (!vendor_event)
1597 {
1598 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301599 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301600 return;
1601 }
1602
1603 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301604 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1605 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1606 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301607 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1608 pWifiRadioStat->radio) ||
1609 nla_put_u32(vendor_event,
1610 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1611 pWifiRadioStat->onTime) ||
1612 nla_put_u32(vendor_event,
1613 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1614 pWifiRadioStat->txTime) ||
1615 nla_put_u32(vendor_event,
1616 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1617 pWifiRadioStat->rxTime) ||
1618 nla_put_u32(vendor_event,
1619 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1620 pWifiRadioStat->onTimeScan) ||
1621 nla_put_u32(vendor_event,
1622 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1623 pWifiRadioStat->onTimeNbd) ||
1624 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301625 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1626 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301627 nla_put_u32(vendor_event,
1628 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1629 pWifiRadioStat->onTimeRoamScan) ||
1630 nla_put_u32(vendor_event,
1631 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1632 pWifiRadioStat->onTimePnoScan) ||
1633 nla_put_u32(vendor_event,
1634 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1635 pWifiRadioStat->onTimeHs20) ||
1636 nla_put_u32(vendor_event,
1637 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1638 pWifiRadioStat->numChannels))
1639 {
1640 hddLog(VOS_TRACE_LEVEL_ERROR,
1641 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1642 kfree_skb(vendor_event);
1643 return ;
1644 }
1645
1646 chList = nla_nest_start(vendor_event,
1647 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301648 if(!chList)
1649 {
1650 hddLog(VOS_TRACE_LEVEL_ERROR,
1651 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1652 __func__);
1653 kfree_skb(vendor_event);
1654 return;
1655 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301656 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1657 {
1658 struct nlattr *chInfo;
1659
1660 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1661 pWifiRadioStat->channels +
1662 (i * sizeof(tSirWifiChannelStats)));
1663
1664 hddLog(VOS_TRACE_LEVEL_INFO,
1665 " %d) Channel Info"
1666 " width is %u "
1667 " CenterFreq %u "
1668 " CenterFreq0 %u "
1669 " CenterFreq1 %u "
1670 " onTime %u "
1671 " ccaBusyTime %u",
1672 i,
1673 pWifiChannelStats->channel.width,
1674 pWifiChannelStats->channel.centerFreq,
1675 pWifiChannelStats->channel.centerFreq0,
1676 pWifiChannelStats->channel.centerFreq1,
1677 pWifiChannelStats->onTime,
1678 pWifiChannelStats->ccaBusyTime);
1679
1680
1681 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301682 if(!chInfo)
1683 {
1684 hddLog(VOS_TRACE_LEVEL_ERROR,
1685 "%s: failed to put chInfo",
1686 __func__);
1687 kfree_skb(vendor_event);
1688 return;
1689 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301690
1691 if (nla_put_u32(vendor_event,
1692 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1693 pWifiChannelStats->channel.width) ||
1694 nla_put_u32(vendor_event,
1695 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1696 pWifiChannelStats->channel.centerFreq) ||
1697 nla_put_u32(vendor_event,
1698 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1699 pWifiChannelStats->channel.centerFreq0) ||
1700 nla_put_u32(vendor_event,
1701 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1702 pWifiChannelStats->channel.centerFreq1) ||
1703 nla_put_u32(vendor_event,
1704 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1705 pWifiChannelStats->onTime) ||
1706 nla_put_u32(vendor_event,
1707 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1708 pWifiChannelStats->ccaBusyTime))
1709 {
1710 hddLog(VOS_TRACE_LEVEL_ERROR,
1711 FL("cfg80211_vendor_event_alloc failed") );
1712 kfree_skb(vendor_event);
1713 return ;
1714 }
1715 nla_nest_end(vendor_event, chInfo);
1716 }
1717 nla_nest_end(vendor_event, chList);
1718
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301719 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301720
1721 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301722 return;
1723}
1724
1725/*
1726 * hdd_link_layer_stats_ind_callback () - This function is called after
1727 * receiving Link Layer indications from FW.This callback converts the firmware
1728 * data to the NL data and send the same to the kernel/upper layers.
1729 */
1730static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1731 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301732 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301733{
Dino Mycled3d50022014-07-07 12:58:25 +05301734 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1735 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301736 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301737 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301738 int status;
1739
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301740 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301741
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301742 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301743 if (0 != status)
1744 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301745 return;
1746 }
1747
Dino Mycled3d50022014-07-07 12:58:25 +05301748 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1749 if (NULL == pAdapter)
1750 {
1751 hddLog(VOS_TRACE_LEVEL_ERROR,
1752 FL(" MAC address %pM does not exist with host"),
1753 macAddr);
1754 return;
1755 }
1756
Sunil Duttc69bccb2014-05-26 21:30:20 +05301757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301758 "%s: Interface: %s LLStats indType: %d", __func__,
1759 pAdapter->dev->name, indType);
1760
Sunil Duttc69bccb2014-05-26 21:30:20 +05301761 switch (indType)
1762 {
1763 case SIR_HAL_LL_STATS_RESULTS_RSP:
1764 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301765 hddLog(VOS_TRACE_LEVEL_INFO,
1766 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1767 hddLog(VOS_TRACE_LEVEL_INFO,
1768 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1769 linkLayerStatsResults->paramId);
1770 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301771 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1772 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301773 hddLog(VOS_TRACE_LEVEL_INFO,
1774 "LL_STATS RESULTS RESPONSE respId = %u",
1775 linkLayerStatsResults->respId);
1776 hddLog(VOS_TRACE_LEVEL_INFO,
1777 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1778 linkLayerStatsResults->moreResultToFollow);
1779 hddLog(VOS_TRACE_LEVEL_INFO,
1780 "LL_STATS RESULTS RESPONSE result = %p",
1781 linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301782 spin_lock(&hdd_context_lock);
1783 context = &pHddCtx->ll_stats_context;
1784 /* validate response received from target */
1785 if ((context->request_id != linkLayerStatsResults->respId) ||
1786 !(context->request_bitmap & linkLayerStatsResults->paramId))
1787 {
1788 spin_unlock(&hdd_context_lock);
1789 hddLog(LOGE,
1790 FL("Error : Request id %d response id %d request bitmap 0x%x"
1791 "response bitmap 0x%x"),
1792 context->request_id, linkLayerStatsResults->respId,
1793 context->request_bitmap, linkLayerStatsResults->paramId);
1794 return;
1795 }
1796 spin_unlock(&hdd_context_lock);
1797
Sunil Duttc69bccb2014-05-26 21:30:20 +05301798 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1799 {
1800 hdd_link_layer_process_radio_stats(pAdapter,
1801 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301802 spin_lock(&hdd_context_lock);
1803 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1804 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301805 }
1806 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1807 {
1808 hdd_link_layer_process_iface_stats(pAdapter,
1809 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301810 spin_lock(&hdd_context_lock);
1811 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1812 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301813 }
1814 else if ( linkLayerStatsResults->paramId &
1815 WMI_LINK_STATS_ALL_PEER )
1816 {
1817 hdd_link_layer_process_peer_stats(pAdapter,
1818 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301819 spin_lock(&hdd_context_lock);
1820 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1821 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301822 } /* WMI_LINK_STATS_ALL_PEER */
1823 else
1824 {
1825 hddLog(VOS_TRACE_LEVEL_ERROR,
1826 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1827 }
1828
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301829 spin_lock(&hdd_context_lock);
1830 /* complete response event if all requests are completed */
1831 if (0 == context->request_bitmap)
1832 complete(&context->response_event);
1833 spin_unlock(&hdd_context_lock);
1834
Sunil Duttc69bccb2014-05-26 21:30:20 +05301835 break;
1836 }
1837 default:
1838 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1839 break;
1840 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301841
1842 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301843 return;
1844}
1845
1846const struct
1847nla_policy
1848qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1849{
1850 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1851 { .type = NLA_U32 },
1852 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1853 { .type = NLA_U32 },
1854};
1855
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301856static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1857 struct wireless_dev *wdev,
1858 const void *data,
1859 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301860{
1861 int status;
1862 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301863 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301864 struct net_device *dev = wdev->netdev;
1865 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1866 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1867
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301868 ENTER();
1869
Sunil Duttc69bccb2014-05-26 21:30:20 +05301870 status = wlan_hdd_validate_context(pHddCtx);
1871 if (0 != status)
1872 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301873 return -EINVAL;
1874 }
1875
1876 if (NULL == pAdapter)
1877 {
1878 hddLog(VOS_TRACE_LEVEL_ERROR,
1879 FL("HDD adapter is Null"));
1880 return -ENODEV;
1881 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301882 /* check the LLStats Capability */
1883 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1884 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1885 {
1886 hddLog(VOS_TRACE_LEVEL_ERROR,
1887 FL("Link Layer Statistics not supported by Firmware"));
1888 return -EINVAL;
1889 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301890
1891 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1892 (struct nlattr *)data,
1893 data_len, qca_wlan_vendor_ll_set_policy))
1894 {
1895 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1896 return -EINVAL;
1897 }
1898 if (!tb_vendor
1899 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1900 {
1901 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1902 return -EINVAL;
1903 }
1904 if (!tb_vendor[
1905 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1906 {
1907 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1908 return -EINVAL;
1909 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301910 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301911 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301912
Dino Mycledf0a5d92014-07-04 09:41:55 +05301913 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301914 nla_get_u32(
1915 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1916
Dino Mycledf0a5d92014-07-04 09:41:55 +05301917 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301918 nla_get_u32(
1919 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1920
Dino Mycled3d50022014-07-07 12:58:25 +05301921 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1922 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301923
1924
1925 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301926 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301927 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301928 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301929 hddLog(VOS_TRACE_LEVEL_INFO,
1930 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301931 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301932 hddLog(VOS_TRACE_LEVEL_INFO,
1933 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301934 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301935
1936 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1937 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301938 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301939 {
1940 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1941 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301942 return -EINVAL;
1943
1944 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301945
Sunil Duttc69bccb2014-05-26 21:30:20 +05301946 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301947 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301948 {
1949 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1950 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301951 return -EINVAL;
1952 }
1953
1954 pAdapter->isLinkLayerStatsSet = 1;
1955
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301956 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301957 return 0;
1958}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301959static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1960 struct wireless_dev *wdev,
1961 const void *data,
1962 int data_len)
1963{
1964 int ret = 0;
1965
1966 vos_ssr_protect(__func__);
1967 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1968 vos_ssr_unprotect(__func__);
1969
1970 return ret;
1971}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301972
1973const struct
1974nla_policy
1975qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1976{
1977 /* Unsigned 32bit value provided by the caller issuing the GET stats
1978 * command. When reporting
1979 * the stats results, the driver uses the same value to indicate
1980 * which GET request the results
1981 * correspond to.
1982 */
1983 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1984
1985 /* Unsigned 32bit value . bit mask to identify what statistics are
1986 requested for retrieval */
1987 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1988};
1989
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301990static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1991 struct wireless_dev *wdev,
1992 const void *data,
1993 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301994{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301995 unsigned long rc;
1996 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301997 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1998 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301999 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302000 struct net_device *dev = wdev->netdev;
2001 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302002 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302003 int status;
2004
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302005 ENTER();
2006
Sunil Duttc69bccb2014-05-26 21:30:20 +05302007 status = wlan_hdd_validate_context(pHddCtx);
2008 if (0 != status)
2009 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302010 return -EINVAL ;
2011 }
2012
2013 if (NULL == pAdapter)
2014 {
2015 hddLog(VOS_TRACE_LEVEL_FATAL,
2016 "%s: HDD adapter is Null", __func__);
2017 return -ENODEV;
2018 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302019
2020 if (pHddStaCtx == NULL)
2021 {
2022 hddLog(VOS_TRACE_LEVEL_FATAL,
2023 "%s: HddStaCtx is Null", __func__);
2024 return -ENODEV;
2025 }
2026
Dino Mycledf0a5d92014-07-04 09:41:55 +05302027 /* check the LLStats Capability */
2028 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2029 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2030 {
2031 hddLog(VOS_TRACE_LEVEL_ERROR,
2032 FL("Link Layer Statistics not supported by Firmware"));
2033 return -EINVAL;
2034 }
2035
Sunil Duttc69bccb2014-05-26 21:30:20 +05302036
2037 if (!pAdapter->isLinkLayerStatsSet)
2038 {
2039 hddLog(VOS_TRACE_LEVEL_FATAL,
2040 "%s: isLinkLayerStatsSet : %d",
2041 __func__, pAdapter->isLinkLayerStatsSet);
2042 return -EINVAL;
2043 }
2044
Mukul Sharma10313ba2015-07-29 19:14:39 +05302045 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2046 {
2047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2048 "%s: Roaming in progress, so unable to proceed this request", __func__);
2049 return -EBUSY;
2050 }
2051
Sunil Duttc69bccb2014-05-26 21:30:20 +05302052 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2053 (struct nlattr *)data,
2054 data_len, qca_wlan_vendor_ll_get_policy))
2055 {
2056 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2057 return -EINVAL;
2058 }
2059
2060 if (!tb_vendor
2061 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2062 {
2063 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2064 return -EINVAL;
2065 }
2066
2067 if (!tb_vendor
2068 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2069 {
2070 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2071 return -EINVAL;
2072 }
2073
Sunil Duttc69bccb2014-05-26 21:30:20 +05302074
Dino Mycledf0a5d92014-07-04 09:41:55 +05302075 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302076 nla_get_u32( tb_vendor[
2077 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302078 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302079 nla_get_u32( tb_vendor[
2080 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2081
Dino Mycled3d50022014-07-07 12:58:25 +05302082 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2083 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302084
2085 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302086 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302087 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302088 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302089 hddLog(VOS_TRACE_LEVEL_INFO,
2090 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302091 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302092
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302093 spin_lock(&hdd_context_lock);
2094 context = &pHddCtx->ll_stats_context;
2095 context->request_id = linkLayerStatsGetReq.reqId;
2096 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
2097 INIT_COMPLETION(context->response_event);
2098 spin_unlock(&hdd_context_lock);
2099
Sunil Duttc69bccb2014-05-26 21:30:20 +05302100 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302101 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302102 {
2103 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2104 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302105 return -EINVAL;
2106 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302107
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302108 rc = wait_for_completion_timeout(&context->response_event,
2109 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
2110 if (!rc)
2111 {
2112 hddLog(LOGE,
2113 FL("Target response timed out request id %d request bitmap 0x%x"),
2114 context->request_id, context->request_bitmap);
2115 return -ETIMEDOUT;
2116 }
2117
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302118 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302119 return 0;
2120}
2121
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302122static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2123 struct wireless_dev *wdev,
2124 const void *data,
2125 int data_len)
2126{
2127 int ret = 0;
2128
2129 vos_ssr_protect(__func__);
2130 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
2131 vos_ssr_unprotect(__func__);
2132
2133 return ret;
2134}
2135
Sunil Duttc69bccb2014-05-26 21:30:20 +05302136const struct
2137nla_policy
2138qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2139{
2140 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2141 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2142 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2143 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2144};
2145
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302146static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2147 struct wireless_dev *wdev,
2148 const void *data,
2149 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302150{
2151 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2152 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302153 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302154 struct net_device *dev = wdev->netdev;
2155 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2156 u32 statsClearReqMask;
2157 u8 stopReq;
2158 int status;
2159
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302160 ENTER();
2161
Sunil Duttc69bccb2014-05-26 21:30:20 +05302162 status = wlan_hdd_validate_context(pHddCtx);
2163 if (0 != status)
2164 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302165 return -EINVAL;
2166 }
2167
2168 if (NULL == pAdapter)
2169 {
2170 hddLog(VOS_TRACE_LEVEL_FATAL,
2171 "%s: HDD adapter is Null", __func__);
2172 return -ENODEV;
2173 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302174 /* check the LLStats Capability */
2175 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2176 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2177 {
2178 hddLog(VOS_TRACE_LEVEL_ERROR,
2179 FL("Enable LLStats Capability"));
2180 return -EINVAL;
2181 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302182
2183 if (!pAdapter->isLinkLayerStatsSet)
2184 {
2185 hddLog(VOS_TRACE_LEVEL_FATAL,
2186 "%s: isLinkLayerStatsSet : %d",
2187 __func__, pAdapter->isLinkLayerStatsSet);
2188 return -EINVAL;
2189 }
2190
2191 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2192 (struct nlattr *)data,
2193 data_len, qca_wlan_vendor_ll_clr_policy))
2194 {
2195 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2196 return -EINVAL;
2197 }
2198
2199 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2200
2201 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2202 {
2203 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2204 return -EINVAL;
2205
2206 }
2207
Sunil Duttc69bccb2014-05-26 21:30:20 +05302208
Dino Mycledf0a5d92014-07-04 09:41:55 +05302209 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302210 nla_get_u32(
2211 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2212
Dino Mycledf0a5d92014-07-04 09:41:55 +05302213 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302214 nla_get_u8(
2215 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2216
2217 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302218 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302219
Dino Mycled3d50022014-07-07 12:58:25 +05302220 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2221 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302222
2223 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302224 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302225 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302226 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302227 hddLog(VOS_TRACE_LEVEL_INFO,
2228 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302229 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302230 hddLog(VOS_TRACE_LEVEL_INFO,
2231 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302232 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302233
2234 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302235 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302236 {
2237 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302238 hdd_station_ctx_t *pHddStaCtx;
2239
2240 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2241 if (VOS_STATUS_SUCCESS !=
2242 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2243 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2244 {
2245 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2246 "WLANTL_ClearInterfaceStats Failed", __func__);
2247 return -EINVAL;
2248 }
2249 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2250 (statsClearReqMask & WIFI_STATS_IFACE)) {
2251 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2252 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2253 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2254 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2255 }
2256
Sunil Duttc69bccb2014-05-26 21:30:20 +05302257 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2258 2 * sizeof(u32) +
2259 NLMSG_HDRLEN);
2260
2261 if (temp_skbuff != NULL)
2262 {
2263
2264 if (nla_put_u32(temp_skbuff,
2265 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2266 statsClearReqMask) ||
2267 nla_put_u32(temp_skbuff,
2268 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2269 stopReq))
2270 {
2271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2272 kfree_skb(temp_skbuff);
2273 return -EINVAL;
2274 }
2275 /* If the ask is to stop the stats collection as part of clear
2276 * (stopReq = 1) , ensure that no further requests of get
2277 * go to the firmware by having isLinkLayerStatsSet set to 0.
2278 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302279 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302280 * case the firmware is just asked to clear the statistics.
2281 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302282 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302283 pAdapter->isLinkLayerStatsSet = 0;
2284 return cfg80211_vendor_cmd_reply(temp_skbuff);
2285 }
2286 return -ENOMEM;
2287 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302288
2289 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302290 return -EINVAL;
2291}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302292static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2293 struct wireless_dev *wdev,
2294 const void *data,
2295 int data_len)
2296{
2297 int ret = 0;
2298
2299 vos_ssr_protect(__func__);
2300 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2301 vos_ssr_unprotect(__func__);
2302
2303 return ret;
2304
2305
2306}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302307#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2308
Dino Mycle6fb96c12014-06-10 11:52:40 +05302309#ifdef WLAN_FEATURE_EXTSCAN
2310static const struct nla_policy
2311wlan_hdd_extscan_config_policy
2312 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2313{
2314 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2315 { .type = NLA_U32 },
2316 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2317 { .type = NLA_U32 },
2318 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2319 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2320 { .type = NLA_U32 },
2321 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2322 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2323
2324 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2325 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2326 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2327 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2328 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302329 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2330 { .type = NLA_U32 },
2331 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2332 { .type = NLA_U32 },
2333 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2334 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302335 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2336 { .type = NLA_U32 },
2337 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2338 { .type = NLA_U32 },
2339 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2340 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302341 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2342 { .type = NLA_U8 },
2343 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302344 { .type = NLA_U8 },
2345 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2346 { .type = NLA_U8 },
2347 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2348 { .type = NLA_U8 },
2349
2350 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2351 { .type = NLA_U32 },
2352 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2353 { .type = NLA_UNSPEC },
2354 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2355 { .type = NLA_S32 },
2356 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2357 { .type = NLA_S32 },
2358 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2359 { .type = NLA_U32 },
2360 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2361 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302362 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2363 { .type = NLA_U32 },
2364 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2365 { .type = NLA_BINARY,
2366 .len = IEEE80211_MAX_SSID_LEN + 1 },
2367 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302368 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302369 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2370 { .type = NLA_U32 },
2371 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2372 { .type = NLA_U8 },
2373 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2374 { .type = NLA_S32 },
2375 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2376 { .type = NLA_S32 },
2377 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2378 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302379};
2380
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302381/**
2382 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2383 * @ctx: hdd global context
2384 * @data: capabilities data
2385 *
2386 * Return: none
2387 */
2388static void
2389wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302390{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302391 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302392 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302393 tSirEXTScanCapabilitiesEvent *data =
2394 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302395
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302396 ENTER();
2397
2398 if (wlan_hdd_validate_context(pHddCtx))
2399 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302400 return;
2401 }
2402
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302403 if (!pMsg)
2404 {
2405 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2406 return;
2407 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302408
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302409 vos_spin_lock_acquire(&hdd_context_lock);
2410
2411 context = &pHddCtx->ext_scan_context;
2412 /* validate response received from target*/
2413 if (context->request_id != data->requestId)
2414 {
2415 vos_spin_lock_release(&hdd_context_lock);
2416 hddLog(LOGE,
2417 FL("Target response id did not match: request_id %d resposne_id %d"),
2418 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302419 return;
2420 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302421 else
2422 {
2423 context->capability_response = *data;
2424 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302425 }
2426
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302427 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302428
Dino Mycle6fb96c12014-06-10 11:52:40 +05302429 return;
2430}
2431
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302432/*
2433 * define short names for the global vendor params
2434 * used by wlan_hdd_send_ext_scan_capability()
2435 */
2436#define PARAM_REQUEST_ID \
2437 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2438#define PARAM_STATUS \
2439 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2440#define MAX_SCAN_CACHE_SIZE \
2441 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2442#define MAX_SCAN_BUCKETS \
2443 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2444#define MAX_AP_CACHE_PER_SCAN \
2445 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2446#define MAX_RSSI_SAMPLE_SIZE \
2447 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2448#define MAX_SCAN_RPT_THRHOLD \
2449 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2450#define MAX_HOTLIST_BSSIDS \
2451 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2452#define MAX_BSSID_HISTORY_ENTRIES \
2453 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2454#define MAX_HOTLIST_SSIDS \
2455 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302456#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2457 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302458
2459static int wlan_hdd_send_ext_scan_capability(void *ctx)
2460{
2461 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2462 struct sk_buff *skb = NULL;
2463 int ret;
2464 tSirEXTScanCapabilitiesEvent *data;
2465 tANI_U32 nl_buf_len;
2466
2467 ret = wlan_hdd_validate_context(pHddCtx);
2468 if (0 != ret)
2469 {
2470 return ret;
2471 }
2472
2473 data = &(pHddCtx->ext_scan_context.capability_response);
2474
2475 nl_buf_len = NLMSG_HDRLEN;
2476 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2477 (sizeof(data->status) + NLA_HDRLEN) +
2478 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2479 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2480 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2481 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2482 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2483 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2484 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2485 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2486
2487 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2488
2489 if (!skb)
2490 {
2491 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2492 return -ENOMEM;
2493 }
2494
2495 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2496 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2497 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2498 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2499 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2500 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2501 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2502 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2503
2504 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2505 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2506 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2507 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2508 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2509 data->maxApPerScan) ||
2510 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2511 data->maxRssiSampleSize) ||
2512 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2513 data->maxScanReportingThreshold) ||
2514 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2515 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2516 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302517 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2518 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302519 {
2520 hddLog(LOGE, FL("nla put fail"));
2521 goto nla_put_failure;
2522 }
2523
2524 cfg80211_vendor_cmd_reply(skb);
2525 return 0;
2526
2527nla_put_failure:
2528 kfree_skb(skb);
2529 return -EINVAL;;
2530}
2531
2532/*
2533 * done with short names for the global vendor params
2534 * used by wlan_hdd_send_ext_scan_capability()
2535 */
2536#undef PARAM_REQUEST_ID
2537#undef PARAM_STATUS
2538#undef MAX_SCAN_CACHE_SIZE
2539#undef MAX_SCAN_BUCKETS
2540#undef MAX_AP_CACHE_PER_SCAN
2541#undef MAX_RSSI_SAMPLE_SIZE
2542#undef MAX_SCAN_RPT_THRHOLD
2543#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302544#undef MAX_BSSID_HISTORY_ENTRIES
2545#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302546
2547static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2548{
2549 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2550 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302551 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302552 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302553
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302554 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302555
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302556 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302557 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302558
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302559 if (!pMsg)
2560 {
2561 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302562 return;
2563 }
2564
Dino Mycle6fb96c12014-06-10 11:52:40 +05302565 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2566 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2567
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302568 context = &pHddCtx->ext_scan_context;
2569 spin_lock(&hdd_context_lock);
2570 if (context->request_id == pData->requestId) {
2571 context->response_status = pData->status ? -EINVAL : 0;
2572 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302573 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302574 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302575
2576 /*
2577 * Store the Request ID for comparing with the requestID obtained
2578 * in other requests.HDD shall return a failure is the extscan_stop
2579 * request is issued with a different requestId as that of the
2580 * extscan_start request. Also, This requestId shall be used while
2581 * indicating the full scan results to the upper layers.
2582 * The requestId is stored with the assumption that the firmware
2583 * shall return the ext scan start request's requestId in ext scan
2584 * start response.
2585 */
2586 if (pData->status == 0)
2587 pMac->sme.extScanStartReqId = pData->requestId;
2588
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302589 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302590 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302591}
2592
2593
2594static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2595{
2596 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2597 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302598 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302599
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302600 ENTER();
2601
2602 if (wlan_hdd_validate_context(pHddCtx)){
2603 return;
2604 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302605
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302606 if (!pMsg)
2607 {
2608 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302609 return;
2610 }
2611
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302612 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2613 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302614
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302615 context = &pHddCtx->ext_scan_context;
2616 spin_lock(&hdd_context_lock);
2617 if (context->request_id == pData->requestId) {
2618 context->response_status = pData->status ? -EINVAL : 0;
2619 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302620 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302621 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302622
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302623 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302624 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302625}
2626
Dino Mycle6fb96c12014-06-10 11:52:40 +05302627static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2628 void *pMsg)
2629{
2630 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302631 tpSirEXTScanSetBssidHotListRspParams pData =
2632 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302633 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302634
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302635 ENTER();
2636
2637 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302638 return;
2639 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302640
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302641 if (!pMsg)
2642 {
2643 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2644 return;
2645 }
2646
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302647 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2648 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302649
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302650 context = &pHddCtx->ext_scan_context;
2651 spin_lock(&hdd_context_lock);
2652 if (context->request_id == pData->requestId) {
2653 context->response_status = pData->status ? -EINVAL : 0;
2654 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302655 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302656 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302657
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302658 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302659 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302660}
2661
2662static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2663 void *pMsg)
2664{
2665 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2666 struct sk_buff *skb = NULL;
2667 tpSirEXTScanResetBssidHotlistRspParams pData =
2668 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2669
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302670 ENTER();
2671
2672 if (wlan_hdd_validate_context(pHddCtx)) {
2673 return;
2674 }
2675 if (!pMsg)
2676 {
2677 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302678 return;
2679 }
2680
2681 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302682#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2683 NULL,
2684#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302685 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2686 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2687 GFP_KERNEL);
2688
2689 if (!skb) {
2690 hddLog(VOS_TRACE_LEVEL_ERROR,
2691 FL("cfg80211_vendor_event_alloc failed"));
2692 return;
2693 }
2694 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2695 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2696
2697 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2698 pData->requestId) ||
2699 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2700 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2701 goto nla_put_failure;
2702 }
2703
2704 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302705 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302706 return;
2707
2708nla_put_failure:
2709 kfree_skb(skb);
2710 return;
2711}
2712
Dino Mycle6fb96c12014-06-10 11:52:40 +05302713static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2714 void *pMsg)
2715{
2716 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2717 struct sk_buff *skb = NULL;
2718 tANI_U32 i = 0, j, resultsPerEvent;
2719 tANI_S32 totalResults;
2720 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2721 tpSirWifiScanResult pSirWifiScanResult;
2722
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302723 ENTER();
2724
2725 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302726 return;
2727 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302728 if (!pMsg)
2729 {
2730 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2731 return;
2732 }
2733
Dino Mycle6fb96c12014-06-10 11:52:40 +05302734 totalResults = pData->numOfAps;
2735 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2736 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2737 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2738
2739 do{
2740 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2741 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2742 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2743
2744 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302745#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2746 NULL,
2747#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302748 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2749 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2750 GFP_KERNEL);
2751
2752 if (!skb) {
2753 hddLog(VOS_TRACE_LEVEL_ERROR,
2754 FL("cfg80211_vendor_event_alloc failed"));
2755 return;
2756 }
2757
2758 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2759
2760 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2761 pData->requestId) ||
2762 nla_put_u32(skb,
2763 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2764 resultsPerEvent)) {
2765 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2766 goto fail;
2767 }
2768 if (nla_put_u8(skb,
2769 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2770 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2771 {
2772 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2773 goto fail;
2774 }
2775
2776 if (resultsPerEvent) {
2777 struct nlattr *aps;
2778
2779 aps = nla_nest_start(skb,
2780 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2781 if (!aps)
2782 {
2783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2784 goto fail;
2785 }
2786
2787 for (j = 0; j < resultsPerEvent; j++, i++) {
2788 struct nlattr *ap;
2789 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2790 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2791
2792 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2793 "Ssid (%s)"
2794 "Bssid: %pM "
2795 "Channel (%u)"
2796 "Rssi (%d)"
2797 "RTT (%u)"
2798 "RTT_SD (%u)",
2799 i,
2800 pSirWifiScanResult->ts,
2801 pSirWifiScanResult->ssid,
2802 pSirWifiScanResult->bssid,
2803 pSirWifiScanResult->channel,
2804 pSirWifiScanResult->rssi,
2805 pSirWifiScanResult->rtt,
2806 pSirWifiScanResult->rtt_sd);
2807
2808 ap = nla_nest_start(skb, j + 1);
2809 if (!ap)
2810 {
2811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2812 goto fail;
2813 }
2814
2815 if (nla_put_u64(skb,
2816 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2817 pSirWifiScanResult->ts) )
2818 {
2819 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2820 goto fail;
2821 }
2822 if (nla_put(skb,
2823 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2824 sizeof(pSirWifiScanResult->ssid),
2825 pSirWifiScanResult->ssid) )
2826 {
2827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2828 goto fail;
2829 }
2830 if (nla_put(skb,
2831 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2832 sizeof(pSirWifiScanResult->bssid),
2833 pSirWifiScanResult->bssid) )
2834 {
2835 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2836 goto fail;
2837 }
2838 if (nla_put_u32(skb,
2839 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2840 pSirWifiScanResult->channel) )
2841 {
2842 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2843 goto fail;
2844 }
Dasari Srinivas90747d72014-10-08 12:16:15 +05302845 if (nla_put_s32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302846 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2847 pSirWifiScanResult->rssi) )
2848 {
2849 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2850 goto fail;
2851 }
2852 if (nla_put_u32(skb,
2853 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2854 pSirWifiScanResult->rtt) )
2855 {
2856 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2857 goto fail;
2858 }
2859 if (nla_put_u32(skb,
2860 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2861 pSirWifiScanResult->rtt_sd))
2862 {
2863 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2864 goto fail;
2865 }
2866
2867 nla_nest_end(skb, ap);
2868 }
2869 nla_nest_end(skb, aps);
2870
2871 }
2872 cfg80211_vendor_event(skb, GFP_KERNEL);
2873 } while (totalResults > 0);
2874
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302875 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302876 return;
2877fail:
2878 kfree_skb(skb);
2879 return;
2880}
2881
2882static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2883 void *pMsg)
2884{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302885 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302886 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2887 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302888 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302889
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302890 ENTER();
2891
2892 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302893 hddLog(LOGE,
2894 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302895 return;
2896 }
2897 if (!pMsg)
2898 {
2899 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302900 return;
2901 }
2902
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302903 if (pData->bss_found)
2904 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2905 else
2906 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2907
Dino Mycle6fb96c12014-06-10 11:52:40 +05302908 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302909#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2910 NULL,
2911#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302912 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302913 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302914
2915 if (!skb) {
2916 hddLog(VOS_TRACE_LEVEL_ERROR,
2917 FL("cfg80211_vendor_event_alloc failed"));
2918 return;
2919 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302920
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302921 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2922 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2923 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2924 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2925
2926 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302927 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2928 "Ssid (%s) "
2929 "Bssid (" MAC_ADDRESS_STR ") "
2930 "Channel (%u) "
2931 "Rssi (%d) "
2932 "RTT (%u) "
2933 "RTT_SD (%u) ",
2934 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302935 pData->bssHotlist[i].ts,
2936 pData->bssHotlist[i].ssid,
2937 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2938 pData->bssHotlist[i].channel,
2939 pData->bssHotlist[i].rssi,
2940 pData->bssHotlist[i].rtt,
2941 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302942 }
2943
2944 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2945 pData->requestId) ||
2946 nla_put_u32(skb,
2947 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302948 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302949 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2950 goto fail;
2951 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302952 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302953 struct nlattr *aps;
2954
2955 aps = nla_nest_start(skb,
2956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2957 if (!aps)
2958 goto fail;
2959
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302960 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302961 struct nlattr *ap;
2962
2963 ap = nla_nest_start(skb, i + 1);
2964 if (!ap)
2965 goto fail;
2966
2967 if (nla_put_u64(skb,
2968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302969 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302970 nla_put(skb,
2971 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302972 sizeof(pData->bssHotlist[i].ssid),
2973 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302974 nla_put(skb,
2975 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302976 sizeof(pData->bssHotlist[i].bssid),
2977 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302978 nla_put_u32(skb,
2979 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302980 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302981 nla_put_s32(skb,
2982 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302983 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302984 nla_put_u32(skb,
2985 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302986 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302987 nla_put_u32(skb,
2988 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302989 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302990 goto fail;
2991
2992 nla_nest_end(skb, ap);
2993 }
2994 nla_nest_end(skb, aps);
2995
2996 if (nla_put_u8(skb,
2997 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2998 pData->moreData))
2999 goto fail;
3000 }
3001
3002 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303003 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303004 return;
3005
3006fail:
3007 kfree_skb(skb);
3008 return;
3009
3010}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303011
3012static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3013 void *pMsg)
3014{
3015 struct sk_buff *skb;
3016 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3017 tpSirWifiFullScanResultEvent pData =
3018 (tpSirWifiFullScanResultEvent) (pMsg);
3019
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303020 ENTER();
3021
3022 if (wlan_hdd_validate_context(pHddCtx)) {
3023 return;
3024 }
3025 if (!pMsg)
3026 {
3027 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303028 return;
3029 }
3030
3031 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303032#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3033 NULL,
3034#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303035 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3036 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3037 GFP_KERNEL);
3038
3039 if (!skb) {
3040 hddLog(VOS_TRACE_LEVEL_ERROR,
3041 FL("cfg80211_vendor_event_alloc failed"));
3042 return;
3043 }
3044
3045 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3046 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3047 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3048 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3049 "Ssid (%s)"
3050 "Bssid (" MAC_ADDRESS_STR ")"
3051 "Channel (%u)"
3052 "Rssi (%d)"
3053 "RTT (%u)"
3054 "RTT_SD (%u)"),
3055 pData->ap.ts,
3056 pData->ap.ssid,
3057 MAC_ADDR_ARRAY(pData->ap.bssid),
3058 pData->ap.channel,
3059 pData->ap.rssi,
3060 pData->ap.rtt,
3061 pData->ap.rtt_sd);
3062 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3063 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3064 pData->requestId) ||
3065 nla_put_u64(skb,
3066 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3067 pData->ap.ts) ||
3068 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3069 sizeof(pData->ap.ssid),
3070 pData->ap.ssid) ||
3071 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3072 WNI_CFG_BSSID_LEN,
3073 pData->ap.bssid) ||
3074 nla_put_u32(skb,
3075 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3076 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303077 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303078 pData->ap.rssi) ||
3079 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3080 pData->ap.rtt) ||
3081 nla_put_u32(skb,
3082 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3083 pData->ap.rtt_sd) ||
3084 nla_put_u16(skb,
3085 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3086 pData->ap.beaconPeriod) ||
3087 nla_put_u16(skb,
3088 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3089 pData->ap.capability) ||
3090 nla_put_u32(skb,
3091 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3092 pData->ieLength))
3093 {
3094 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3095 goto nla_put_failure;
3096 }
3097 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3098 pData->ieLength,
3099 pData->ie))
3100 {
3101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3102 goto nla_put_failure;
3103 }
3104
3105 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303106 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303107 return;
3108
3109nla_put_failure:
3110 kfree_skb(skb);
3111 return;
3112}
3113
3114static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3115 void *pMsg)
3116{
3117 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3118 struct sk_buff *skb = NULL;
3119 tpSirEXTScanResultsAvailableIndParams pData =
3120 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3121
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303122 ENTER();
3123
3124 if (wlan_hdd_validate_context(pHddCtx)){
3125 return;
3126 }
3127 if (!pMsg)
3128 {
3129 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303130 return;
3131 }
3132
3133 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303134#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3135 NULL,
3136#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303137 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3138 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3139 GFP_KERNEL);
3140
3141 if (!skb) {
3142 hddLog(VOS_TRACE_LEVEL_ERROR,
3143 FL("cfg80211_vendor_event_alloc failed"));
3144 return;
3145 }
3146
3147 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3148 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3149 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3150 pData->numResultsAvailable);
3151 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3152 pData->requestId) ||
3153 nla_put_u32(skb,
3154 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3155 pData->numResultsAvailable)) {
3156 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3157 goto nla_put_failure;
3158 }
3159
3160 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303161 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303162 return;
3163
3164nla_put_failure:
3165 kfree_skb(skb);
3166 return;
3167}
3168
3169static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3170{
3171 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3172 struct sk_buff *skb = NULL;
3173 tpSirEXTScanProgressIndParams pData =
3174 (tpSirEXTScanProgressIndParams) pMsg;
3175
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303176 ENTER();
3177
3178 if (wlan_hdd_validate_context(pHddCtx)){
3179 return;
3180 }
3181 if (!pMsg)
3182 {
3183 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303184 return;
3185 }
3186
3187 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303188#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3189 NULL,
3190#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303191 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3192 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3193 GFP_KERNEL);
3194
3195 if (!skb) {
3196 hddLog(VOS_TRACE_LEVEL_ERROR,
3197 FL("cfg80211_vendor_event_alloc failed"));
3198 return;
3199 }
3200 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3201 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3202 pData->extScanEventType);
3203 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3204 pData->status);
3205
3206 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3207 pData->extScanEventType) ||
3208 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303209 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3210 pData->requestId) ||
3211 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303212 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3213 pData->status)) {
3214 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3215 goto nla_put_failure;
3216 }
3217
3218 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303219 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303220 return;
3221
3222nla_put_failure:
3223 kfree_skb(skb);
3224 return;
3225}
3226
3227void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3228 void *pMsg)
3229{
3230 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3231
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303232 ENTER();
3233
Dino Mycle6fb96c12014-06-10 11:52:40 +05303234 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303235 return;
3236 }
3237
3238 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3239
3240
3241 switch(evType) {
3242 case SIR_HAL_EXTSCAN_START_RSP:
3243 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3244 break;
3245
3246 case SIR_HAL_EXTSCAN_STOP_RSP:
3247 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3248 break;
3249 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3250 /* There is no need to send this response to upper layer
3251 Just log the message */
3252 hddLog(VOS_TRACE_LEVEL_INFO,
3253 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3254 break;
3255 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3256 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3257 break;
3258
3259 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3260 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3261 break;
3262
Dino Mycle6fb96c12014-06-10 11:52:40 +05303263 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303264 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303265 break;
3266 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3267 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3268 break;
3269 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3270 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3271 break;
3272 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3273 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3274 break;
3275 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3276 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3277 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303278 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3279 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3280 break;
3281 default:
3282 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3283 break;
3284 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303285 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303286}
3287
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303288static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3289 struct wireless_dev *wdev,
3290 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303291{
Dino Myclee8843b32014-07-04 14:21:45 +05303292 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303293 struct net_device *dev = wdev->netdev;
3294 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3295 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3296 struct nlattr
3297 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3298 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303299 struct hdd_ext_scan_context *context;
3300 unsigned long rc;
3301 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303302
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303303 ENTER();
3304
Dino Mycle6fb96c12014-06-10 11:52:40 +05303305 status = wlan_hdd_validate_context(pHddCtx);
3306 if (0 != status)
3307 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303308 return -EINVAL;
3309 }
Dino Myclee8843b32014-07-04 14:21:45 +05303310 /* check the EXTScan Capability */
3311 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3312 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3313 {
3314 hddLog(VOS_TRACE_LEVEL_ERROR,
3315 FL("EXTScan not enabled/supported by Firmware"));
3316 return -EINVAL;
3317 }
3318
Dino Mycle6fb96c12014-06-10 11:52:40 +05303319 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3320 data, dataLen,
3321 wlan_hdd_extscan_config_policy)) {
3322 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3323 return -EINVAL;
3324 }
3325
3326 /* Parse and fetch request Id */
3327 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3328 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3329 return -EINVAL;
3330 }
3331
Dino Myclee8843b32014-07-04 14:21:45 +05303332 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303333 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303334 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303335
Dino Myclee8843b32014-07-04 14:21:45 +05303336 reqMsg.sessionId = pAdapter->sessionId;
3337 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303338
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303339 vos_spin_lock_acquire(&hdd_context_lock);
3340 context = &pHddCtx->ext_scan_context;
3341 context->request_id = reqMsg.requestId;
3342 INIT_COMPLETION(context->response_event);
3343 vos_spin_lock_release(&hdd_context_lock);
3344
Dino Myclee8843b32014-07-04 14:21:45 +05303345 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303346 if (!HAL_STATUS_SUCCESS(status)) {
3347 hddLog(VOS_TRACE_LEVEL_ERROR,
3348 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303349 return -EINVAL;
3350 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303351
3352 rc = wait_for_completion_timeout(&context->response_event,
3353 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3354 if (!rc) {
3355 hddLog(LOGE, FL("Target response timed out"));
3356 return -ETIMEDOUT;
3357 }
3358
3359 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3360 if (ret)
3361 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3362
3363 return ret;
3364
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303365 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303366 return 0;
3367}
3368
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303369static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3370 struct wireless_dev *wdev,
3371 const void *data, int dataLen)
3372{
3373 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303374
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303375 vos_ssr_protect(__func__);
3376 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3377 vos_ssr_unprotect(__func__);
3378
3379 return ret;
3380}
3381
3382static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3383 struct wireless_dev *wdev,
3384 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303385{
Dino Myclee8843b32014-07-04 14:21:45 +05303386 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303387 struct net_device *dev = wdev->netdev;
3388 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3389 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3390 struct nlattr
3391 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3392 eHalStatus status;
3393
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303394 ENTER();
3395
Dino Mycle6fb96c12014-06-10 11:52:40 +05303396 status = wlan_hdd_validate_context(pHddCtx);
3397 if (0 != status)
3398 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303399 return -EINVAL;
3400 }
Dino Myclee8843b32014-07-04 14:21:45 +05303401 /* check the EXTScan Capability */
3402 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3403 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3404 {
3405 hddLog(VOS_TRACE_LEVEL_ERROR,
3406 FL("EXTScan not enabled/supported by Firmware"));
3407 return -EINVAL;
3408 }
3409
Dino Mycle6fb96c12014-06-10 11:52:40 +05303410 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3411 data, dataLen,
3412 wlan_hdd_extscan_config_policy)) {
3413 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3414 return -EINVAL;
3415 }
3416 /* Parse and fetch request Id */
3417 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3418 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3419 return -EINVAL;
3420 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303421
Dino Myclee8843b32014-07-04 14:21:45 +05303422 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303423 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3424
Dino Myclee8843b32014-07-04 14:21:45 +05303425 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303426
Dino Myclee8843b32014-07-04 14:21:45 +05303427 reqMsg.sessionId = pAdapter->sessionId;
3428 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303429
3430 /* Parse and fetch flush parameter */
3431 if (!tb
3432 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3433 {
3434 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3435 goto failed;
3436 }
Dino Myclee8843b32014-07-04 14:21:45 +05303437 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303438 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3439
Dino Myclee8843b32014-07-04 14:21:45 +05303440 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303441
Dino Myclee8843b32014-07-04 14:21:45 +05303442 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303443 if (!HAL_STATUS_SUCCESS(status)) {
3444 hddLog(VOS_TRACE_LEVEL_ERROR,
3445 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303446 return -EINVAL;
3447 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303448 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303449 return 0;
3450
3451failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303452 return -EINVAL;
3453}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303454static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3455 struct wireless_dev *wdev,
3456 const void *data, int dataLen)
3457{
3458 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303459
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303460 vos_ssr_protect(__func__);
3461 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3462 vos_ssr_unprotect(__func__);
3463
3464 return ret;
3465}
3466
3467static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303468 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303469 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303470{
3471 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3472 struct net_device *dev = wdev->netdev;
3473 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3474 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3475 struct nlattr
3476 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3477 struct nlattr
3478 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3479 struct nlattr *apTh;
3480 eHalStatus status;
3481 tANI_U8 i = 0;
3482 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303483 struct hdd_ext_scan_context *context;
3484 tANI_U32 request_id;
3485 unsigned long rc;
3486 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303487
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303488 ENTER();
3489
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303490 if (VOS_FTM_MODE == hdd_get_conparam()) {
3491 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3492 return -EINVAL;
3493 }
3494
Dino Mycle6fb96c12014-06-10 11:52:40 +05303495 status = wlan_hdd_validate_context(pHddCtx);
3496 if (0 != status)
3497 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303498 return -EINVAL;
3499 }
Dino Myclee8843b32014-07-04 14:21:45 +05303500 /* check the EXTScan Capability */
3501 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3502 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3503 {
3504 hddLog(VOS_TRACE_LEVEL_ERROR,
3505 FL("EXTScan not enabled/supported by Firmware"));
3506 return -EINVAL;
3507 }
3508
Dino Mycle6fb96c12014-06-10 11:52:40 +05303509 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3510 data, dataLen,
3511 wlan_hdd_extscan_config_policy)) {
3512 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3513 return -EINVAL;
3514 }
3515
3516 /* Parse and fetch request Id */
3517 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3518 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3519 return -EINVAL;
3520 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303521 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3522 vos_mem_malloc(sizeof(*pReqMsg));
3523 if (!pReqMsg) {
3524 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3525 return -ENOMEM;
3526 }
3527
Dino Myclee8843b32014-07-04 14:21:45 +05303528
Dino Mycle6fb96c12014-06-10 11:52:40 +05303529 pReqMsg->requestId = nla_get_u32(
3530 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3531 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3532
3533 /* Parse and fetch number of APs */
3534 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3535 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3536 goto fail;
3537 }
3538
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303539 /* Parse and fetch lost ap sample size */
3540 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3541 hddLog(LOGE, FL("attr lost ap sample size failed"));
3542 goto fail;
3543 }
3544
3545 pReqMsg->lostBssidSampleSize = nla_get_u32(
3546 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3547 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3548
Dino Mycle6fb96c12014-06-10 11:52:40 +05303549 pReqMsg->sessionId = pAdapter->sessionId;
3550 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3551
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303552 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303553 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303554 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303555
3556 nla_for_each_nested(apTh,
3557 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3558 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3559 nla_data(apTh), nla_len(apTh),
3560 NULL)) {
3561 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3562 goto fail;
3563 }
3564
3565 /* Parse and fetch MAC address */
3566 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3567 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3568 goto fail;
3569 }
3570 memcpy(pReqMsg->ap[i].bssid, nla_data(
3571 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3572 sizeof(tSirMacAddr));
3573 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3574
3575 /* Parse and fetch low RSSI */
3576 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3577 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3578 goto fail;
3579 }
3580 pReqMsg->ap[i].low = nla_get_s32(
3581 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3582 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3583
3584 /* Parse and fetch high RSSI */
3585 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3586 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3587 goto fail;
3588 }
3589 pReqMsg->ap[i].high = nla_get_s32(
3590 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3591 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3592 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303593 i++;
3594 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303595
3596 context = &pHddCtx->ext_scan_context;
3597 spin_lock(&hdd_context_lock);
3598 INIT_COMPLETION(context->response_event);
3599 context->request_id = request_id = pReqMsg->requestId;
3600 spin_unlock(&hdd_context_lock);
3601
Dino Mycle6fb96c12014-06-10 11:52:40 +05303602 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3603 if (!HAL_STATUS_SUCCESS(status)) {
3604 hddLog(VOS_TRACE_LEVEL_ERROR,
3605 FL("sme_SetBssHotlist failed(err=%d)"), status);
3606 vos_mem_free(pReqMsg);
3607 return -EINVAL;
3608 }
3609
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303610 /* request was sent -- wait for the response */
3611 rc = wait_for_completion_timeout(&context->response_event,
3612 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3613
3614 if (!rc) {
3615 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3616 retval = -ETIMEDOUT;
3617 } else {
3618 spin_lock(&hdd_context_lock);
3619 if (context->request_id == request_id)
3620 retval = context->response_status;
3621 else
3622 retval = -EINVAL;
3623 spin_unlock(&hdd_context_lock);
3624 }
3625
Dino Myclee8843b32014-07-04 14:21:45 +05303626 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303627 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303628 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303629
3630fail:
3631 vos_mem_free(pReqMsg);
3632 return -EINVAL;
3633}
3634
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303635static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3636 struct wireless_dev *wdev,
3637 const void *data, int dataLen)
3638{
3639 int ret = 0;
3640
3641 vos_ssr_protect(__func__);
3642 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3643 dataLen);
3644 vos_ssr_unprotect(__func__);
3645
3646 return ret;
3647}
3648
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303649static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303650 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303651 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303652{
3653 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3654 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3655 tANI_U8 numChannels = 0;
3656 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05303657 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303658 tWifiBand wifiBand;
3659 eHalStatus status;
3660 struct sk_buff *replySkb;
3661 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303662 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303663
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303664 ENTER();
3665
Dino Mycle6fb96c12014-06-10 11:52:40 +05303666 status = wlan_hdd_validate_context(pHddCtx);
3667 if (0 != status)
3668 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303669 return -EINVAL;
3670 }
Dino Myclee8843b32014-07-04 14:21:45 +05303671
Dino Mycle6fb96c12014-06-10 11:52:40 +05303672 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3673 data, dataLen,
3674 wlan_hdd_extscan_config_policy)) {
3675 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3676 return -EINVAL;
3677 }
3678
3679 /* Parse and fetch request Id */
3680 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3681 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3682 return -EINVAL;
3683 }
3684 requestId = nla_get_u32(
3685 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3686 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3687
3688 /* Parse and fetch wifi band */
3689 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3690 {
3691 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3692 return -EINVAL;
3693 }
3694 wifiBand = nla_get_u32(
3695 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3696 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3697
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05303698 /* Parse and fetch max channels */
3699 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
3700 {
3701 hddLog(LOGE, FL("attr max channels failed"));
3702 return -EINVAL;
3703 }
3704 maxChannels = nla_get_u32(
3705 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
3706 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
3707
Dino Mycle6fb96c12014-06-10 11:52:40 +05303708 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3709 wifiBand, ChannelList,
3710 &numChannels);
3711 if (eHAL_STATUS_SUCCESS != status) {
3712 hddLog(VOS_TRACE_LEVEL_ERROR,
3713 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3714 return -EINVAL;
3715 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05303716
3717 numChannels = VOS_MIN(numChannels, maxChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303718 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05303719
Dino Mycle6fb96c12014-06-10 11:52:40 +05303720 for (i = 0; i < numChannels; i++)
3721 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3722
3723 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3724 sizeof(u32) * numChannels +
3725 NLMSG_HDRLEN);
3726
3727 if (!replySkb) {
3728 hddLog(VOS_TRACE_LEVEL_ERROR,
3729 FL("valid channels: buffer alloc fail"));
3730 return -EINVAL;
3731 }
3732 if (nla_put_u32(replySkb,
3733 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3734 numChannels) ||
3735 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3736 sizeof(u32) * numChannels, ChannelList)) {
3737
3738 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3739 kfree_skb(replySkb);
3740 return -EINVAL;
3741 }
3742
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303743 ret = cfg80211_vendor_cmd_reply(replySkb);
3744
3745 EXIT();
3746 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303747}
3748
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303749static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3750 struct wireless_dev *wdev,
3751 const void *data, int dataLen)
3752{
3753 int ret = 0;
3754
3755 vos_ssr_protect(__func__);
3756 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
3757 dataLen);
3758 vos_ssr_unprotect(__func__);
3759
3760 return ret;
3761}
3762
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303763static int hdd_extscan_start_fill_bucket_channel_spec(
3764 hdd_context_t *pHddCtx,
3765 tpSirEXTScanStartReqParams pReqMsg,
3766 struct nlattr **tb)
3767{
3768 struct nlattr *bucket[
3769 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3770 struct nlattr *channel[
3771 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3772 struct nlattr *buckets;
3773 struct nlattr *channels;
3774 int rem1, rem2;
3775 eHalStatus status;
3776 tANI_U8 bktIndex, j, numChannels;
3777 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3778 tANI_U32 passive_max_chn_time, active_max_chn_time;
3779
3780 bktIndex = 0;
3781
3782 nla_for_each_nested(buckets,
3783 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3784 if (nla_parse(bucket,
3785 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3786 nla_data(buckets), nla_len(buckets), NULL)) {
3787 hddLog(LOGE, FL("nla_parse failed"));
3788 return -EINVAL;
3789 }
3790
3791 /* Parse and fetch bucket spec */
3792 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3793 hddLog(LOGE, FL("attr bucket index failed"));
3794 return -EINVAL;
3795 }
3796 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
3797 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3798 hddLog(LOG1, FL("Bucket spec Index %d"),
3799 pReqMsg->buckets[bktIndex].bucket);
3800
3801 /* Parse and fetch wifi band */
3802 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3803 hddLog(LOGE, FL("attr wifi band failed"));
3804 return -EINVAL;
3805 }
3806 pReqMsg->buckets[bktIndex].band = nla_get_u8(
3807 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3808 hddLog(LOG1, FL("Wifi band %d"),
3809 pReqMsg->buckets[bktIndex].band);
3810
3811 /* Parse and fetch period */
3812 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3813 hddLog(LOGE, FL("attr period failed"));
3814 return -EINVAL;
3815 }
3816 pReqMsg->buckets[bktIndex].period = nla_get_u32(
3817 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3818 hddLog(LOG1, FL("period %d"),
3819 pReqMsg->buckets[bktIndex].period);
3820
3821 /* Parse and fetch report events */
3822 if (!bucket[
3823 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3824 hddLog(LOGE, FL("attr report events failed"));
3825 return -EINVAL;
3826 }
3827 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
3828 bucket[
3829 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3830 hddLog(LOG1, FL("report events %d"),
3831 pReqMsg->buckets[bktIndex].reportEvents);
3832
3833 /* Parse and fetch max period */
3834 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
3835 hddLog(LOGE, FL("attr max period failed"));
3836 return -EINVAL;
3837 }
3838 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
3839 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
3840 hddLog(LOG1, FL("max period %u"),
3841 pReqMsg->buckets[bktIndex].max_period);
3842
3843 /* Parse and fetch exponent */
3844 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
3845 hddLog(LOGE, FL("attr exponent failed"));
3846 return -EINVAL;
3847 }
3848 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
3849 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
3850 hddLog(LOG1, FL("exponent %u"),
3851 pReqMsg->buckets[bktIndex].exponent);
3852
3853 /* Parse and fetch step count */
3854 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
3855 hddLog(LOGE, FL("attr step count failed"));
3856 return -EINVAL;
3857 }
3858 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
3859 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
3860 hddLog(LOG1, FL("Step count %u"),
3861 pReqMsg->buckets[bktIndex].step_count);
3862
3863 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
3864 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
3865
3866 /* Framework shall pass the channel list if the input WiFi band is
3867 * WIFI_BAND_UNSPECIFIED.
3868 * If the input WiFi band is specified (any value other than
3869 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
3870 */
3871 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
3872 numChannels = 0;
3873 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
3874 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
3875 pReqMsg->buckets[bktIndex].band,
3876 chanList, &numChannels);
3877 if (!HAL_STATUS_SUCCESS(status)) {
3878 hddLog(LOGE,
3879 FL("sme_GetValidChannelsByBand failed (err=%d)"),
3880 status);
3881 return -EINVAL;
3882 }
3883
3884 pReqMsg->buckets[bktIndex].numChannels =
3885 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
3886 hddLog(LOG1, FL("Num channels %d"),
3887 pReqMsg->buckets[bktIndex].numChannels);
3888
3889 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
3890 j++) {
3891 pReqMsg->buckets[bktIndex].channels[j].channel =
3892 chanList[j];
3893 pReqMsg->buckets[bktIndex].channels[j].
3894 chnlClass = 0;
3895 if (CSR_IS_CHANNEL_DFS(
3896 vos_freq_to_chan(chanList[j]))) {
3897 pReqMsg->buckets[bktIndex].channels[j].
3898 passive = 1;
3899 pReqMsg->buckets[bktIndex].channels[j].
3900 dwellTimeMs = passive_max_chn_time;
3901 } else {
3902 pReqMsg->buckets[bktIndex].channels[j].
3903 passive = 0;
3904 pReqMsg->buckets[bktIndex].channels[j].
3905 dwellTimeMs = active_max_chn_time;
3906 }
3907
3908 hddLog(LOG1,
3909 "Channel %u Passive %u Dwell time %u ms",
3910 pReqMsg->buckets[bktIndex].channels[j].channel,
3911 pReqMsg->buckets[bktIndex].channels[j].passive,
3912 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
3913 }
3914
3915 bktIndex++;
3916 continue;
3917 }
3918
3919 /* Parse and fetch number of channels */
3920 if (!bucket[
3921 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
3922 hddLog(LOGE, FL("attr num channels failed"));
3923 return -EINVAL;
3924 }
3925
3926 pReqMsg->buckets[bktIndex].numChannels =
3927 nla_get_u32(bucket[
3928 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3929 hddLog(LOG1, FL("num channels %d"),
3930 pReqMsg->buckets[bktIndex].numChannels);
3931
3932 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3933 hddLog(LOGE, FL("attr channel spec failed"));
3934 return -EINVAL;
3935 }
3936
3937 j = 0;
3938 nla_for_each_nested(channels,
3939 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3940 if (nla_parse(channel,
3941 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3942 nla_data(channels), nla_len(channels),
3943 wlan_hdd_extscan_config_policy)) {
3944 hddLog(LOGE, FL("nla_parse failed"));
3945 return -EINVAL;
3946 }
3947
3948 /* Parse and fetch channel */
3949 if (!channel[
3950 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3951 hddLog(LOGE, FL("attr channel failed"));
3952 return -EINVAL;
3953 }
3954 pReqMsg->buckets[bktIndex].channels[j].channel =
3955 nla_get_u32(channel[
3956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3957 hddLog(LOG1, FL("channel %u"),
3958 pReqMsg->buckets[bktIndex].channels[j].channel);
3959
3960 /* Parse and fetch dwell time */
3961 if (!channel[
3962 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3963 hddLog(LOGE, FL("attr dwelltime failed"));
3964 return -EINVAL;
3965 }
3966 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
3967 nla_get_u32(channel[
3968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3969
3970 hddLog(LOG1, FL("Dwell time (%u ms)"),
3971 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
3972
3973
3974 /* Parse and fetch channel spec passive */
3975 if (!channel[
3976 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3977 hddLog(LOGE,
3978 FL("attr channel spec passive failed"));
3979 return -EINVAL;
3980 }
3981 pReqMsg->buckets[bktIndex].channels[j].passive =
3982 nla_get_u8(channel[
3983 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3984 hddLog(LOG1, FL("Chnl spec passive %u"),
3985 pReqMsg->buckets[bktIndex].channels[j].passive);
3986
3987 j++;
3988 }
3989
3990 bktIndex++;
3991 }
3992
3993 return 0;
3994}
3995
3996
3997/*
3998 * define short names for the global vendor params
3999 * used by wlan_hdd_cfg80211_extscan_start()
4000 */
4001#define PARAM_MAX \
4002QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4003#define PARAM_REQUEST_ID \
4004QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4005#define PARAM_BASE_PERIOD \
4006QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4007#define PARAM_MAX_AP_PER_SCAN \
4008QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4009#define PARAM_RPT_THRHLD_PERCENT \
4010QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4011#define PARAM_RPT_THRHLD_NUM_SCANS \
4012QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4013#define PARAM_NUM_BUCKETS \
4014QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4015
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304016static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304017 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304018 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304019{
Dino Myclee8843b32014-07-04 14:21:45 +05304020 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304021 struct net_device *dev = wdev->netdev;
4022 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4023 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4024 struct nlattr *tb[PARAM_MAX + 1];
4025 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304026 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304027 tANI_U32 request_id;
4028 struct hdd_ext_scan_context *context;
4029 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304030
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304031 ENTER();
4032
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304033 if (VOS_FTM_MODE == hdd_get_conparam()) {
4034 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4035 return -EINVAL;
4036 }
4037
Dino Mycle6fb96c12014-06-10 11:52:40 +05304038 status = wlan_hdd_validate_context(pHddCtx);
4039 if (0 != status)
4040 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304041 return -EINVAL;
4042 }
Dino Myclee8843b32014-07-04 14:21:45 +05304043 /* check the EXTScan Capability */
4044 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4045 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4046 {
4047 hddLog(VOS_TRACE_LEVEL_ERROR,
4048 FL("EXTScan not enabled/supported by Firmware"));
4049 return -EINVAL;
4050 }
4051
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304052 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304053 data, dataLen,
4054 wlan_hdd_extscan_config_policy)) {
4055 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4056 return -EINVAL;
4057 }
4058
4059 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304060 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304061 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4062 return -EINVAL;
4063 }
4064
Dino Myclee8843b32014-07-04 14:21:45 +05304065 pReqMsg = (tpSirEXTScanStartReqParams)
4066 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304067 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304068 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4069 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304070 }
4071
4072 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304073 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304074 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4075
4076 pReqMsg->sessionId = pAdapter->sessionId;
4077 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4078
4079 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304080 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304081 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4082 goto fail;
4083 }
4084 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304085 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304086 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4087 pReqMsg->basePeriod);
4088
4089 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304090 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304091 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4092 goto fail;
4093 }
4094 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304095 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304096 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4097 pReqMsg->maxAPperScan);
4098
4099 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304100 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4102 goto fail;
4103 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304104 pReqMsg->reportThresholdPercent = nla_get_u8(
4105 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304106 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304107 pReqMsg->reportThresholdPercent);
4108
4109 /* Parse and fetch report threshold num scans */
4110 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4111 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4112 goto fail;
4113 }
4114 pReqMsg->reportThresholdNumScans = nla_get_u8(
4115 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4116 hddLog(LOG1, FL("Report Threshold num scans %d"),
4117 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304118
4119 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304120 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304121 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4122 goto fail;
4123 }
4124 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304125 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304126 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4127 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4128 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4129 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4130 }
4131 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4132 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304133
Dino Mycle6fb96c12014-06-10 11:52:40 +05304134 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4135 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4136 goto fail;
4137 }
4138
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304139 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304140
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304141 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4142 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304143
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304144 context = &pHddCtx->ext_scan_context;
4145 spin_lock(&hdd_context_lock);
4146 INIT_COMPLETION(context->response_event);
4147 context->request_id = request_id = pReqMsg->requestId;
4148 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304149
Dino Mycle6fb96c12014-06-10 11:52:40 +05304150 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4151 if (!HAL_STATUS_SUCCESS(status)) {
4152 hddLog(VOS_TRACE_LEVEL_ERROR,
4153 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304154 goto fail;
4155 }
4156
4157 /* request was sent -- wait for the response */
4158 rc = wait_for_completion_timeout(&context->response_event,
4159 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4160
4161 if (!rc) {
4162 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4163 retval = -ETIMEDOUT;
4164 } else {
4165 spin_lock(&hdd_context_lock);
4166 if (context->request_id == request_id)
4167 retval = context->response_status;
4168 else
4169 retval = -EINVAL;
4170 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304171 }
4172
Dino Myclee8843b32014-07-04 14:21:45 +05304173 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304174 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304175 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304176
4177fail:
4178 vos_mem_free(pReqMsg);
4179 return -EINVAL;
4180}
4181
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304182/*
4183 * done with short names for the global vendor params
4184 * used by wlan_hdd_cfg80211_extscan_start()
4185 */
4186#undef PARAM_MAX
4187#undef PARAM_REQUEST_ID
4188#undef PARAM_BASE_PERIOD
4189#undef PARAMS_MAX_AP_PER_SCAN
4190#undef PARAMS_RPT_THRHLD_PERCENT
4191#undef PARAMS_RPT_THRHLD_NUM_SCANS
4192#undef PARAMS_NUM_BUCKETS
4193
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304194static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4195 struct wireless_dev *wdev,
4196 const void *data, int dataLen)
4197{
4198 int ret = 0;
4199
4200 vos_ssr_protect(__func__);
4201 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4202 vos_ssr_unprotect(__func__);
4203
4204 return ret;
4205}
4206
4207static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304208 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304209 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304210{
Dino Myclee8843b32014-07-04 14:21:45 +05304211 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304212 struct net_device *dev = wdev->netdev;
4213 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4214 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4215 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4216 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304217 int retval;
4218 unsigned long rc;
4219 struct hdd_ext_scan_context *context;
4220 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304221
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304222 ENTER();
4223
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304224 if (VOS_FTM_MODE == hdd_get_conparam()) {
4225 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4226 return -EINVAL;
4227 }
4228
Dino Mycle6fb96c12014-06-10 11:52:40 +05304229 status = wlan_hdd_validate_context(pHddCtx);
4230 if (0 != status)
4231 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304232 return -EINVAL;
4233 }
Dino Myclee8843b32014-07-04 14:21:45 +05304234 /* check the EXTScan Capability */
4235 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4236 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4237 {
4238 hddLog(VOS_TRACE_LEVEL_ERROR,
4239 FL("EXTScan not enabled/supported by Firmware"));
4240 return -EINVAL;
4241 }
4242
Dino Mycle6fb96c12014-06-10 11:52:40 +05304243 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4244 data, dataLen,
4245 wlan_hdd_extscan_config_policy)) {
4246 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4247 return -EINVAL;
4248 }
4249
4250 /* Parse and fetch request Id */
4251 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4252 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4253 return -EINVAL;
4254 }
4255
Dino Myclee8843b32014-07-04 14:21:45 +05304256 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304257 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304258 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304259
Dino Myclee8843b32014-07-04 14:21:45 +05304260 reqMsg.sessionId = pAdapter->sessionId;
4261 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304262
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304263 context = &pHddCtx->ext_scan_context;
4264 spin_lock(&hdd_context_lock);
4265 INIT_COMPLETION(context->response_event);
4266 context->request_id = request_id = reqMsg.sessionId;
4267 spin_unlock(&hdd_context_lock);
4268
Dino Myclee8843b32014-07-04 14:21:45 +05304269 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304270 if (!HAL_STATUS_SUCCESS(status)) {
4271 hddLog(VOS_TRACE_LEVEL_ERROR,
4272 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304273 return -EINVAL;
4274 }
4275
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304276 /* request was sent -- wait for the response */
4277 rc = wait_for_completion_timeout(&context->response_event,
4278 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4279
4280 if (!rc) {
4281 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4282 retval = -ETIMEDOUT;
4283 } else {
4284 spin_lock(&hdd_context_lock);
4285 if (context->request_id == request_id)
4286 retval = context->response_status;
4287 else
4288 retval = -EINVAL;
4289 spin_unlock(&hdd_context_lock);
4290 }
4291
4292 return retval;
4293
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304294 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304295 return 0;
4296}
4297
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304298static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4299 struct wireless_dev *wdev,
4300 const void *data, int dataLen)
4301{
4302 int ret = 0;
4303
4304 vos_ssr_protect(__func__);
4305 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4306 vos_ssr_unprotect(__func__);
4307
4308 return ret;
4309}
4310
4311static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304312 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304313 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304314{
Dino Myclee8843b32014-07-04 14:21:45 +05304315 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304316 struct net_device *dev = wdev->netdev;
4317 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4318 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4319 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4320 eHalStatus status;
4321
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304322 ENTER();
4323
Dino Mycle6fb96c12014-06-10 11:52:40 +05304324 status = wlan_hdd_validate_context(pHddCtx);
4325 if (0 != status)
4326 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304327 return -EINVAL;
4328 }
Dino Myclee8843b32014-07-04 14:21:45 +05304329 /* check the EXTScan Capability */
4330 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4331 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4332 {
4333 hddLog(VOS_TRACE_LEVEL_ERROR,
4334 FL("EXTScan not enabled/supported by Firmware"));
4335 return -EINVAL;
4336 }
4337
Dino Mycle6fb96c12014-06-10 11:52:40 +05304338 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4339 data, dataLen,
4340 wlan_hdd_extscan_config_policy)) {
4341 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4342 return -EINVAL;
4343 }
4344
4345 /* Parse and fetch request Id */
4346 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4347 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4348 return -EINVAL;
4349 }
4350
Dino Myclee8843b32014-07-04 14:21:45 +05304351 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304352 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304353 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304354
Dino Myclee8843b32014-07-04 14:21:45 +05304355 reqMsg.sessionId = pAdapter->sessionId;
4356 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304357
Dino Myclee8843b32014-07-04 14:21:45 +05304358 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304359 if (!HAL_STATUS_SUCCESS(status)) {
4360 hddLog(VOS_TRACE_LEVEL_ERROR,
4361 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304362 return -EINVAL;
4363 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304364 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304365 return 0;
4366}
4367
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304368static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4369 struct wireless_dev *wdev,
4370 const void *data, int dataLen)
4371{
4372 int ret = 0;
4373
4374 vos_ssr_protect(__func__);
4375 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4376 vos_ssr_unprotect(__func__);
4377
4378 return ret;
4379}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304380#endif /* WLAN_FEATURE_EXTSCAN */
4381
Atul Mittal115287b2014-07-08 13:26:33 +05304382/*EXT TDLS*/
4383static const struct nla_policy
4384wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4385{
4386 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4387 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4388 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4389 {.type = NLA_S32 },
4390 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4391 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4392
4393};
4394
4395static const struct nla_policy
4396wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4397{
4398 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4399
4400};
4401
4402static const struct nla_policy
4403wlan_hdd_tdls_config_state_change_policy[
4404 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4405{
4406 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4407 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4408 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304409 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4410 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4411 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304412
4413};
4414
4415static const struct nla_policy
4416wlan_hdd_tdls_config_get_status_policy[
4417 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4418{
4419 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4420 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4421 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304422 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4423 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4424 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304425
4426};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304427
4428static const struct nla_policy
4429wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4430{
4431 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4432};
4433
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304434static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304435 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304436 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304437 int data_len)
4438{
4439
4440 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4441 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4442
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304443 ENTER();
4444
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304445 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304446 return -EINVAL;
4447 }
4448 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05304449 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304450 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304451 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304452 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05304453 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304454 return -ENOTSUPP;
4455 }
4456
4457 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4458 data, data_len, wlan_hdd_mac_config)) {
4459 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4460 return -EINVAL;
4461 }
4462
4463 /* Parse and fetch mac address */
4464 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4465 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4466 return -EINVAL;
4467 }
4468
4469 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4470 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4471 VOS_MAC_ADDR_LAST_3_BYTES);
4472
Siddharth Bhal76972212014-10-15 16:22:51 +05304473 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4474
4475 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304476 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4477 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304478 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4479 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4480 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4481 {
4482 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4483 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4484 VOS_MAC_ADDRESS_LEN);
4485 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304486 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304487
Siddharth Bhal76972212014-10-15 16:22:51 +05304488 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
4489 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304490 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4491 }
4492
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304493 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304494 return 0;
4495}
4496
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304497static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
4498 struct wireless_dev *wdev,
4499 const void *data,
4500 int data_len)
4501{
4502 int ret = 0;
4503
4504 vos_ssr_protect(__func__);
4505 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
4506 vos_ssr_unprotect(__func__);
4507
4508 return ret;
4509}
4510
4511static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304512 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304513 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304514 int data_len)
4515{
4516 u8 peer[6] = {0};
4517 struct net_device *dev = wdev->netdev;
4518 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4519 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4520 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4521 eHalStatus ret;
4522 tANI_S32 state;
4523 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304524 tANI_S32 global_operating_class = 0;
4525 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304526 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304527 int retVal;
4528
4529 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304530
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304531 if (!pAdapter) {
4532 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4533 return -EINVAL;
4534 }
4535
Atul Mittal115287b2014-07-08 13:26:33 +05304536 ret = wlan_hdd_validate_context(pHddCtx);
4537 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304538 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304539 return -EINVAL;
4540 }
4541 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304542 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304543 return -ENOTSUPP;
4544 }
4545 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4546 data, data_len,
4547 wlan_hdd_tdls_config_get_status_policy)) {
4548 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4549 return -EINVAL;
4550 }
4551
4552 /* Parse and fetch mac address */
4553 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4554 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4555 return -EINVAL;
4556 }
4557
4558 memcpy(peer, nla_data(
4559 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4560 sizeof(peer));
4561 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4562
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05304563 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05304564
Atul Mittal115287b2014-07-08 13:26:33 +05304565 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304566 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304567 NLMSG_HDRLEN);
4568
4569 if (!skb) {
4570 hddLog(VOS_TRACE_LEVEL_ERROR,
4571 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4572 return -EINVAL;
4573 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304574 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 +05304575 reason,
4576 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304577 global_operating_class,
4578 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304579 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304580 if (nla_put_s32(skb,
4581 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4582 state) ||
4583 nla_put_s32(skb,
4584 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4585 reason) ||
4586 nla_put_s32(skb,
4587 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4588 global_operating_class) ||
4589 nla_put_s32(skb,
4590 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4591 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304592
4593 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4594 goto nla_put_failure;
4595 }
4596
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304597 retVal = cfg80211_vendor_cmd_reply(skb);
4598 EXIT();
4599 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05304600
4601nla_put_failure:
4602 kfree_skb(skb);
4603 return -EINVAL;
4604}
4605
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304606static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4607 struct wireless_dev *wdev,
4608 const void *data,
4609 int data_len)
4610{
4611 int ret = 0;
4612
4613 vos_ssr_protect(__func__);
4614 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
4615 vos_ssr_unprotect(__func__);
4616
4617 return ret;
4618}
4619
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05304620static int wlan_hdd_cfg80211_exttdls_callback(
4621#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
4622 const tANI_U8* mac,
4623#else
4624 tANI_U8* mac,
4625#endif
Atul Mittal115287b2014-07-08 13:26:33 +05304626 tANI_S32 state,
4627 tANI_S32 reason,
4628 void *ctx)
4629{
4630 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05304631 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304632 tANI_S32 global_operating_class = 0;
4633 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304634 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05304635
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304636 ENTER();
4637
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304638 if (!pAdapter) {
4639 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4640 return -EINVAL;
4641 }
4642
4643 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05304644 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304645 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304646 return -EINVAL;
4647 }
4648
4649 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304650 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304651 return -ENOTSUPP;
4652 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304653 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
4654#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4655 NULL,
4656#endif
Atul Mittal115287b2014-07-08 13:26:33 +05304657 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4658 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4659 GFP_KERNEL);
4660
4661 if (!skb) {
4662 hddLog(VOS_TRACE_LEVEL_ERROR,
4663 FL("cfg80211_vendor_event_alloc failed"));
4664 return -EINVAL;
4665 }
4666 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304667 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4668 reason,
4669 state,
4670 global_operating_class,
4671 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304672 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4673 MAC_ADDR_ARRAY(mac));
4674
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304675 if (nla_put(skb,
4676 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4677 VOS_MAC_ADDR_SIZE, mac) ||
4678 nla_put_s32(skb,
4679 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4680 state) ||
4681 nla_put_s32(skb,
4682 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4683 reason) ||
4684 nla_put_s32(skb,
4685 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4686 channel) ||
4687 nla_put_s32(skb,
4688 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4689 global_operating_class)
4690 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304691 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4692 goto nla_put_failure;
4693 }
4694
4695 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304696 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05304697 return (0);
4698
4699nla_put_failure:
4700 kfree_skb(skb);
4701 return -EINVAL;
4702}
4703
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304704static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304705 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304706 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304707 int data_len)
4708{
4709 u8 peer[6] = {0};
4710 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304711 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4712 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4713 eHalStatus status;
4714 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304715 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304716 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304717
4718 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304719
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304720 if (!dev) {
4721 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4722 return -EINVAL;
4723 }
4724
4725 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4726 if (!pAdapter) {
4727 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4728 return -EINVAL;
4729 }
4730
Atul Mittal115287b2014-07-08 13:26:33 +05304731 status = wlan_hdd_validate_context(pHddCtx);
4732 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304733 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304734 return -EINVAL;
4735 }
4736 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304737 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304738 return -ENOTSUPP;
4739 }
4740 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4741 data, data_len,
4742 wlan_hdd_tdls_config_enable_policy)) {
4743 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4744 return -EINVAL;
4745 }
4746
4747 /* Parse and fetch mac address */
4748 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4749 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4750 return -EINVAL;
4751 }
4752
4753 memcpy(peer, nla_data(
4754 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4755 sizeof(peer));
4756 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4757
4758 /* Parse and fetch channel */
4759 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4760 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4761 return -EINVAL;
4762 }
4763 pReqMsg.channel = nla_get_s32(
4764 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4765 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4766
4767 /* Parse and fetch global operating class */
4768 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4770 return -EINVAL;
4771 }
4772 pReqMsg.global_operating_class = nla_get_s32(
4773 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4774 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4775 pReqMsg.global_operating_class);
4776
4777 /* Parse and fetch latency ms */
4778 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4779 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4780 return -EINVAL;
4781 }
4782 pReqMsg.max_latency_ms = nla_get_s32(
4783 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4784 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4785 pReqMsg.max_latency_ms);
4786
4787 /* Parse and fetch required bandwidth kbps */
4788 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4789 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4790 return -EINVAL;
4791 }
4792
4793 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4794 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4795 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4796 pReqMsg.min_bandwidth_kbps);
4797
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304798 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05304799 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05304800 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304801 wlan_hdd_cfg80211_exttdls_callback);
4802
4803 EXIT();
4804 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304805}
4806
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304807static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4808 struct wireless_dev *wdev,
4809 const void *data,
4810 int data_len)
4811{
4812 int ret = 0;
4813
4814 vos_ssr_protect(__func__);
4815 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
4816 vos_ssr_unprotect(__func__);
4817
4818 return ret;
4819}
4820
4821static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304822 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304823 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304824 int data_len)
4825{
4826 u8 peer[6] = {0};
4827 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304828 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4829 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4830 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304831 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304832 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304833
4834 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304835
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304836 if (!dev) {
4837 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4838 return -EINVAL;
4839 }
4840
4841 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4842 if (!pAdapter) {
4843 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
4844 return -EINVAL;
4845 }
4846
Atul Mittal115287b2014-07-08 13:26:33 +05304847 status = wlan_hdd_validate_context(pHddCtx);
4848 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304849 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304850 return -EINVAL;
4851 }
4852 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304853 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304854 return -ENOTSUPP;
4855 }
4856 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4857 data, data_len,
4858 wlan_hdd_tdls_config_disable_policy)) {
4859 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4860 return -EINVAL;
4861 }
4862 /* Parse and fetch mac address */
4863 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4864 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4865 return -EINVAL;
4866 }
4867
4868 memcpy(peer, nla_data(
4869 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4870 sizeof(peer));
4871 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4872
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304873 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
4874
4875 EXIT();
4876 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304877}
4878
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304879static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4880 struct wireless_dev *wdev,
4881 const void *data,
4882 int data_len)
4883{
4884 int ret = 0;
4885
4886 vos_ssr_protect(__func__);
4887 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
4888 vos_ssr_unprotect(__func__);
4889
4890 return ret;
4891}
4892
Dasari Srinivas7875a302014-09-26 17:50:57 +05304893static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304894__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05304895 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304896 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05304897{
4898 struct net_device *dev = wdev->netdev;
4899 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4900 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4901 struct sk_buff *skb = NULL;
4902 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304903 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05304904
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304905 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304906
4907 ret = wlan_hdd_validate_context(pHddCtx);
4908 if (0 != ret)
4909 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304910 return ret;
4911 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05304912 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
4913 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
4914 fset |= WIFI_FEATURE_INFRA;
4915 }
4916
4917 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
4918 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
4919 fset |= WIFI_FEATURE_INFRA_5G;
4920 }
4921
4922#ifdef WLAN_FEATURE_P2P
4923 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
4924 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
4925 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
4926 fset |= WIFI_FEATURE_P2P;
4927 }
4928#endif
4929
4930 /* Soft-AP is supported currently by default */
4931 fset |= WIFI_FEATURE_SOFT_AP;
4932
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05304933 /* HOTSPOT is a supplicant feature, enable it by default */
4934 fset |= WIFI_FEATURE_HOTSPOT;
4935
Dasari Srinivas7875a302014-09-26 17:50:57 +05304936#ifdef WLAN_FEATURE_EXTSCAN
4937 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
4938 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
4939 hddLog(LOG1, FL("EXTScan is supported by firmware"));
4940 fset |= WIFI_FEATURE_EXTSCAN;
4941 }
4942#endif
4943
Dasari Srinivas7875a302014-09-26 17:50:57 +05304944 if (sme_IsFeatureSupportedByFW(NAN)) {
4945 hddLog(LOG1, FL("NAN is supported by firmware"));
4946 fset |= WIFI_FEATURE_NAN;
4947 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05304948
4949 /* D2D RTT is not supported currently by default */
4950 if (sme_IsFeatureSupportedByFW(RTT)) {
4951 hddLog(LOG1, FL("RTT is supported by firmware"));
4952 fset |= WIFI_FEATURE_D2AP_RTT;
4953 }
4954
4955#ifdef FEATURE_WLAN_BATCH_SCAN
4956 if (fset & WIFI_FEATURE_EXTSCAN) {
4957 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
4958 fset &= ~WIFI_FEATURE_BATCH_SCAN;
4959 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
4960 hddLog(LOG1, FL("Batch scan is supported by firmware"));
4961 fset |= WIFI_FEATURE_BATCH_SCAN;
4962 }
4963#endif
4964
4965#ifdef FEATURE_WLAN_SCAN_PNO
4966 if (pHddCtx->cfg_ini->configPNOScanSupport &&
4967 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
4968 hddLog(LOG1, FL("PNO is supported by firmware"));
4969 fset |= WIFI_FEATURE_PNO;
4970 }
4971#endif
4972
4973 /* STA+STA is supported currently by default */
4974 fset |= WIFI_FEATURE_ADDITIONAL_STA;
4975
4976#ifdef FEATURE_WLAN_TDLS
4977 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
4978 sme_IsFeatureSupportedByFW(TDLS)) {
4979 hddLog(LOG1, FL("TDLS is supported by firmware"));
4980 fset |= WIFI_FEATURE_TDLS;
4981 }
4982
4983 /* TDLS_OFFCHANNEL is not supported currently by default */
4984#endif
4985
4986#ifdef WLAN_AP_STA_CONCURRENCY
4987 /* AP+STA concurrency is supported currently by default */
4988 fset |= WIFI_FEATURE_AP_STA;
4989#endif
4990
Mukul Sharma5add0532015-08-17 15:57:47 +05304991#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4992 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
4993 hddLog(LOG1, FL("Link layer stats is supported by driver"));
4994#endif
4995
Dasari Srinivas7875a302014-09-26 17:50:57 +05304996 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
4997 NLMSG_HDRLEN);
4998
4999 if (!skb) {
5000 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5001 return -EINVAL;
5002 }
5003 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5004
5005 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5006 hddLog(LOGE, FL("nla put fail"));
5007 goto nla_put_failure;
5008 }
5009
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305010 ret = cfg80211_vendor_cmd_reply(skb);
5011 EXIT();
5012 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305013
5014nla_put_failure:
5015 kfree_skb(skb);
5016 return -EINVAL;
5017}
5018
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305019static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305020wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5021 struct wireless_dev *wdev,
5022 const void *data, int data_len)
5023{
5024 int ret = 0;
5025
5026 vos_ssr_protect(__func__);
5027 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5028 vos_ssr_unprotect(__func__);
5029
5030 return ret;
5031}
5032
5033static int
5034__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305035 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305036 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305037{
5038 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5039 uint8_t i, feature_sets, max_feature_sets;
5040 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5041 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305042 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5043 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305044
5045 ENTER();
5046
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305047 ret = wlan_hdd_validate_context(pHddCtx);
5048 if (0 != ret)
5049 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305050 return ret;
5051 }
5052
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305053 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5054 data, data_len, NULL)) {
5055 hddLog(LOGE, FL("Invalid ATTR"));
5056 return -EINVAL;
5057 }
5058
5059 /* Parse and fetch max feature set */
5060 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5061 hddLog(LOGE, FL("Attr max feature set size failed"));
5062 return -EINVAL;
5063 }
5064 max_feature_sets = nla_get_u32(
5065 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5066 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5067
5068 /* Fill feature combination matrix */
5069 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305070 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5071 WIFI_FEATURE_P2P;
5072
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305073 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5074 WIFI_FEATURE_SOFT_AP;
5075
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305076 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5077 WIFI_FEATURE_SOFT_AP;
5078
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305079 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5080 WIFI_FEATURE_SOFT_AP |
5081 WIFI_FEATURE_P2P;
5082
5083 /* Add more feature combinations here */
5084
5085 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5086 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5087 hddLog(LOG1, "Feature set matrix");
5088 for (i = 0; i < feature_sets; i++)
5089 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5090
5091 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5092 sizeof(u32) * feature_sets +
5093 NLMSG_HDRLEN);
5094
5095 if (reply_skb) {
5096 if (nla_put_u32(reply_skb,
5097 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5098 feature_sets) ||
5099 nla_put(reply_skb,
5100 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5101 sizeof(u32) * feature_sets, feature_set_matrix)) {
5102 hddLog(LOGE, FL("nla put fail"));
5103 kfree_skb(reply_skb);
5104 return -EINVAL;
5105 }
5106
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305107 ret = cfg80211_vendor_cmd_reply(reply_skb);
5108 EXIT();
5109 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305110 }
5111 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5112 return -ENOMEM;
5113
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305114}
5115
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305116static int
5117wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5118 struct wireless_dev *wdev,
5119 const void *data, int data_len)
5120{
5121 int ret = 0;
5122
5123 vos_ssr_protect(__func__);
5124 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5125 data_len);
5126 vos_ssr_unprotect(__func__);
5127
5128 return ret;
5129}
5130
Agarwal Ashish738843c2014-09-25 12:27:56 +05305131static const struct nla_policy
5132wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5133 +1] =
5134{
5135 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5136};
5137
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305138static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305139 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305140 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305141 int data_len)
5142{
5143 struct net_device *dev = wdev->netdev;
5144 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5145 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5146 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5147 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5148 eHalStatus status;
5149 u32 dfsFlag = 0;
5150
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305151 ENTER();
5152
Agarwal Ashish738843c2014-09-25 12:27:56 +05305153 status = wlan_hdd_validate_context(pHddCtx);
5154 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305155 return -EINVAL;
5156 }
5157 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5158 data, data_len,
5159 wlan_hdd_set_no_dfs_flag_config_policy)) {
5160 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5161 return -EINVAL;
5162 }
5163
5164 /* Parse and fetch required bandwidth kbps */
5165 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5166 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5167 return -EINVAL;
5168 }
5169
5170 dfsFlag = nla_get_u32(
5171 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5172 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5173 dfsFlag);
5174
5175 pHddCtx->disable_dfs_flag = dfsFlag;
5176
5177 sme_disable_dfs_channel(hHal, dfsFlag);
5178 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305179
5180 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305181 return 0;
5182}
Atul Mittal115287b2014-07-08 13:26:33 +05305183
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305184static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5185 struct wireless_dev *wdev,
5186 const void *data,
5187 int data_len)
5188{
5189 int ret = 0;
5190
5191 vos_ssr_protect(__func__);
5192 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5193 vos_ssr_unprotect(__func__);
5194
5195 return ret;
5196
5197}
5198
Mukul Sharma2a271632014-10-13 14:59:01 +05305199const struct
5200nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5201{
5202 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5203 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5204};
5205
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305206static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305207 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305208{
5209
5210 u8 bssid[6] = {0};
5211 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5212 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5213 eHalStatus status = eHAL_STATUS_SUCCESS;
5214 v_U32_t isFwrRoamEnabled = FALSE;
5215 int ret;
5216
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305217 ENTER();
5218
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305219 ret = wlan_hdd_validate_context(pHddCtx);
5220 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305221 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305222 }
5223
5224 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5225 data, data_len,
5226 qca_wlan_vendor_attr);
5227 if (ret){
5228 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5229 return -EINVAL;
5230 }
5231
5232 /* Parse and fetch Enable flag */
5233 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5234 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5235 return -EINVAL;
5236 }
5237
5238 isFwrRoamEnabled = nla_get_u32(
5239 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5240
5241 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5242
5243 /* Parse and fetch bssid */
5244 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5245 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5246 return -EINVAL;
5247 }
5248
5249 memcpy(bssid, nla_data(
5250 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5251 sizeof(bssid));
5252 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5253
5254 //Update roaming
5255 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305256 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305257 return status;
5258}
5259
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305260static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5261 struct wireless_dev *wdev, const void *data, int data_len)
5262{
5263 int ret = 0;
5264
5265 vos_ssr_protect(__func__);
5266 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5267 vos_ssr_unprotect(__func__);
5268
5269 return ret;
5270}
5271
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305272/**
5273 * __wlan_hdd_cfg80211_setband() - set band
5274 * @wiphy: Pointer to wireless phy
5275 * @wdev: Pointer to wireless device
5276 * @data: Pointer to data
5277 * @data_len: Data length
5278 *
5279 * Return: 0 on success, negative errno on failure
5280 */
5281static int
5282__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5283 struct wireless_dev *wdev,
5284 const void *data,
5285 int data_len)
5286{
5287 struct net_device *dev = wdev->netdev;
5288 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5289 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5290 int ret;
5291 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
5292 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
5293
5294 ENTER();
5295
5296 ret = wlan_hdd_validate_context(hdd_ctx);
5297 if (0 != ret) {
5298 hddLog(LOGE, FL("HDD context is not valid"));
5299 return ret;
5300 }
5301
5302 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
5303 policy)) {
5304 hddLog(LOGE, FL("Invalid ATTR"));
5305 return -EINVAL;
5306 }
5307
5308 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
5309 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
5310 return -EINVAL;
5311 }
5312
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305313 hdd_ctx->isSetBandByNL = TRUE;
5314 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305315 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305316 hdd_ctx->isSetBandByNL = FALSE;
5317
5318 EXIT();
5319 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305320}
5321
5322/**
5323 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
5324 * @wiphy: wiphy structure pointer
5325 * @wdev: Wireless device structure pointer
5326 * @data: Pointer to the data received
5327 * @data_len: Length of @data
5328 *
5329 * Return: 0 on success; errno on failure
5330 */
5331static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5332 struct wireless_dev *wdev,
5333 const void *data,
5334 int data_len)
5335{
5336 int ret = 0;
5337
5338 vos_ssr_protect(__func__);
5339 ret = __wlan_hdd_cfg80211_setband(wiphy,
5340 wdev, data, data_len);
5341 vos_ssr_unprotect(__func__);
5342
5343 return ret;
5344}
5345
Sunil Duttc69bccb2014-05-26 21:30:20 +05305346const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
5347{
Mukul Sharma2a271632014-10-13 14:59:01 +05305348 {
5349 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5350 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
5351 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5352 WIPHY_VENDOR_CMD_NEED_NETDEV |
5353 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305354 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05305355 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305356
5357 {
5358 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5359 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
5360 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5361 WIPHY_VENDOR_CMD_NEED_NETDEV |
5362 WIPHY_VENDOR_CMD_NEED_RUNNING,
5363 .doit = wlan_hdd_cfg80211_nan_request
5364 },
5365
Sunil Duttc69bccb2014-05-26 21:30:20 +05305366#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5367 {
5368 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5369 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
5370 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5371 WIPHY_VENDOR_CMD_NEED_NETDEV |
5372 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305373 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05305374 },
5375
5376 {
5377 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5378 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
5379 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5380 WIPHY_VENDOR_CMD_NEED_NETDEV |
5381 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305382 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05305383 },
5384
5385 {
5386 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5387 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
5388 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5389 WIPHY_VENDOR_CMD_NEED_NETDEV |
5390 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305391 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05305392 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305393#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305394#ifdef WLAN_FEATURE_EXTSCAN
5395 {
5396 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5397 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
5398 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5399 WIPHY_VENDOR_CMD_NEED_NETDEV |
5400 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305401 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05305402 },
5403 {
5404 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5405 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
5406 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5407 WIPHY_VENDOR_CMD_NEED_NETDEV |
5408 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305409 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05305410 },
5411 {
5412 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5413 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
5414 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5415 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305416 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05305417 },
5418 {
5419 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5420 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
5421 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5422 WIPHY_VENDOR_CMD_NEED_NETDEV |
5423 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305424 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05305425 },
5426 {
5427 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5428 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
5429 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5430 WIPHY_VENDOR_CMD_NEED_NETDEV |
5431 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305432 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05305433 },
5434 {
5435 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5436 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
5437 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5438 WIPHY_VENDOR_CMD_NEED_NETDEV |
5439 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305440 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305441 },
5442 {
5443 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5444 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
5445 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5446 WIPHY_VENDOR_CMD_NEED_NETDEV |
5447 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305448 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305449 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05305450#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305451/*EXT TDLS*/
5452 {
5453 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5454 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
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_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05305459 },
5460 {
5461 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5462 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
5463 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5464 WIPHY_VENDOR_CMD_NEED_NETDEV |
5465 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305466 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05305467 },
5468 {
5469 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5470 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
5471 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5472 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305473 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05305474 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05305475 {
5476 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5477 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
5478 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5479 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305480 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05305481 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05305482 {
5483 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5484 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
5485 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5486 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305487 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05305488 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305489 {
5490 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5491 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
5492 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5493 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305494 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305495 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305496 {
5497 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5498 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
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_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305502 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305503 {
5504 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5505 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
5506 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5507 WIPHY_VENDOR_CMD_NEED_NETDEV |
5508 WIPHY_VENDOR_CMD_NEED_RUNNING,
5509 .doit = wlan_hdd_cfg80211_setband
5510 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05305511};
5512
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005513/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05305514static const
5515struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005516{
5517#ifdef FEATURE_WLAN_CH_AVOID
5518 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05305519 .vendor_id = QCA_NL80211_VENDOR_ID,
5520 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005521 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305522#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
5523#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5524 {
5525 /* Index = 1*/
5526 .vendor_id = QCA_NL80211_VENDOR_ID,
5527 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
5528 },
5529 {
5530 /* Index = 2*/
5531 .vendor_id = QCA_NL80211_VENDOR_ID,
5532 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
5533 },
5534 {
5535 /* Index = 3*/
5536 .vendor_id = QCA_NL80211_VENDOR_ID,
5537 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
5538 },
5539 {
5540 /* Index = 4*/
5541 .vendor_id = QCA_NL80211_VENDOR_ID,
5542 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
5543 },
5544 {
5545 /* Index = 5*/
5546 .vendor_id = QCA_NL80211_VENDOR_ID,
5547 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
5548 },
5549 {
5550 /* Index = 6*/
5551 .vendor_id = QCA_NL80211_VENDOR_ID,
5552 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
5553 },
5554#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305555#ifdef WLAN_FEATURE_EXTSCAN
5556 {
5557 .vendor_id = QCA_NL80211_VENDOR_ID,
5558 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
5559 },
5560 {
5561 .vendor_id = QCA_NL80211_VENDOR_ID,
5562 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
5563 },
5564 {
5565 .vendor_id = QCA_NL80211_VENDOR_ID,
5566 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
5567 },
5568 {
5569 .vendor_id = QCA_NL80211_VENDOR_ID,
5570 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
5571 },
5572 {
5573 .vendor_id = QCA_NL80211_VENDOR_ID,
5574 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
5575 },
5576 {
5577 .vendor_id = QCA_NL80211_VENDOR_ID,
5578 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
5579 },
5580 {
5581 .vendor_id = QCA_NL80211_VENDOR_ID,
5582 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
5583 },
5584 {
5585 .vendor_id = QCA_NL80211_VENDOR_ID,
5586 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
5587 },
5588 {
5589 .vendor_id = QCA_NL80211_VENDOR_ID,
5590 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
5591 },
5592 {
5593 .vendor_id = QCA_NL80211_VENDOR_ID,
5594 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
5595 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05305596#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305597/*EXT TDLS*/
5598 {
5599 .vendor_id = QCA_NL80211_VENDOR_ID,
5600 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
5601 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305602
5603 {
5604 .vendor_id = QCA_NL80211_VENDOR_ID,
5605 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
5606 },
5607
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005608};
5609
Jeff Johnson295189b2012-06-20 16:38:30 -07005610/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305611 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305612 * This function is called by hdd_wlan_startup()
5613 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305614 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07005615 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305616struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07005617{
5618 struct wiphy *wiphy;
5619 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305620 /*
5621 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07005622 */
5623 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
5624
5625 if (!wiphy)
5626 {
5627 /* Print error and jump into err label and free the memory */
5628 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
5629 return NULL;
5630 }
5631
Sunil Duttc69bccb2014-05-26 21:30:20 +05305632
Jeff Johnson295189b2012-06-20 16:38:30 -07005633 return wiphy;
5634}
5635
5636/*
5637 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305638 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07005639 * private ioctl to change the band value
5640 */
5641int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
5642{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305643 int i, j;
5644 eNVChannelEnabledType channelEnabledState;
5645
Jeff Johnsone7245742012-09-05 17:12:55 -07005646 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305647
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305648 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005649 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305650
5651 if (NULL == wiphy->bands[i])
5652 {
5653 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5654 __func__, i);
5655 continue;
5656 }
5657
5658 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5659 {
5660 struct ieee80211_supported_band *band = wiphy->bands[i];
5661
5662 channelEnabledState = vos_nv_getChannelEnabledState(
5663 band->channels[j].hw_value);
5664
5665 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
5666 {
Abhishek Singh678227a2014-11-04 10:52:38 +05305667 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305668 continue;
5669 }
5670 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
5671 {
5672 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5673 continue;
5674 }
5675
5676 if (NV_CHANNEL_DISABLE == channelEnabledState ||
5677 NV_CHANNEL_INVALID == channelEnabledState)
5678 {
5679 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5680 }
5681 else if (NV_CHANNEL_DFS == channelEnabledState)
5682 {
5683 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5684 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
5685 }
5686 else
5687 {
5688 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
5689 |IEEE80211_CHAN_RADAR);
5690 }
5691 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005692 }
5693 return 0;
5694}
5695/*
5696 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305697 * This function is called by hdd_wlan_startup()
5698 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005699 * This function is used to initialize and register wiphy structure.
5700 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305701int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005702 struct wiphy *wiphy,
5703 hdd_config_t *pCfg
5704 )
5705{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305706 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305707 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5708
Jeff Johnsone7245742012-09-05 17:12:55 -07005709 ENTER();
5710
Jeff Johnson295189b2012-06-20 16:38:30 -07005711 /* Now bind the underlying wlan device with wiphy */
5712 set_wiphy_dev(wiphy, dev);
5713
5714 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005715
Kiet Lam6c583332013-10-14 05:37:09 +05305716#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005717 /* the flag for the other case would be initialzed in
5718 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005719 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305720#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005721
Amar Singhalfddc28c2013-09-05 13:03:40 -07005722 /* This will disable updating of NL channels from passive to
5723 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05305724#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
5725 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
5726#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07005727 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05305728#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07005729
Amar Singhala49cbc52013-10-08 18:37:44 -07005730
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005731#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005732 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5733 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5734 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005735 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05305736#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
5737 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
5738#else
5739 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
5740#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005741#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005742
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005743#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005744 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005745#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005746 || pCfg->isFastRoamIniFeatureEnabled
5747#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005748#ifdef FEATURE_WLAN_ESE
5749 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005750#endif
5751 )
5752 {
5753 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5754 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005755#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005756#ifdef FEATURE_WLAN_TDLS
5757 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5758 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5759#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305760#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305761 if (pCfg->configPNOScanSupport)
5762 {
5763 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5764 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5765 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5766 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5767 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305768#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005769
Abhishek Singh10d85972015-04-17 10:27:23 +05305770#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5771 wiphy->features |= NL80211_FEATURE_HT_IBSS;
5772#endif
5773
Amar Singhalfddc28c2013-09-05 13:03:40 -07005774#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005775 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5776 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005777 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005778 driver need to determine what to do with both
5779 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005780
5781 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005782#else
5783 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005784#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005785
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305786 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5787
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05305788 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005789
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305790 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5791
Jeff Johnson295189b2012-06-20 16:38:30 -07005792 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05305793 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
5794 | BIT(NL80211_IFTYPE_ADHOC)
5795 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5796 | BIT(NL80211_IFTYPE_P2P_GO)
5797 | BIT(NL80211_IFTYPE_AP);
5798
5799 if (VOS_MONITOR_MODE == hdd_get_conparam())
5800 {
5801 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
5802 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005803
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305804 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005805 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305806#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5807 if( pCfg->enableMCC )
5808 {
5809 /* Currently, supports up to two channels */
5810 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005811
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305812 if( !pCfg->allowMCCGODiffBI )
5813 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005814
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305815 }
5816 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5817 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005818#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305819 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005820
Jeff Johnson295189b2012-06-20 16:38:30 -07005821 /* Before registering we need to update the ht capabilitied based
5822 * on ini values*/
5823 if( !pCfg->ShortGI20MhzEnable )
5824 {
5825 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5826 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5827 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5828 }
5829
5830 if( !pCfg->ShortGI40MhzEnable )
5831 {
5832 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5833 }
5834
5835 if( !pCfg->nChannelBondingMode5GHz )
5836 {
5837 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5838 }
5839
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305840 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305841 if (true == hdd_is_5g_supported(pHddCtx))
5842 {
5843 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5844 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305845
5846 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5847 {
5848
5849 if (NULL == wiphy->bands[i])
5850 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305851 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305852 __func__, i);
5853 continue;
5854 }
5855
5856 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5857 {
5858 struct ieee80211_supported_band *band = wiphy->bands[i];
5859
5860 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5861 {
5862 // Enable social channels for P2P
5863 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5864 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5865 else
5866 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5867 continue;
5868 }
5869 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5870 {
5871 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5872 continue;
5873 }
5874 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005875 }
5876 /*Initialise the supported cipher suite details*/
5877 wiphy->cipher_suites = hdd_cipher_suites;
5878 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5879
5880 /*signal strength in mBm (100*dBm) */
5881 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5882
5883#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305884 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005885#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005886
Sunil Duttc69bccb2014-05-26 21:30:20 +05305887 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
5888 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005889 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
5890 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
5891
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305892 EXIT();
5893 return 0;
5894}
5895
5896/* In this function we are registering wiphy. */
5897int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
5898{
5899 ENTER();
5900 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005901 if (0 > wiphy_register(wiphy))
5902 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305903 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07005904 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
5905 return -EIO;
5906 }
5907
5908 EXIT();
5909 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305910}
Jeff Johnson295189b2012-06-20 16:38:30 -07005911
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305912/* In this function we are updating channel list when,
5913 regulatory domain is FCC and country code is US.
5914 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
5915 As per FCC smart phone is not a indoor device.
5916 GO should not opeate on indoor channels */
5917void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
5918{
5919 int j;
5920 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5921 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
5922 //Default counrtycode from NV at the time of wiphy initialization.
5923 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
5924 &defaultCountryCode[0]))
5925 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005926 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305927 }
5928 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
5929 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305930 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
5931 {
5932 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
5933 return;
5934 }
5935 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
5936 {
5937 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
5938 // Mark UNII -1 band channel as passive
5939 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
5940 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
5941 }
5942 }
5943}
5944
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305945/* This function registers for all frame which supplicant is interested in */
5946void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005947{
Jeff Johnson295189b2012-06-20 16:38:30 -07005948 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5949 /* Register for all P2P action, public action etc frames */
5950 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5951
Jeff Johnsone7245742012-09-05 17:12:55 -07005952 ENTER();
5953
Jeff Johnson295189b2012-06-20 16:38:30 -07005954 /* Right now we are registering these frame when driver is getting
5955 initialized. Once we will move to 2.6.37 kernel, in which we have
5956 frame register ops, we will move this code as a part of that */
5957 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305958 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07005959 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5960
5961 /* GAS Initial Response */
5962 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5963 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305964
Jeff Johnson295189b2012-06-20 16:38:30 -07005965 /* GAS Comeback Request */
5966 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5967 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5968
5969 /* GAS Comeback Response */
5970 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5971 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5972
5973 /* P2P Public Action */
5974 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305975 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005976 P2P_PUBLIC_ACTION_FRAME_SIZE );
5977
5978 /* P2P Action */
5979 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5980 (v_U8_t*)P2P_ACTION_FRAME,
5981 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07005982
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05305983 /* WNM BSS Transition Request frame */
5984 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5985 (v_U8_t*)WNM_BSS_ACTION_FRAME,
5986 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005987
5988 /* WNM-Notification */
5989 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5990 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5991 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005992}
5993
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305994void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005995{
Jeff Johnson295189b2012-06-20 16:38:30 -07005996 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5997 /* Register for all P2P action, public action etc frames */
5998 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5999
Jeff Johnsone7245742012-09-05 17:12:55 -07006000 ENTER();
6001
Jeff Johnson295189b2012-06-20 16:38:30 -07006002 /* Right now we are registering these frame when driver is getting
6003 initialized. Once we will move to 2.6.37 kernel, in which we have
6004 frame register ops, we will move this code as a part of that */
6005 /* GAS Initial Request */
6006
6007 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6008 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6009
6010 /* GAS Initial Response */
6011 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6012 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306013
Jeff Johnson295189b2012-06-20 16:38:30 -07006014 /* GAS Comeback Request */
6015 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6016 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6017
6018 /* GAS Comeback Response */
6019 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6020 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6021
6022 /* P2P Public Action */
6023 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306024 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006025 P2P_PUBLIC_ACTION_FRAME_SIZE );
6026
6027 /* P2P Action */
6028 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6029 (v_U8_t*)P2P_ACTION_FRAME,
6030 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006031 /* WNM-Notification */
6032 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6033 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6034 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006035}
6036
6037#ifdef FEATURE_WLAN_WAPI
6038void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05306039 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006040{
6041 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6042 tCsrRoamSetKey setKey;
6043 v_BOOL_t isConnected = TRUE;
6044 int status = 0;
6045 v_U32_t roamId= 0xFF;
6046 tANI_U8 *pKeyPtr = NULL;
6047 int n = 0;
6048
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306049 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6050 __func__, hdd_device_modetoString(pAdapter->device_mode),
6051 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006052
Gopichand Nakkalae7480202013-02-11 15:24:22 +05306053 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006054 setKey.keyId = key_index; // Store Key ID
6055 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
6056 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
6057 setKey.paeRole = 0 ; // the PAE role
6058 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
6059 {
6060 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
6061 }
6062 else
6063 {
6064 isConnected = hdd_connIsConnected(pHddStaCtx);
6065 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
6066 }
6067 setKey.keyLength = key_Len;
6068 pKeyPtr = setKey.Key;
6069 memcpy( pKeyPtr, key, key_Len);
6070
Arif Hussain6d2a3322013-11-17 19:50:10 -08006071 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07006072 __func__, key_Len);
6073 for (n = 0 ; n < key_Len; n++)
6074 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
6075 __func__,n,setKey.Key[n]);
6076
6077 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
6078 if ( isConnected )
6079 {
6080 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
6081 pAdapter->sessionId, &setKey, &roamId );
6082 }
6083 if ( status != 0 )
6084 {
6085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6086 "[%4d] sme_RoamSetKey returned ERROR status= %d",
6087 __LINE__, status );
6088 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
6089 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05306090 /* Need to clear any trace of key value in the memory.
6091 * Thus zero out the memory even though it is local
6092 * variable.
6093 */
6094 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006095}
6096#endif /* FEATURE_WLAN_WAPI*/
6097
6098#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306099int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006100 beacon_data_t **ppBeacon,
6101 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006102#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306103int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006104 beacon_data_t **ppBeacon,
6105 struct cfg80211_beacon_data *params,
6106 int dtim_period)
6107#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306108{
Jeff Johnson295189b2012-06-20 16:38:30 -07006109 int size;
6110 beacon_data_t *beacon = NULL;
6111 beacon_data_t *old = NULL;
6112 int head_len,tail_len;
6113
Jeff Johnsone7245742012-09-05 17:12:55 -07006114 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006115 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306116 {
6117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6118 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006119 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306120 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006121
6122 old = pAdapter->sessionCtx.ap.beacon;
6123
6124 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306125 {
6126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6127 FL("session(%d) old and new heads points to NULL"),
6128 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006129 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306130 }
6131
6132 if (params->tail && !params->tail_len)
6133 {
6134 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6135 FL("tail_len is zero but tail is not NULL"));
6136 return -EINVAL;
6137 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006138
Jeff Johnson295189b2012-06-20 16:38:30 -07006139#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
6140 /* Kernel 3.0 is not updating dtim_period for set beacon */
6141 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306142 {
6143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6144 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006145 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306146 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006147#endif
6148
6149 if(params->head)
6150 head_len = params->head_len;
6151 else
6152 head_len = old->head_len;
6153
6154 if(params->tail || !old)
6155 tail_len = params->tail_len;
6156 else
6157 tail_len = old->tail_len;
6158
6159 size = sizeof(beacon_data_t) + head_len + tail_len;
6160
6161 beacon = kzalloc(size, GFP_KERNEL);
6162
6163 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306164 {
6165 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6166 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006167 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306168 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006169
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006170#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006171 if(params->dtim_period || !old )
6172 beacon->dtim_period = params->dtim_period;
6173 else
6174 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006175#else
6176 if(dtim_period || !old )
6177 beacon->dtim_period = dtim_period;
6178 else
6179 beacon->dtim_period = old->dtim_period;
6180#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306181
Jeff Johnson295189b2012-06-20 16:38:30 -07006182 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6183 beacon->tail = beacon->head + head_len;
6184 beacon->head_len = head_len;
6185 beacon->tail_len = tail_len;
6186
6187 if(params->head) {
6188 memcpy (beacon->head,params->head,beacon->head_len);
6189 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306190 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07006191 if(old)
6192 memcpy (beacon->head,old->head,beacon->head_len);
6193 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306194
Jeff Johnson295189b2012-06-20 16:38:30 -07006195 if(params->tail) {
6196 memcpy (beacon->tail,params->tail,beacon->tail_len);
6197 }
6198 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306199 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07006200 memcpy (beacon->tail,old->tail,beacon->tail_len);
6201 }
6202
6203 *ppBeacon = beacon;
6204
6205 kfree(old);
6206
6207 return 0;
6208
6209}
Jeff Johnson295189b2012-06-20 16:38:30 -07006210
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306211v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
6212#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6213 const v_U8_t *pIes,
6214#else
6215 v_U8_t *pIes,
6216#endif
6217 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006218{
6219 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306220 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07006221 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306222
Jeff Johnson295189b2012-06-20 16:38:30 -07006223 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306224 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006225 elem_id = ptr[0];
6226 elem_len = ptr[1];
6227 left -= 2;
6228 if(elem_len > left)
6229 {
6230 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006231 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006232 eid,elem_len,left);
6233 return NULL;
6234 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306235 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006236 {
6237 return ptr;
6238 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306239
Jeff Johnson295189b2012-06-20 16:38:30 -07006240 left -= elem_len;
6241 ptr += (elem_len + 2);
6242 }
6243 return NULL;
6244}
6245
Jeff Johnson295189b2012-06-20 16:38:30 -07006246/* Check if rate is 11g rate or not */
6247static int wlan_hdd_rate_is_11g(u8 rate)
6248{
Sanjay Devnani28322e22013-06-21 16:13:40 -07006249 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006250 u8 i;
6251 for (i = 0; i < 8; i++)
6252 {
6253 if(rate == gRateArray[i])
6254 return TRUE;
6255 }
6256 return FALSE;
6257}
6258
6259/* Check for 11g rate and set proper 11g only mode */
6260static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
6261 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
6262{
6263 u8 i, num_rates = pIe[0];
6264
6265 pIe += 1;
6266 for ( i = 0; i < num_rates; i++)
6267 {
6268 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
6269 {
6270 /* If rate set have 11g rate than change the mode to 11G */
6271 *pSapHw_mode = eSAP_DOT11_MODE_11g;
6272 if (pIe[i] & BASIC_RATE_MASK)
6273 {
6274 /* If we have 11g rate as basic rate, it means mode
6275 is 11g only mode.
6276 */
6277 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
6278 *pCheckRatesfor11g = FALSE;
6279 }
6280 }
6281 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6282 {
6283 *require_ht = TRUE;
6284 }
6285 }
6286 return;
6287}
6288
6289static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
6290{
6291 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6292 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6293 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6294 u8 checkRatesfor11g = TRUE;
6295 u8 require_ht = FALSE;
6296 u8 *pIe=NULL;
6297
6298 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
6299
6300 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6301 pBeacon->head_len, WLAN_EID_SUPP_RATES);
6302 if (pIe != NULL)
6303 {
6304 pIe += 1;
6305 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6306 &pConfig->SapHw_mode);
6307 }
6308
6309 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6310 WLAN_EID_EXT_SUPP_RATES);
6311 if (pIe != NULL)
6312 {
6313
6314 pIe += 1;
6315 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6316 &pConfig->SapHw_mode);
6317 }
6318
6319 if( pConfig->channel > 14 )
6320 {
6321 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
6322 }
6323
6324 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6325 WLAN_EID_HT_CAPABILITY);
6326
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306327 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006328 {
6329 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
6330 if(require_ht)
6331 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
6332 }
6333}
6334
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306335static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
6336 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
6337{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006338 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306339 v_U8_t *pIe = NULL;
6340 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6341
6342 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6343 pBeacon->tail, pBeacon->tail_len);
6344
6345 if (pIe)
6346 {
6347 ielen = pIe[1] + 2;
6348 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6349 {
6350 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
6351 }
6352 else
6353 {
6354 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
6355 return -EINVAL;
6356 }
6357 *total_ielen += ielen;
6358 }
6359 return 0;
6360}
6361
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006362static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
6363 v_U8_t *genie, v_U8_t *total_ielen)
6364{
6365 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6366 int left = pBeacon->tail_len;
6367 v_U8_t *ptr = pBeacon->tail;
6368 v_U8_t elem_id, elem_len;
6369 v_U16_t ielen = 0;
6370
6371 if ( NULL == ptr || 0 == left )
6372 return;
6373
6374 while (left >= 2)
6375 {
6376 elem_id = ptr[0];
6377 elem_len = ptr[1];
6378 left -= 2;
6379 if (elem_len > left)
6380 {
6381 hddLog( VOS_TRACE_LEVEL_ERROR,
6382 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
6383 elem_id, elem_len, left);
6384 return;
6385 }
6386 if (IE_EID_VENDOR == elem_id)
6387 {
6388 /* skipping the VSIE's which we don't want to include or
6389 * it will be included by existing code
6390 */
6391 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
6392#ifdef WLAN_FEATURE_WFD
6393 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
6394#endif
6395 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6396 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6397 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
6398 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6399 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
6400 {
6401 ielen = ptr[1] + 2;
6402 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6403 {
6404 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
6405 *total_ielen += ielen;
6406 }
6407 else
6408 {
6409 hddLog( VOS_TRACE_LEVEL_ERROR,
6410 "IE Length is too big "
6411 "IEs eid=%d elem_len=%d total_ie_lent=%d",
6412 elem_id, elem_len, *total_ielen);
6413 }
6414 }
6415 }
6416
6417 left -= elem_len;
6418 ptr += (elem_len + 2);
6419 }
6420 return;
6421}
6422
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006423#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006424static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6425 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006426#else
6427static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6428 struct cfg80211_beacon_data *params)
6429#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006430{
6431 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306432 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006433 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07006434 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006435
6436 genie = vos_mem_malloc(MAX_GENIE_LEN);
6437
6438 if(genie == NULL) {
6439
6440 return -ENOMEM;
6441 }
6442
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306443 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6444 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006445 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306446 hddLog(LOGE,
6447 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306448 ret = -EINVAL;
6449 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006450 }
6451
6452#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306453 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6454 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
6455 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306456 hddLog(LOGE,
6457 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306458 ret = -EINVAL;
6459 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006460 }
6461#endif
6462
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306463 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6464 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006465 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306466 hddLog(LOGE,
6467 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306468 ret = -EINVAL;
6469 goto done;
6470 }
6471
6472 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
6473 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006474 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07006475 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006476
6477 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6478 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
6479 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6480 {
6481 hddLog(LOGE,
6482 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006483 ret = -EINVAL;
6484 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006485 }
6486
6487 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6488 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6489 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6490 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6491 ==eHAL_STATUS_FAILURE)
6492 {
6493 hddLog(LOGE,
6494 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006495 ret = -EINVAL;
6496 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006497 }
6498
6499 // Added for ProResp IE
6500 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
6501 {
6502 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
6503 u8 probe_rsp_ie_len[3] = {0};
6504 u8 counter = 0;
6505 /* Check Probe Resp Length if it is greater then 255 then Store
6506 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
6507 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
6508 Store More then 255 bytes into One Variable.
6509 */
6510 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6511 {
6512 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6513 {
6514 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6515 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6516 }
6517 else
6518 {
6519 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6520 rem_probe_resp_ie_len = 0;
6521 }
6522 }
6523
6524 rem_probe_resp_ie_len = 0;
6525
6526 if (probe_rsp_ie_len[0] > 0)
6527 {
6528 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6529 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6530 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6531 probe_rsp_ie_len[0], NULL,
6532 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6533 {
6534 hddLog(LOGE,
6535 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006536 ret = -EINVAL;
6537 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006538 }
6539 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6540 }
6541
6542 if (probe_rsp_ie_len[1] > 0)
6543 {
6544 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6545 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6546 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6547 probe_rsp_ie_len[1], NULL,
6548 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6549 {
6550 hddLog(LOGE,
6551 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006552 ret = -EINVAL;
6553 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006554 }
6555 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6556 }
6557
6558 if (probe_rsp_ie_len[2] > 0)
6559 {
6560 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6561 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6562 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6563 probe_rsp_ie_len[2], NULL,
6564 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6565 {
6566 hddLog(LOGE,
6567 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006568 ret = -EINVAL;
6569 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006570 }
6571 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6572 }
6573
6574 if (probe_rsp_ie_len[1] == 0 )
6575 {
6576 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6577 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6578 eANI_BOOLEAN_FALSE) )
6579 {
6580 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006581 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006582 }
6583 }
6584
6585 if (probe_rsp_ie_len[2] == 0 )
6586 {
6587 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6588 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6589 eANI_BOOLEAN_FALSE) )
6590 {
6591 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006592 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006593 }
6594 }
6595
6596 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6597 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6598 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6599 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6600 == eHAL_STATUS_FAILURE)
6601 {
6602 hddLog(LOGE,
6603 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006604 ret = -EINVAL;
6605 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006606 }
6607 }
6608 else
6609 {
6610 // Reset WNI_CFG_PROBE_RSP Flags
6611 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
6612
6613 hddLog(VOS_TRACE_LEVEL_INFO,
6614 "%s: No Probe Response IE received in set beacon",
6615 __func__);
6616 }
6617
6618 // Added for AssocResp IE
6619 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
6620 {
6621 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6622 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
6623 params->assocresp_ies_len, NULL,
6624 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6625 {
6626 hddLog(LOGE,
6627 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006628 ret = -EINVAL;
6629 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006630 }
6631
6632 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6633 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
6634 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6635 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6636 == eHAL_STATUS_FAILURE)
6637 {
6638 hddLog(LOGE,
6639 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006640 ret = -EINVAL;
6641 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006642 }
6643 }
6644 else
6645 {
6646 hddLog(VOS_TRACE_LEVEL_INFO,
6647 "%s: No Assoc Response IE received in set beacon",
6648 __func__);
6649
6650 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6651 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6652 eANI_BOOLEAN_FALSE) )
6653 {
6654 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006655 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006656 }
6657 }
6658
Jeff Johnsone7245742012-09-05 17:12:55 -07006659done:
Jeff Johnson295189b2012-06-20 16:38:30 -07006660 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306661 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006662}
Jeff Johnson295189b2012-06-20 16:38:30 -07006663
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306664/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006665 * FUNCTION: wlan_hdd_validate_operation_channel
6666 * called by wlan_hdd_cfg80211_start_bss() and
6667 * wlan_hdd_cfg80211_set_channel()
6668 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306669 * channel list.
6670 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006671VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006672{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306673
Jeff Johnson295189b2012-06-20 16:38:30 -07006674 v_U32_t num_ch = 0;
6675 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6676 u32 indx = 0;
6677 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306678 v_U8_t fValidChannel = FALSE, count = 0;
6679 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306680
Jeff Johnson295189b2012-06-20 16:38:30 -07006681 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6682
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306683 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006684 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306685 /* Validate the channel */
6686 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006687 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306688 if ( channel == rfChannels[count].channelNum )
6689 {
6690 fValidChannel = TRUE;
6691 break;
6692 }
6693 }
6694 if (fValidChannel != TRUE)
6695 {
6696 hddLog(VOS_TRACE_LEVEL_ERROR,
6697 "%s: Invalid Channel [%d]", __func__, channel);
6698 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006699 }
6700 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306701 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006702 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306703 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6704 valid_ch, &num_ch))
6705 {
6706 hddLog(VOS_TRACE_LEVEL_ERROR,
6707 "%s: failed to get valid channel list", __func__);
6708 return VOS_STATUS_E_FAILURE;
6709 }
6710 for (indx = 0; indx < num_ch; indx++)
6711 {
6712 if (channel == valid_ch[indx])
6713 {
6714 break;
6715 }
6716 }
6717
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306718 if (indx >= num_ch)
6719 {
6720 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6721 {
6722 eCsrBand band;
6723 unsigned int freq;
6724
6725 sme_GetFreqBand(hHal, &band);
6726
6727 if (eCSR_BAND_5G == band)
6728 {
6729#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6730 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6731 {
6732 freq = ieee80211_channel_to_frequency(channel,
6733 IEEE80211_BAND_2GHZ);
6734 }
6735 else
6736 {
6737 freq = ieee80211_channel_to_frequency(channel,
6738 IEEE80211_BAND_5GHZ);
6739 }
6740#else
6741 freq = ieee80211_channel_to_frequency(channel);
6742#endif
6743 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6744 return VOS_STATUS_SUCCESS;
6745 }
6746 }
6747
6748 hddLog(VOS_TRACE_LEVEL_ERROR,
6749 "%s: Invalid Channel [%d]", __func__, channel);
6750 return VOS_STATUS_E_FAILURE;
6751 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006752 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306753
Jeff Johnson295189b2012-06-20 16:38:30 -07006754 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306755
Jeff Johnson295189b2012-06-20 16:38:30 -07006756}
6757
Viral Modi3a32cc52013-02-08 11:14:52 -08006758/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306759 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08006760 * This function is used to set the channel number
6761 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306762static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08006763 struct ieee80211_channel *chan,
6764 enum nl80211_channel_type channel_type
6765 )
6766{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306767 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006768 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006769 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006770 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306771 hdd_context_t *pHddCtx;
6772 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006773
6774 ENTER();
6775
6776 if( NULL == dev )
6777 {
6778 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006779 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006780 return -ENODEV;
6781 }
6782 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306783
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306784 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6785 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6786 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006787 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306788 "%s: device_mode = %s (%d) freq = %d", __func__,
6789 hdd_device_modetoString(pAdapter->device_mode),
6790 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306791
6792 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6793 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306794 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006795 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306796 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006797 }
6798
6799 /*
6800 * Do freq to chan conversion
6801 * TODO: for 11a
6802 */
6803
6804 channel = ieee80211_frequency_to_channel(freq);
6805
6806 /* Check freq range */
6807 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6808 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6809 {
6810 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006811 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006812 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6813 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6814 return -EINVAL;
6815 }
6816
6817 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6818
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306819 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6820 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006821 {
6822 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6823 {
6824 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006825 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006826 return -EINVAL;
6827 }
6828 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6829 "%s: set channel to [%d] for device mode =%d",
6830 __func__, channel,pAdapter->device_mode);
6831 }
6832 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006833 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006834 )
6835 {
6836 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6837 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6838 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6839
6840 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6841 {
6842 /* Link is up then return cant set channel*/
6843 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006844 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006845 return -EINVAL;
6846 }
6847
6848 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6849 pHddStaCtx->conn_info.operationChannel = channel;
6850 pRoamProfile->ChannelInfo.ChannelList =
6851 &pHddStaCtx->conn_info.operationChannel;
6852 }
6853 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006854 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006855 )
6856 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306857 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6858 {
6859 if(VOS_STATUS_SUCCESS !=
6860 wlan_hdd_validate_operation_channel(pAdapter,channel))
6861 {
6862 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006863 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306864 return -EINVAL;
6865 }
6866 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6867 }
6868 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006869 {
6870 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6871
6872 /* If auto channel selection is configured as enable/ 1 then ignore
6873 channel set by supplicant
6874 */
6875 if ( cfg_param->apAutoChannelSelection )
6876 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306877 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6878 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006879 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306880 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6881 __func__, hdd_device_modetoString(pAdapter->device_mode),
6882 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006883 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306884 else
6885 {
6886 if(VOS_STATUS_SUCCESS !=
6887 wlan_hdd_validate_operation_channel(pAdapter,channel))
6888 {
6889 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006890 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306891 return -EINVAL;
6892 }
6893 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6894 }
Viral Modi3a32cc52013-02-08 11:14:52 -08006895 }
6896 }
6897 else
6898 {
6899 hddLog(VOS_TRACE_LEVEL_FATAL,
6900 "%s: Invalid device mode failed to set valid channel", __func__);
6901 return -EINVAL;
6902 }
6903 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306904 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006905}
6906
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306907static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
6908 struct net_device *dev,
6909 struct ieee80211_channel *chan,
6910 enum nl80211_channel_type channel_type
6911 )
6912{
6913 int ret;
6914
6915 vos_ssr_protect(__func__);
6916 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
6917 vos_ssr_unprotect(__func__);
6918
6919 return ret;
6920}
6921
Jeff Johnson295189b2012-06-20 16:38:30 -07006922#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6923static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6924 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006925#else
6926static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6927 struct cfg80211_beacon_data *params,
6928 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05306929 enum nl80211_hidden_ssid hidden_ssid,
6930 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006931#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006932{
6933 tsap_Config_t *pConfig;
6934 beacon_data_t *pBeacon = NULL;
6935 struct ieee80211_mgmt *pMgmt_frame;
6936 v_U8_t *pIe=NULL;
6937 v_U16_t capab_info;
6938 eCsrAuthType RSNAuthType;
6939 eCsrEncryptionType RSNEncryptType;
6940 eCsrEncryptionType mcRSNEncryptType;
6941 int status = VOS_STATUS_SUCCESS;
6942 tpWLAN_SAPEventCB pSapEventCallback;
6943 hdd_hostapd_state_t *pHostapdState;
6944 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
6945 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306946 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006947 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306948 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07006949 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08006950 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05306951 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07006952 v_BOOL_t MFPCapable = VOS_FALSE;
6953 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05306954 v_BOOL_t sapEnable11AC =
6955 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07006956 ENTER();
6957
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306958 iniConfig = pHddCtx->cfg_ini;
6959
Jeff Johnson295189b2012-06-20 16:38:30 -07006960 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
6961
6962 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6963
6964 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6965
6966 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6967
6968 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
6969
6970 //channel is already set in the set_channel Call back
6971 //pConfig->channel = pCommitConfig->channel;
6972
6973 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306974 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07006975 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
6976
6977 pConfig->dtim_period = pBeacon->dtim_period;
6978
Arif Hussain6d2a3322013-11-17 19:50:10 -08006979 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07006980 pConfig->dtim_period);
6981
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08006982 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07006983 {
6984 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006985 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05306986 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
6987 {
6988 tANI_BOOLEAN restartNeeded;
6989 pConfig->ieee80211d = 1;
6990 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
6991 sme_setRegInfo(hHal, pConfig->countryCode);
6992 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
6993 }
6994 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006995 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07006996 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07006997 pConfig->ieee80211d = 1;
6998 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
6999 sme_setRegInfo(hHal, pConfig->countryCode);
7000 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07007001 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007002 else
7003 {
7004 pConfig->ieee80211d = 0;
7005 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307006 /*
7007 * If auto channel is configured i.e. channel is 0,
7008 * so skip channel validation.
7009 */
7010 if( AUTO_CHANNEL_SELECT != pConfig->channel )
7011 {
7012 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
7013 {
7014 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007015 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307016 return -EINVAL;
7017 }
7018 }
7019 else
7020 {
7021 if(1 != pHddCtx->is_dynamic_channel_range_set)
7022 {
7023 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
7024 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
7025 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
7026 }
7027 pHddCtx->is_dynamic_channel_range_set = 0;
7028 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007029 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007030 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007031 {
7032 pConfig->ieee80211d = 0;
7033 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307034
7035#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7036 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7037 pConfig->authType = eSAP_OPEN_SYSTEM;
7038 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7039 pConfig->authType = eSAP_SHARED_KEY;
7040 else
7041 pConfig->authType = eSAP_AUTO_SWITCH;
7042#else
7043 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7044 pConfig->authType = eSAP_OPEN_SYSTEM;
7045 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7046 pConfig->authType = eSAP_SHARED_KEY;
7047 else
7048 pConfig->authType = eSAP_AUTO_SWITCH;
7049#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007050
7051 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307052
7053 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07007054 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
7055
7056 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7057
7058 /*Set wps station to configured*/
7059 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7060
7061 if(pIe)
7062 {
7063 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
7064 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007065 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07007066 return -EINVAL;
7067 }
7068 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
7069 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007070 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07007071 /* Check 15 bit of WPS IE as it contain information for wps state
7072 * WPS state
7073 */
7074 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
7075 {
7076 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
7077 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
7078 {
7079 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7080 }
7081 }
7082 }
7083 else
7084 {
7085 pConfig->wps_state = SAP_WPS_DISABLED;
7086 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307087 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07007088
c_hpothufe599e92014-06-16 11:38:55 +05307089 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7090 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7091 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7092 eCSR_ENCRYPT_TYPE_NONE;
7093
Jeff Johnson295189b2012-06-20 16:38:30 -07007094 pConfig->RSNWPAReqIELength = 0;
7095 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307096 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007097 WLAN_EID_RSN);
7098 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307099 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007100 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7101 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7102 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307103 /* The actual processing may eventually be more extensive than
7104 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07007105 * by the app.
7106 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307107 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007108 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7109 &RSNEncryptType,
7110 &mcRSNEncryptType,
7111 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007112 &MFPCapable,
7113 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007114 pConfig->pRSNWPAReqIE[1]+2,
7115 pConfig->pRSNWPAReqIE );
7116
7117 if( VOS_STATUS_SUCCESS == status )
7118 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307119 /* Now copy over all the security attributes you have
7120 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007121 * */
7122 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7123 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7124 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7125 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307126 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007127 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007128 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7129 }
7130 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307131
Jeff Johnson295189b2012-06-20 16:38:30 -07007132 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7133 pBeacon->tail, pBeacon->tail_len);
7134
7135 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
7136 {
7137 if (pConfig->pRSNWPAReqIE)
7138 {
7139 /*Mixed mode WPA/WPA2*/
7140 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
7141 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7142 }
7143 else
7144 {
7145 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7146 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7147 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307148 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007149 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7150 &RSNEncryptType,
7151 &mcRSNEncryptType,
7152 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007153 &MFPCapable,
7154 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007155 pConfig->pRSNWPAReqIE[1]+2,
7156 pConfig->pRSNWPAReqIE );
7157
7158 if( VOS_STATUS_SUCCESS == status )
7159 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307160 /* Now copy over all the security attributes you have
7161 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007162 * */
7163 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7164 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7165 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7166 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307167 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007168 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007169 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7170 }
7171 }
7172 }
7173
Jeff Johnson4416a782013-03-25 14:17:50 -07007174 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
7175 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
7176 return -EINVAL;
7177 }
7178
Jeff Johnson295189b2012-06-20 16:38:30 -07007179 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
7180
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007181#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007182 if (params->ssid != NULL)
7183 {
7184 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
7185 pConfig->SSIDinfo.ssid.length = params->ssid_len;
7186 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7187 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7188 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007189#else
7190 if (ssid != NULL)
7191 {
7192 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
7193 pConfig->SSIDinfo.ssid.length = ssid_len;
7194 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7195 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7196 }
7197#endif
7198
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307199 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07007200 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307201
Jeff Johnson295189b2012-06-20 16:38:30 -07007202 /* default value */
7203 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7204 pConfig->num_accept_mac = 0;
7205 pConfig->num_deny_mac = 0;
7206
7207 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7208 pBeacon->tail, pBeacon->tail_len);
7209
7210 /* pIe for black list is following form:
7211 type : 1 byte
7212 length : 1 byte
7213 OUI : 4 bytes
7214 acl type : 1 byte
7215 no of mac addr in black list: 1 byte
7216 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307217 */
7218 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007219 {
7220 pConfig->SapMacaddr_acl = pIe[6];
7221 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007222 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007223 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307224 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7225 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007226 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7227 for (i = 0; i < pConfig->num_deny_mac; i++)
7228 {
7229 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7230 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307231 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007232 }
7233 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7234 pBeacon->tail, pBeacon->tail_len);
7235
7236 /* pIe for white list is following form:
7237 type : 1 byte
7238 length : 1 byte
7239 OUI : 4 bytes
7240 acl type : 1 byte
7241 no of mac addr in white list: 1 byte
7242 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307243 */
7244 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007245 {
7246 pConfig->SapMacaddr_acl = pIe[6];
7247 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007248 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007249 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307250 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7251 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007252 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7253 for (i = 0; i < pConfig->num_accept_mac; i++)
7254 {
7255 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7256 acl_entry++;
7257 }
7258 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307259
Jeff Johnson295189b2012-06-20 16:38:30 -07007260 wlan_hdd_set_sapHwmode(pHostapdAdapter);
7261
Jeff Johnsone7245742012-09-05 17:12:55 -07007262#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007263 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307264 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
7265 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05307266 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
7267 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007268 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
7269 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307270 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
7271 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07007272 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307273 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07007274 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307275 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007276
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307277 /* If ACS disable and selected channel <= 14
7278 * OR
7279 * ACS enabled and ACS operating band is choosen as 2.4
7280 * AND
7281 * VHT in 2.4G Disabled
7282 * THEN
7283 * Fallback to 11N mode
7284 */
7285 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
7286 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05307287 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307288 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007289 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307290 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
7291 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007292 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
7293 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007294 }
7295#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307296
Jeff Johnson295189b2012-06-20 16:38:30 -07007297 // ht_capab is not what the name conveys,this is used for protection bitmap
7298 pConfig->ht_capab =
7299 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
7300
7301 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
7302 {
7303 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7304 return -EINVAL;
7305 }
7306
7307 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307308 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07007309 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
7310 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307311 pConfig->obssProtEnabled =
7312 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07007313
Chet Lanctot8cecea22014-02-11 19:09:36 -08007314#ifdef WLAN_FEATURE_11W
7315 pConfig->mfpCapable = MFPCapable;
7316 pConfig->mfpRequired = MFPRequired;
7317 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
7318 pConfig->mfpCapable, pConfig->mfpRequired);
7319#endif
7320
Arif Hussain6d2a3322013-11-17 19:50:10 -08007321 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07007322 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007323 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
7324 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7325 (int)pConfig->channel);
7326 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
7327 pConfig->SapHw_mode, pConfig->privacy,
7328 pConfig->authType);
7329 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
7330 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7331 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7332 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07007333
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307334 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007335 {
7336 //Bss already started. just return.
7337 //TODO Probably it should update some beacon params.
7338 hddLog( LOGE, "Bss Already started...Ignore the request");
7339 EXIT();
7340 return 0;
7341 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307342
Agarwal Ashish51325b52014-06-16 16:50:49 +05307343 if (vos_max_concurrent_connections_reached()) {
7344 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7345 return -EINVAL;
7346 }
7347
Jeff Johnson295189b2012-06-20 16:38:30 -07007348 pConfig->persona = pHostapdAdapter->device_mode;
7349
Peng Xu2446a892014-09-05 17:21:18 +05307350 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
7351 if ( NULL != psmeConfig)
7352 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307353 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05307354 sme_GetConfigParam(hHal, psmeConfig);
7355 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307356#ifdef WLAN_FEATURE_AP_HT40_24G
7357 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7358 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
7359 && pHddCtx->cfg_ini->apHT40_24GEnabled)
7360 {
7361 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
7362 sme_UpdateConfig (hHal, psmeConfig);
7363 }
7364#endif
Peng Xu2446a892014-09-05 17:21:18 +05307365 vos_mem_free(psmeConfig);
7366 }
Peng Xuafc34e32014-09-25 13:23:55 +05307367 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05307368
Jeff Johnson295189b2012-06-20 16:38:30 -07007369 pSapEventCallback = hdd_hostapd_SAPEventCB;
7370 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
7371 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
7372 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007373 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007374 return -EINVAL;
7375 }
7376
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307377 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07007378 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7379
7380 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307381
Jeff Johnson295189b2012-06-20 16:38:30 -07007382 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307383 {
7384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007385 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07007386 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07007387 VOS_ASSERT(0);
7388 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307389
Jeff Johnson295189b2012-06-20 16:38:30 -07007390 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05307391 /* Initialize WMM configuation */
7392 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307393 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007394
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007395#ifdef WLAN_FEATURE_P2P_DEBUG
7396 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
7397 {
7398 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
7399 {
7400 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7401 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007402 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007403 }
7404 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
7405 {
7406 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7407 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007408 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007409 }
7410 }
7411#endif
7412
Jeff Johnson295189b2012-06-20 16:38:30 -07007413 pHostapdState->bCommit = TRUE;
7414 EXIT();
7415
7416 return 0;
7417}
7418
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007419#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307420static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307421 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007422 struct beacon_parameters *params)
7423{
7424 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307425 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307426 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007427
7428 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307429
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307430 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7431 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
7432 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307433 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
7434 hdd_device_modetoString(pAdapter->device_mode),
7435 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007436
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307437 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7438 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307439 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007440 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307441 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007442 }
7443
Agarwal Ashish51325b52014-06-16 16:50:49 +05307444 if (vos_max_concurrent_connections_reached()) {
7445 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7446 return -EINVAL;
7447 }
7448
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307449 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007450 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007451 )
7452 {
7453 beacon_data_t *old,*new;
7454
7455 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307456
Jeff Johnson295189b2012-06-20 16:38:30 -07007457 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307458 {
7459 hddLog(VOS_TRACE_LEVEL_WARN,
7460 FL("already beacon info added to session(%d)"),
7461 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007462 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307463 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007464
7465 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7466
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307467 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07007468 {
7469 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007470 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007471 return -EINVAL;
7472 }
7473
7474 pAdapter->sessionCtx.ap.beacon = new;
7475
7476 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7477 }
7478
7479 EXIT();
7480 return status;
7481}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307482
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307483static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
7484 struct net_device *dev,
7485 struct beacon_parameters *params)
7486{
7487 int ret;
7488
7489 vos_ssr_protect(__func__);
7490 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
7491 vos_ssr_unprotect(__func__);
7492
7493 return ret;
7494}
7495
7496static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007497 struct net_device *dev,
7498 struct beacon_parameters *params)
7499{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307500 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307501 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7502 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307503 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007504
7505 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307506
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307507 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7508 TRACE_CODE_HDD_CFG80211_SET_BEACON,
7509 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
7510 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7511 __func__, hdd_device_modetoString(pAdapter->device_mode),
7512 pAdapter->device_mode);
7513
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307514 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7515 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307516 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007517 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307518 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007519 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307520
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307521 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007522 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307523 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007524 {
7525 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307526
Jeff Johnson295189b2012-06-20 16:38:30 -07007527 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307528
Jeff Johnson295189b2012-06-20 16:38:30 -07007529 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307530 {
7531 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7532 FL("session(%d) old and new heads points to NULL"),
7533 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007534 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307535 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007536
7537 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7538
7539 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307540 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007541 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007542 return -EINVAL;
7543 }
7544
7545 pAdapter->sessionCtx.ap.beacon = new;
7546
7547 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7548 }
7549
7550 EXIT();
7551 return status;
7552}
7553
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307554static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
7555 struct net_device *dev,
7556 struct beacon_parameters *params)
7557{
7558 int ret;
7559
7560 vos_ssr_protect(__func__);
7561 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
7562 vos_ssr_unprotect(__func__);
7563
7564 return ret;
7565}
7566
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007567#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7568
7569#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307570static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007571 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007572#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307573static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007574 struct net_device *dev)
7575#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007576{
7577 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07007578 hdd_context_t *pHddCtx = NULL;
7579 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307580 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307581 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007582
7583 ENTER();
7584
7585 if (NULL == pAdapter)
7586 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007588 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007589 return -ENODEV;
7590 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007591
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307592 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7593 TRACE_CODE_HDD_CFG80211_STOP_AP,
7594 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307595 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7596 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307597 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007598 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307599 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07007600 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007601
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007602 pScanInfo = &pHddCtx->scan_info;
7603
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307604 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7605 __func__, hdd_device_modetoString(pAdapter->device_mode),
7606 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007607
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307608 ret = wlan_hdd_scan_abort(pAdapter);
7609
Girish Gowli4bf7a632014-06-12 13:42:11 +05307610 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07007611 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307612 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7613 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307614
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307615 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07007616 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7618 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08007619
Jeff Johnsone7245742012-09-05 17:12:55 -07007620 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307621 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07007622 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307623 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07007624 }
7625
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05307626 /* Delete all associated STAs before stopping AP/P2P GO */
7627 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05307628 hdd_hostapd_stop(dev);
7629
Jeff Johnson295189b2012-06-20 16:38:30 -07007630 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007631 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007632 )
7633 {
7634 beacon_data_t *old;
7635
7636 old = pAdapter->sessionCtx.ap.beacon;
7637
7638 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307639 {
7640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7641 FL("session(%d) beacon data points to NULL"),
7642 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007643 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307644 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007645
Jeff Johnson295189b2012-06-20 16:38:30 -07007646 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007647
7648 mutex_lock(&pHddCtx->sap_lock);
7649 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7650 {
Jeff Johnson4416a782013-03-25 14:17:50 -07007651 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007652 {
7653 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7654
7655 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7656
7657 if (!VOS_IS_STATUS_SUCCESS(status))
7658 {
7659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007660 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007661 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307662 }
7663 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007664 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307665 /* BSS stopped, clear the active sessions for this device mode */
7666 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007667 }
7668 mutex_unlock(&pHddCtx->sap_lock);
7669
7670 if(status != VOS_STATUS_SUCCESS)
7671 {
7672 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007673 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007674 return -EINVAL;
7675 }
7676
Jeff Johnson4416a782013-03-25 14:17:50 -07007677 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007678 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
7679 ==eHAL_STATUS_FAILURE)
7680 {
7681 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007682 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007683 }
7684
Jeff Johnson4416a782013-03-25 14:17:50 -07007685 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007686 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7687 eANI_BOOLEAN_FALSE) )
7688 {
7689 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007690 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007691 }
7692
7693 // Reset WNI_CFG_PROBE_RSP Flags
7694 wlan_hdd_reset_prob_rspies(pAdapter);
7695
7696 pAdapter->sessionCtx.ap.beacon = NULL;
7697 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007698#ifdef WLAN_FEATURE_P2P_DEBUG
7699 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7700 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
7701 {
7702 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
7703 "GO got removed");
7704 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
7705 }
7706#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007707 }
7708 EXIT();
7709 return status;
7710}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007711
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307712#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7713static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
7714 struct net_device *dev)
7715{
7716 int ret;
7717
7718 vos_ssr_protect(__func__);
7719 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
7720 vos_ssr_unprotect(__func__);
7721
7722 return ret;
7723}
7724#else
7725static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7726 struct net_device *dev)
7727{
7728 int ret;
7729
7730 vos_ssr_protect(__func__);
7731 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7732 vos_ssr_unprotect(__func__);
7733
7734 return ret;
7735}
7736#endif
7737
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007738#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7739
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307740static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307741 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007742 struct cfg80211_ap_settings *params)
7743{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307744 hdd_adapter_t *pAdapter;
7745 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307746 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007747
7748 ENTER();
7749
Girish Gowlib143d7a2015-02-18 19:39:55 +05307750 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007751 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05307753 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307754 return -ENODEV;
7755 }
7756
7757 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7758 if (NULL == pAdapter)
7759 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307761 "%s: HDD adapter is Null", __func__);
7762 return -ENODEV;
7763 }
7764
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307765 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7766 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
7767 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307768 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7769 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307770 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307771 "%s: HDD adapter magic is invalid", __func__);
7772 return -ENODEV;
7773 }
7774
7775 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307776 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307777 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307778 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307779 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307780 }
7781
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307782 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7783 __func__, hdd_device_modetoString(pAdapter->device_mode),
7784 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307785
7786 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007787 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007788 )
7789 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307790 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007791
7792 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307793
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007794 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307795 {
7796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7797 FL("already beacon info added to session(%d)"),
7798 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007799 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307800 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007801
Girish Gowlib143d7a2015-02-18 19:39:55 +05307802#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7803 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7804 &new,
7805 &params->beacon);
7806#else
7807 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7808 &new,
7809 &params->beacon,
7810 params->dtim_period);
7811#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007812
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307813 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007814 {
7815 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307816 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007817 return -EINVAL;
7818 }
7819 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007820#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007821 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7822#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7823 params->channel, params->channel_type);
7824#else
7825 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7826#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007827#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007828 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307829 params->ssid_len, params->hidden_ssid,
7830 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007831 }
7832
7833 EXIT();
7834 return status;
7835}
7836
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307837static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7838 struct net_device *dev,
7839 struct cfg80211_ap_settings *params)
7840{
7841 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007842
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307843 vos_ssr_protect(__func__);
7844 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
7845 vos_ssr_unprotect(__func__);
7846
7847 return ret;
7848}
7849
7850static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007851 struct net_device *dev,
7852 struct cfg80211_beacon_data *params)
7853{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307854 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307855 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307856 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007857
7858 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307859
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307860 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7861 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7862 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007863 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007864 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307865
7866 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7867 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307868 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007869 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307870 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007871 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007872
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307873 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007874 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307875 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007876 {
7877 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307878
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007879 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307880
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007881 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307882 {
7883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7884 FL("session(%d) beacon data points to NULL"),
7885 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007886 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307887 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007888
7889 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
7890
7891 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307892 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007893 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007894 return -EINVAL;
7895 }
7896
7897 pAdapter->sessionCtx.ap.beacon = new;
7898
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307899 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
7900 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007901 }
7902
7903 EXIT();
7904 return status;
7905}
7906
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307907static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
7908 struct net_device *dev,
7909 struct cfg80211_beacon_data *params)
7910{
7911 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007912
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307913 vos_ssr_protect(__func__);
7914 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
7915 vos_ssr_unprotect(__func__);
7916
7917 return ret;
7918}
7919
7920#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007921
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307922static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007923 struct net_device *dev,
7924 struct bss_parameters *params)
7925{
7926 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307927 hdd_context_t *pHddCtx;
7928 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007929
7930 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307931
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307932 if (NULL == pAdapter)
7933 {
7934 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7935 "%s: HDD adapter is Null", __func__);
7936 return -ENODEV;
7937 }
7938 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307939 ret = wlan_hdd_validate_context(pHddCtx);
7940 if (0 != ret)
7941 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307942 return ret;
7943 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307944 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7945 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
7946 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307947 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7948 __func__, hdd_device_modetoString(pAdapter->device_mode),
7949 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007950
7951 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007952 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307953 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007954 {
7955 /* ap_isolate == -1 means that in change bss, upper layer doesn't
7956 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307957 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07007958 {
7959 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307960 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007961 }
7962
7963 EXIT();
7964 return 0;
7965}
7966
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307967static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
7968 struct net_device *dev,
7969 struct bss_parameters *params)
7970{
7971 int ret;
7972
7973 vos_ssr_protect(__func__);
7974 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
7975 vos_ssr_unprotect(__func__);
7976
7977 return ret;
7978}
Kiet Lam10841362013-11-01 11:36:50 +05307979/* FUNCTION: wlan_hdd_change_country_code_cd
7980* to wait for contry code completion
7981*/
7982void* wlan_hdd_change_country_code_cb(void *pAdapter)
7983{
7984 hdd_adapter_t *call_back_pAdapter = pAdapter;
7985 complete(&call_back_pAdapter->change_country_code);
7986 return NULL;
7987}
7988
Jeff Johnson295189b2012-06-20 16:38:30 -07007989/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307990 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07007991 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
7992 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307993int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007994 struct net_device *ndev,
7995 enum nl80211_iftype type,
7996 u32 *flags,
7997 struct vif_params *params
7998 )
7999{
8000 struct wireless_dev *wdev;
8001 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008002 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07008003 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008004 tCsrRoamProfile *pRoamProfile = NULL;
8005 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308006 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008007 eMib_dot11DesiredBssType connectedBssType;
8008 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308009 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008010
8011 ENTER();
8012
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308013 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008014 {
8015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8016 "%s: Adapter context is null", __func__);
8017 return VOS_STATUS_E_FAILURE;
8018 }
8019
8020 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8021 if (!pHddCtx)
8022 {
8023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8024 "%s: HDD context is null", __func__);
8025 return VOS_STATUS_E_FAILURE;
8026 }
8027
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308028 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8029 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
8030 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308031 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308032 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07008033 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308034 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008035 }
8036
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308037 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8038 __func__, hdd_device_modetoString(pAdapter->device_mode),
8039 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008040
Agarwal Ashish51325b52014-06-16 16:50:49 +05308041 if (vos_max_concurrent_connections_reached()) {
8042 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8043 return -EINVAL;
8044 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308045 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07008046 wdev = ndev->ieee80211_ptr;
8047
8048#ifdef WLAN_BTAMP_FEATURE
8049 if((NL80211_IFTYPE_P2P_CLIENT == type)||
8050 (NL80211_IFTYPE_ADHOC == type)||
8051 (NL80211_IFTYPE_AP == type)||
8052 (NL80211_IFTYPE_P2P_GO == type))
8053 {
8054 pHddCtx->isAmpAllowed = VOS_FALSE;
8055 // stop AMP traffic
8056 status = WLANBAP_StopAmp();
8057 if(VOS_STATUS_SUCCESS != status )
8058 {
8059 pHddCtx->isAmpAllowed = VOS_TRUE;
8060 hddLog(VOS_TRACE_LEVEL_FATAL,
8061 "%s: Failed to stop AMP", __func__);
8062 return -EINVAL;
8063 }
8064 }
8065#endif //WLAN_BTAMP_FEATURE
8066 /* Reset the current device mode bit mask*/
8067 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8068
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +05308069 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
8070 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
8071 (type == NL80211_IFTYPE_P2P_GO)))
8072 {
8073 /* Notify Mode change in case of concurrency.
8074 * Below function invokes TDLS teardown Functionality Since TDLS is
8075 * not Supported in case of concurrency i.e Once P2P session
8076 * is detected disable offchannel and teardown TDLS links
8077 */
8078 hddLog(LOG1,
8079 FL("Device mode = %d Interface type = %d"),
8080 pAdapter->device_mode, type);
8081 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
8082 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +05308083
Jeff Johnson295189b2012-06-20 16:38:30 -07008084 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008085 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07008086 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008087 )
8088 {
8089 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008090 if (!pWextState)
8091 {
8092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8093 "%s: pWextState is null", __func__);
8094 return VOS_STATUS_E_FAILURE;
8095 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008096 pRoamProfile = &pWextState->roamProfile;
8097 LastBSSType = pRoamProfile->BSSType;
8098
8099 switch (type)
8100 {
8101 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008102 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008103 hddLog(VOS_TRACE_LEVEL_INFO,
8104 "%s: setting interface Type to INFRASTRUCTURE", __func__);
8105 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008106#ifdef WLAN_FEATURE_11AC
8107 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
8108 {
8109 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
8110 }
8111#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308112 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07008113 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008114 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008115 //Check for sub-string p2p to confirm its a p2p interface
8116 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308117 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +05308118#ifdef FEATURE_WLAN_TDLS
8119 mutex_lock(&pHddCtx->tdls_lock);
8120 wlan_hdd_tdls_exit(pAdapter, TRUE);
8121 mutex_unlock(&pHddCtx->tdls_lock);
8122#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008123 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8124 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8125 }
8126 else
8127 {
8128 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008129 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008130 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008131 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05308132
Jeff Johnson295189b2012-06-20 16:38:30 -07008133 case NL80211_IFTYPE_ADHOC:
8134 hddLog(VOS_TRACE_LEVEL_INFO,
8135 "%s: setting interface Type to ADHOC", __func__);
8136 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
8137 pRoamProfile->phyMode =
8138 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07008139 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008140 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05308141 hdd_set_ibss_ops( pAdapter );
8142 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +05308143
8144 status = hdd_sta_id_hash_attach(pAdapter);
8145 if (VOS_STATUS_SUCCESS != status) {
8146 hddLog(VOS_TRACE_LEVEL_ERROR,
8147 FL("Failed to initialize hash for IBSS"));
8148 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008149 break;
8150
8151 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008152 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008153 {
8154 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8155 "%s: setting interface Type to %s", __func__,
8156 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
8157
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008158 //Cancel any remain on channel for GO mode
8159 if (NL80211_IFTYPE_P2P_GO == type)
8160 {
8161 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
8162 }
Mohit Khanna0f232092012-09-11 14:46:08 -07008163 if (NL80211_IFTYPE_AP == type)
8164 {
8165 /* As Loading WLAN Driver one interface being created for p2p device
8166 * address. This will take one HW STA and the max number of clients
8167 * that can connect to softAP will be reduced by one. so while changing
8168 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
8169 * interface as it is not required in SoftAP mode.
8170 */
8171
8172 // Get P2P Adapter
8173 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
8174
8175 if (pP2pAdapter)
8176 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308177 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05308178 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07008179 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
8180 }
8181 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05308182 //Disable IMPS & BMPS for SAP/GO
8183 if(VOS_STATUS_E_FAILURE ==
8184 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
8185 {
8186 //Fail to Exit BMPS
8187 VOS_ASSERT(0);
8188 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05308189
8190 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
8191
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308192#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07008193
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308194 /* A Mutex Lock is introduced while changing the mode to
8195 * protect the concurrent access for the Adapters by TDLS
8196 * module.
8197 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308198 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308199#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008200 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05308201 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008202 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07008203 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8204 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308205#ifdef FEATURE_WLAN_TDLS
8206 mutex_unlock(&pHddCtx->tdls_lock);
8207#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008208 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
8209 (pConfig->apRandomBssidEnabled))
8210 {
8211 /* To meet Android requirements create a randomized
8212 MAC address of the form 02:1A:11:Fx:xx:xx */
8213 get_random_bytes(&ndev->dev_addr[3], 3);
8214 ndev->dev_addr[0] = 0x02;
8215 ndev->dev_addr[1] = 0x1A;
8216 ndev->dev_addr[2] = 0x11;
8217 ndev->dev_addr[3] |= 0xF0;
8218 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
8219 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08008220 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
8221 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008222 }
8223
Jeff Johnson295189b2012-06-20 16:38:30 -07008224 hdd_set_ap_ops( pAdapter->dev );
8225
Kiet Lam10841362013-11-01 11:36:50 +05308226 /* This is for only SAP mode where users can
8227 * control country through ini.
8228 * P2P GO follows station country code
8229 * acquired during the STA scanning. */
8230 if((NL80211_IFTYPE_AP == type) &&
8231 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
8232 {
8233 int status = 0;
8234 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
8235 "%s: setting country code from INI ", __func__);
8236 init_completion(&pAdapter->change_country_code);
8237 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
8238 (void *)(tSmeChangeCountryCallback)
8239 wlan_hdd_change_country_code_cb,
8240 pConfig->apCntryCode, pAdapter,
8241 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308242 eSIR_FALSE,
8243 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05308244 if (eHAL_STATUS_SUCCESS == status)
8245 {
8246 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308247 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05308248 &pAdapter->change_country_code,
8249 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308250 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05308251 {
8252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308253 FL("SME Timed out while setting country code %ld"),
8254 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08008255
8256 if (pHddCtx->isLogpInProgress)
8257 {
8258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8259 "%s: LOGP in Progress. Ignore!!!", __func__);
8260 return -EAGAIN;
8261 }
Kiet Lam10841362013-11-01 11:36:50 +05308262 }
8263 }
8264 else
8265 {
8266 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008267 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05308268 return -EINVAL;
8269 }
8270 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008271 status = hdd_init_ap_mode(pAdapter);
8272 if(status != VOS_STATUS_SUCCESS)
8273 {
8274 hddLog(VOS_TRACE_LEVEL_FATAL,
8275 "%s: Error initializing the ap mode", __func__);
8276 return -EINVAL;
8277 }
8278 hdd_set_conparam(1);
8279
Nirav Shah7e3c8132015-06-22 23:51:42 +05308280 status = hdd_sta_id_hash_attach(pAdapter);
8281 if (VOS_STATUS_SUCCESS != status)
8282 {
8283 hddLog(VOS_TRACE_LEVEL_ERROR,
8284 FL("Failed to initialize hash for AP"));
8285 return -EINVAL;
8286 }
8287
Jeff Johnson295189b2012-06-20 16:38:30 -07008288 /*interface type changed update in wiphy structure*/
8289 if(wdev)
8290 {
8291 wdev->iftype = type;
8292 pHddCtx->change_iface = type;
8293 }
8294 else
8295 {
8296 hddLog(VOS_TRACE_LEVEL_ERROR,
8297 "%s: ERROR !!!! Wireless dev is NULL", __func__);
8298 return -EINVAL;
8299 }
8300 goto done;
8301 }
8302
8303 default:
8304 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8305 __func__);
8306 return -EOPNOTSUPP;
8307 }
8308 }
8309 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008310 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008311 )
8312 {
8313 switch(type)
8314 {
8315 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008316 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008317 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05308318
8319 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308320#ifdef FEATURE_WLAN_TDLS
8321
8322 /* A Mutex Lock is introduced while changing the mode to
8323 * protect the concurrent access for the Adapters by TDLS
8324 * module.
8325 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308326 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308327#endif
c_hpothu002231a2015-02-05 14:58:51 +05308328 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008329 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008330 //Check for sub-string p2p to confirm its a p2p interface
8331 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008332 {
8333 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8334 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8335 }
8336 else
8337 {
8338 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008339 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008340 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008341 hdd_set_conparam(0);
8342 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008343 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
8344 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308345#ifdef FEATURE_WLAN_TDLS
8346 mutex_unlock(&pHddCtx->tdls_lock);
8347#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308348 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008349 if( VOS_STATUS_SUCCESS != status )
8350 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07008351 /* In case of JB, for P2P-GO, only change interface will be called,
8352 * This is the right place to enable back bmps_imps()
8353 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308354 if (pHddCtx->hdd_wlan_suspended)
8355 {
8356 hdd_set_pwrparams(pHddCtx);
8357 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008358 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008359 goto done;
8360 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008361 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008362 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008363 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8364 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008365 goto done;
8366 default:
8367 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8368 __func__);
8369 return -EOPNOTSUPP;
8370
8371 }
8372
8373 }
8374 else
8375 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308376 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
8377 __func__, hdd_device_modetoString(pAdapter->device_mode),
8378 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008379 return -EOPNOTSUPP;
8380 }
8381
8382
8383 if(pRoamProfile)
8384 {
8385 if ( LastBSSType != pRoamProfile->BSSType )
8386 {
8387 /*interface type changed update in wiphy structure*/
8388 wdev->iftype = type;
8389
8390 /*the BSS mode changed, We need to issue disconnect
8391 if connected or in IBSS disconnect state*/
8392 if ( hdd_connGetConnectedBssType(
8393 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
8394 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
8395 {
8396 /*need to issue a disconnect to CSR.*/
8397 INIT_COMPLETION(pAdapter->disconnect_comp_var);
8398 if( eHAL_STATUS_SUCCESS ==
8399 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
8400 pAdapter->sessionId,
8401 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
8402 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308403 ret = wait_for_completion_interruptible_timeout(
8404 &pAdapter->disconnect_comp_var,
8405 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
8406 if (ret <= 0)
8407 {
8408 hddLog(VOS_TRACE_LEVEL_ERROR,
8409 FL("wait on disconnect_comp_var failed %ld"), ret);
8410 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008411 }
8412 }
8413 }
8414 }
8415
8416done:
8417 /*set bitmask based on updated value*/
8418 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07008419
8420 /* Only STA mode support TM now
8421 * all other mode, TM feature should be disabled */
8422 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
8423 (~VOS_STA & pHddCtx->concurrency_mode) )
8424 {
8425 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
8426 }
8427
Jeff Johnson295189b2012-06-20 16:38:30 -07008428#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308429 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05308430 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07008431 {
8432 //we are ok to do AMP
8433 pHddCtx->isAmpAllowed = VOS_TRUE;
8434 }
8435#endif //WLAN_BTAMP_FEATURE
8436 EXIT();
8437 return 0;
8438}
8439
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308440/*
8441 * FUNCTION: wlan_hdd_cfg80211_change_iface
8442 * wrapper function to protect the actual implementation from SSR.
8443 */
8444int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
8445 struct net_device *ndev,
8446 enum nl80211_iftype type,
8447 u32 *flags,
8448 struct vif_params *params
8449 )
8450{
8451 int ret;
8452
8453 vos_ssr_protect(__func__);
8454 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
8455 vos_ssr_unprotect(__func__);
8456
8457 return ret;
8458}
8459
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008460#ifdef FEATURE_WLAN_TDLS
8461static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308462 struct net_device *dev,
8463#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
8464 const u8 *mac,
8465#else
8466 u8 *mac,
8467#endif
8468 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008469{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008470 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008471 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308472 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308473 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308474 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05308475 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008476
8477 ENTER();
8478
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308479 if (!dev) {
8480 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
8481 return -EINVAL;
8482 }
8483
8484 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8485 if (!pAdapter) {
8486 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
8487 return -EINVAL;
8488 }
8489
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308490 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008491 {
8492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8493 "Invalid arguments");
8494 return -EINVAL;
8495 }
Hoonki Lee27511902013-03-14 18:19:06 -07008496
8497 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
8498 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
8499 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07008501 "%s: TDLS mode is disabled OR not enabled in FW."
8502 MAC_ADDRESS_STR " Request declined.",
8503 __func__, MAC_ADDR_ARRAY(mac));
8504 return -ENOTSUPP;
8505 }
8506
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008507 if (pHddCtx->isLogpInProgress)
8508 {
8509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8510 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05308511 wlan_hdd_tdls_set_link_status(pAdapter,
8512 mac,
8513 eTDLS_LINK_IDLE,
8514 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008515 return -EBUSY;
8516 }
8517
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308518 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05308519 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008520
8521 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308522 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008523 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
8524 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308525 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008526 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008527 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308528 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008529
8530 /* in add station, we accept existing valid staId if there is */
8531 if ((0 == update) &&
8532 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
8533 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008534 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008536 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008537 " link_status %d. staId %d. add station ignored.",
8538 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
8539 return 0;
8540 }
8541 /* in change station, we accept only when staId is valid */
8542 if ((1 == update) &&
8543 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
8544 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
8545 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008547 "%s: " MAC_ADDRESS_STR
8548 " link status %d. staId %d. change station %s.",
8549 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
8550 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
8551 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008552 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008553
8554 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05308555 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008556 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8558 "%s: " MAC_ADDRESS_STR
8559 " TDLS setup is ongoing. Request declined.",
8560 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07008561 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008562 }
8563
8564 /* first to check if we reached to maximum supported TDLS peer.
8565 TODO: for now, return -EPERM looks working fine,
8566 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308567 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8568 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008569 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8571 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308572 " TDLS Max peer already connected. Request declined."
8573 " Num of peers (%d), Max allowed (%d).",
8574 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
8575 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008576 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008577 }
8578 else
8579 {
8580 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308581 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008582 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008583 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008584 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8585 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
8586 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008587 return -EPERM;
8588 }
8589 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008590 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05308591 wlan_hdd_tdls_set_link_status(pAdapter,
8592 mac,
8593 eTDLS_LINK_CONNECTING,
8594 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008595
Jeff Johnsond75fe012013-04-06 10:53:06 -07008596 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308597 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008598 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008600 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008601 if(StaParams->htcap_present)
8602 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008604 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308605 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008606 "ht_capa->extended_capabilities: %0x",
8607 StaParams->HTCap.extendedHtCapInfo);
8608 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008610 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008612 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008613 if(StaParams->vhtcap_present)
8614 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308615 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008616 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
8617 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
8618 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
8619 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008620 {
8621 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008623 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008625 "[%d]: %x ", i, StaParams->supported_rates[i]);
8626 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07008627 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308628 else if ((1 == update) && (NULL == StaParams))
8629 {
8630 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8631 "%s : update is true, but staParams is NULL. Error!", __func__);
8632 return -EPERM;
8633 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008634
8635 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
8636
8637 if (!update)
8638 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05308639 /*Before adding sta make sure that device exited from BMPS*/
8640 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
8641 {
8642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8643 "%s: Adding tdls peer sta. Disable BMPS", __func__);
8644 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
8645 if (status != VOS_STATUS_SUCCESS) {
8646 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
8647 }
8648 }
8649
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308650 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008651 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308652 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05308653 hddLog(VOS_TRACE_LEVEL_ERROR,
8654 FL("Failed to add TDLS peer STA. Enable Bmps"));
8655 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308656 return -EPERM;
8657 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008658 }
8659 else
8660 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308661 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008662 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308663 if (ret != eHAL_STATUS_SUCCESS) {
8664 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
8665 return -EPERM;
8666 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008667 }
8668
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308669 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008670 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
8671
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308672 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008673 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308675 "%s: timeout waiting for tdls add station indication %ld",
8676 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008677 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008678 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308679
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008680 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
8681 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008683 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008684 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008685 }
8686
8687 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008688
8689error:
Atul Mittal115287b2014-07-08 13:26:33 +05308690 wlan_hdd_tdls_set_link_status(pAdapter,
8691 mac,
8692 eTDLS_LINK_IDLE,
8693 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008694 return -EPERM;
8695
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008696}
8697#endif
8698
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308699static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008700 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308701#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
8702 const u8 *mac,
8703#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008704 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308705#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008706 struct station_parameters *params)
8707{
8708 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308709 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308710 hdd_context_t *pHddCtx;
8711 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008712 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308713 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008714#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008715 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008716 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308717 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008718#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008719
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308720 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308721
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308722 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308723 if ((NULL == pAdapter))
8724 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308726 "invalid adapter ");
8727 return -EINVAL;
8728 }
8729
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308730 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8731 TRACE_CODE_HDD_CHANGE_STATION,
8732 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05308733 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308734
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308735 ret = wlan_hdd_validate_context(pHddCtx);
8736 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05308737 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308738 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308739 }
8740
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308741 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8742
8743 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008744 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8746 "invalid HDD station context");
8747 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008748 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008749 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
8750
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008751 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8752 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07008753 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008754 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07008755 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308756 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07008757 WLANTL_STA_AUTHENTICATED);
8758
Gopichand Nakkala29149562013-05-10 21:43:41 +05308759 if (status != VOS_STATUS_SUCCESS)
8760 {
8761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8762 "%s: Not able to change TL state to AUTHENTICATED", __func__);
8763 return -EINVAL;
8764 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008765 }
8766 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07008767 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8768 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308769#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008770 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8771 StaParams.capability = params->capability;
8772 StaParams.uapsd_queues = params->uapsd_queues;
8773 StaParams.max_sp = params->max_sp;
8774
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308775 /* Convert (first channel , number of channels) tuple to
8776 * the total list of channels. This goes with the assumption
8777 * that if the first channel is < 14, then the next channels
8778 * are an incremental of 1 else an incremental of 4 till the number
8779 * of channels.
8780 */
8781 if (0 != params->supported_channels_len) {
8782 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
8783 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
8784 {
8785 int wifi_chan_index;
8786 StaParams.supported_channels[j] = params->supported_channels[i];
8787 wifi_chan_index =
8788 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
8789 no_of_channels = params->supported_channels[i+1];
8790 for(k=1; k <= no_of_channels; k++)
8791 {
8792 StaParams.supported_channels[j+1] =
8793 StaParams.supported_channels[j] + wifi_chan_index;
8794 j+=1;
8795 }
8796 }
8797 StaParams.supported_channels_len = j;
8798 }
8799 vos_mem_copy(StaParams.supported_oper_classes,
8800 params->supported_oper_classes,
8801 params->supported_oper_classes_len);
8802 StaParams.supported_oper_classes_len =
8803 params->supported_oper_classes_len;
8804
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008805 if (0 != params->ext_capab_len)
8806 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
8807 sizeof(StaParams.extn_capability));
8808
8809 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008810 {
8811 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008812 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008813 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008814
8815 StaParams.supported_rates_len = params->supported_rates_len;
8816
8817 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
8818 * The supported_rates array , for all the structures propogating till Add Sta
8819 * to the firmware has to be modified , if the supplicant (ieee80211) is
8820 * modified to send more rates.
8821 */
8822
8823 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
8824 */
8825 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
8826 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
8827
8828 if (0 != StaParams.supported_rates_len) {
8829 int i = 0;
8830 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
8831 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008833 "Supported Rates with Length %d", StaParams.supported_rates_len);
8834 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008836 "[%d]: %0x", i, StaParams.supported_rates[i]);
8837 }
8838
8839 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008840 {
8841 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008842 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008843 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008844
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008845 if (0 != params->ext_capab_len ) {
8846 /*Define A Macro : TODO Sunil*/
8847 if ((1<<4) & StaParams.extn_capability[3]) {
8848 isBufSta = 1;
8849 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308850 /* TDLS Channel Switching Support */
8851 if ((1<<6) & StaParams.extn_capability[3]) {
8852 isOffChannelSupported = 1;
8853 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008854 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308855 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
8856 &StaParams, isBufSta,
8857 isOffChannelSupported);
8858
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308859 if (VOS_STATUS_SUCCESS != status) {
8860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8861 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
8862 return -EINVAL;
8863 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008864 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
8865
8866 if (VOS_STATUS_SUCCESS != status) {
8867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8868 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
8869 return -EINVAL;
8870 }
8871 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008872#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05308873 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008874 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008875 return status;
8876}
8877
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308878#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
8879static int wlan_hdd_change_station(struct wiphy *wiphy,
8880 struct net_device *dev,
8881 const u8 *mac,
8882 struct station_parameters *params)
8883#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308884static int wlan_hdd_change_station(struct wiphy *wiphy,
8885 struct net_device *dev,
8886 u8 *mac,
8887 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308888#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308889{
8890 int ret;
8891
8892 vos_ssr_protect(__func__);
8893 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
8894 vos_ssr_unprotect(__func__);
8895
8896 return ret;
8897}
8898
Jeff Johnson295189b2012-06-20 16:38:30 -07008899/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308900 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008901 * This function is used to initialize the key information
8902 */
8903#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308904static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008905 struct net_device *ndev,
8906 u8 key_index, bool pairwise,
8907 const u8 *mac_addr,
8908 struct key_params *params
8909 )
8910#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308911static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008912 struct net_device *ndev,
8913 u8 key_index, const u8 *mac_addr,
8914 struct key_params *params
8915 )
8916#endif
8917{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008918 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07008919 tCsrRoamSetKey setKey;
8920 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308921 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008922 v_U32_t roamId= 0xFF;
8923 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008924 hdd_hostapd_state_t *pHostapdState;
8925 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008926 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308927 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008928
8929 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308930
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308931 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8932 TRACE_CODE_HDD_CFG80211_ADD_KEY,
8933 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308934 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8935 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308936 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008937 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308938 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008939 }
8940
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308941 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8942 __func__, hdd_device_modetoString(pAdapter->device_mode),
8943 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008944
8945 if (CSR_MAX_NUM_KEY <= key_index)
8946 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008947 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008948 key_index);
8949
8950 return -EINVAL;
8951 }
8952
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008953 if (CSR_MAX_KEY_LEN < params->key_len)
8954 {
8955 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
8956 params->key_len);
8957
8958 return -EINVAL;
8959 }
8960
8961 hddLog(VOS_TRACE_LEVEL_INFO,
8962 "%s: called with key index = %d & key length %d",
8963 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008964
8965 /*extract key idx, key len and key*/
8966 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8967 setKey.keyId = key_index;
8968 setKey.keyLength = params->key_len;
8969 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
8970
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008971 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07008972 {
8973 case WLAN_CIPHER_SUITE_WEP40:
8974 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
8975 break;
8976
8977 case WLAN_CIPHER_SUITE_WEP104:
8978 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
8979 break;
8980
8981 case WLAN_CIPHER_SUITE_TKIP:
8982 {
8983 u8 *pKey = &setKey.Key[0];
8984 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
8985
8986 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
8987
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008988 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07008989
8990 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008991 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008992 |--------------|----------|----------|
8993 <---16bytes---><--8bytes--><--8bytes-->
8994
8995 */
8996 /*Sme expects the 32 bytes key to be in the below order
8997
8998 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008999 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009000 |--------------|----------|----------|
9001 <---16bytes---><--8bytes--><--8bytes-->
9002 */
9003 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009004 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07009005
9006 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009007 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009008
9009 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009010 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009011
9012
9013 break;
9014 }
9015
9016 case WLAN_CIPHER_SUITE_CCMP:
9017 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
9018 break;
9019
9020#ifdef FEATURE_WLAN_WAPI
9021 case WLAN_CIPHER_SUITE_SMS4:
9022 {
9023 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9024 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
9025 params->key, params->key_len);
9026 return 0;
9027 }
9028#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009029
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009030#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009031 case WLAN_CIPHER_SUITE_KRK:
9032 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
9033 break;
9034#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009035
9036#ifdef WLAN_FEATURE_11W
9037 case WLAN_CIPHER_SUITE_AES_CMAC:
9038 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07009039 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07009040#endif
9041
Jeff Johnson295189b2012-06-20 16:38:30 -07009042 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009043 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009044 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309045 status = -EOPNOTSUPP;
9046 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009047 }
9048
9049 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
9050 __func__, setKey.encType);
9051
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009052 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07009053#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9054 (!pairwise)
9055#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009056 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07009057#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009058 )
9059 {
9060 /* set group key*/
9061 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9062 "%s- %d: setting Broadcast key",
9063 __func__, __LINE__);
9064 setKey.keyDirection = eSIR_RX_ONLY;
9065 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9066 }
9067 else
9068 {
9069 /* set pairwise key*/
9070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9071 "%s- %d: setting pairwise key",
9072 __func__, __LINE__);
9073 setKey.keyDirection = eSIR_TX_RX;
9074 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9075 }
9076 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
9077 {
9078 setKey.keyDirection = eSIR_TX_RX;
9079 /*Set the group key*/
9080 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9081 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07009082
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009083 if ( 0 != status )
9084 {
9085 hddLog(VOS_TRACE_LEVEL_ERROR,
9086 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309087 status = -EINVAL;
9088 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009089 }
9090 /*Save the keys here and call sme_RoamSetKey for setting
9091 the PTK after peer joins the IBSS network*/
9092 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
9093 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309094 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009095 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05309096 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
9097 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
9098 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009099 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009100 if( pHostapdState->bssState == BSS_START )
9101 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009102 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9103 vos_status = wlan_hdd_check_ula_done(pAdapter);
9104
9105 if ( vos_status != VOS_STATUS_SUCCESS )
9106 {
9107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9108 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9109 __LINE__, vos_status );
9110
9111 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9112
9113 status = -EINVAL;
9114 goto end;
9115 }
9116
Jeff Johnson295189b2012-06-20 16:38:30 -07009117 status = WLANSAP_SetKeySta( pVosContext, &setKey);
9118
9119 if ( status != eHAL_STATUS_SUCCESS )
9120 {
9121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9122 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9123 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309124 status = -EINVAL;
9125 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009126 }
9127 }
9128
9129 /* Saving WEP keys */
9130 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
9131 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
9132 {
9133 //Save the wep key in ap context. Issue setkey after the BSS is started.
9134 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9135 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
9136 }
9137 else
9138 {
9139 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009140 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009141 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
9142 }
9143 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009144 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
9145 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009146 {
9147 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9148 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9149
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309150#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9151 if (!pairwise)
9152#else
9153 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9154#endif
9155 {
9156 /* set group key*/
9157 if (pHddStaCtx->roam_info.deferKeyComplete)
9158 {
9159 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9160 "%s- %d: Perform Set key Complete",
9161 __func__, __LINE__);
9162 hdd_PerformRoamSetKeyComplete(pAdapter);
9163 }
9164 }
9165
Jeff Johnson295189b2012-06-20 16:38:30 -07009166 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
9167
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08009168 pWextState->roamProfile.Keys.defaultIndex = key_index;
9169
9170
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009171 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009172 params->key, params->key_len);
9173
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309174
Jeff Johnson295189b2012-06-20 16:38:30 -07009175 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9176
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309177 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009178 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309179 __func__, setKey.peerMac[0], setKey.peerMac[1],
9180 setKey.peerMac[2], setKey.peerMac[3],
9181 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009182 setKey.keyDirection);
9183
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009184 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +05309185
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009186 if ( vos_status != VOS_STATUS_SUCCESS )
9187 {
9188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009189 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9190 __LINE__, vos_status );
9191
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009192 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009193
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009194 status = -EINVAL;
9195 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009196
9197 }
9198
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009199#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309200 /* The supplicant may attempt to set the PTK once pre-authentication
9201 is done. Save the key in the UMAC and include it in the ADD BSS
9202 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009203 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309204 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009205 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309206 hddLog(VOS_TRACE_LEVEL_INFO_MED,
9207 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309208 status = 0;
9209 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309210 }
9211 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
9212 {
9213 hddLog(VOS_TRACE_LEVEL_ERROR,
9214 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309215 status = -EINVAL;
9216 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009217 }
9218#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07009219
9220 /* issue set key request to SME*/
9221 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9222 pAdapter->sessionId, &setKey, &roamId );
9223
9224 if ( 0 != status )
9225 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309226 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009227 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
9228 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309229 status = -EINVAL;
9230 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009231 }
9232
9233
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309234 /* in case of IBSS as there was no information available about WEP keys during
9235 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07009236 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309237 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
9238 !( ( IW_AUTH_KEY_MGMT_802_1X
9239 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07009240 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
9241 )
9242 &&
9243 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
9244 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
9245 )
9246 )
9247 {
9248 setKey.keyDirection = eSIR_RX_ONLY;
9249 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9250
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309251 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009252 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309253 __func__, setKey.peerMac[0], setKey.peerMac[1],
9254 setKey.peerMac[2], setKey.peerMac[3],
9255 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009256 setKey.keyDirection);
9257
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309258 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009259 pAdapter->sessionId, &setKey, &roamId );
9260
9261 if ( 0 != status )
9262 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309263 hddLog(VOS_TRACE_LEVEL_ERROR,
9264 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009265 __func__, status);
9266 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309267 status = -EINVAL;
9268 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009269 }
9270 }
9271 }
9272
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309273end:
9274 /* Need to clear any trace of key value in the memory.
9275 * Thus zero out the memory even though it is local
9276 * variable.
9277 */
9278 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309279 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309280 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009281}
9282
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309283#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9284static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9285 struct net_device *ndev,
9286 u8 key_index, bool pairwise,
9287 const u8 *mac_addr,
9288 struct key_params *params
9289 )
9290#else
9291static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9292 struct net_device *ndev,
9293 u8 key_index, const u8 *mac_addr,
9294 struct key_params *params
9295 )
9296#endif
9297{
9298 int ret;
9299 vos_ssr_protect(__func__);
9300#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9301 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
9302 mac_addr, params);
9303#else
9304 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
9305 params);
9306#endif
9307 vos_ssr_unprotect(__func__);
9308
9309 return ret;
9310}
9311
Jeff Johnson295189b2012-06-20 16:38:30 -07009312/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309313 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009314 * This function is used to get the key information
9315 */
9316#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309317static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309318 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009319 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309320 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009321 const u8 *mac_addr, void *cookie,
9322 void (*callback)(void *cookie, struct key_params*)
9323 )
9324#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309325static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309326 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009327 struct net_device *ndev,
9328 u8 key_index, const u8 *mac_addr, void *cookie,
9329 void (*callback)(void *cookie, struct key_params*)
9330 )
9331#endif
9332{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309333 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309334 hdd_wext_state_t *pWextState = NULL;
9335 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009336 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309337 hdd_context_t *pHddCtx;
9338 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009339
9340 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309341
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309342 if (NULL == pAdapter)
9343 {
9344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9345 "%s: HDD adapter is Null", __func__);
9346 return -ENODEV;
9347 }
9348
9349 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9350 ret = wlan_hdd_validate_context(pHddCtx);
9351 if (0 != ret)
9352 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309353 return ret;
9354 }
9355
9356 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9357 pRoamProfile = &(pWextState->roamProfile);
9358
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309359 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9360 __func__, hdd_device_modetoString(pAdapter->device_mode),
9361 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309362
Jeff Johnson295189b2012-06-20 16:38:30 -07009363 memset(&params, 0, sizeof(params));
9364
9365 if (CSR_MAX_NUM_KEY <= key_index)
9366 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309367 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07009368 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309369 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009370
9371 switch(pRoamProfile->EncryptionType.encryptionType[0])
9372 {
9373 case eCSR_ENCRYPT_TYPE_NONE:
9374 params.cipher = IW_AUTH_CIPHER_NONE;
9375 break;
9376
9377 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
9378 case eCSR_ENCRYPT_TYPE_WEP40:
9379 params.cipher = WLAN_CIPHER_SUITE_WEP40;
9380 break;
9381
9382 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
9383 case eCSR_ENCRYPT_TYPE_WEP104:
9384 params.cipher = WLAN_CIPHER_SUITE_WEP104;
9385 break;
9386
9387 case eCSR_ENCRYPT_TYPE_TKIP:
9388 params.cipher = WLAN_CIPHER_SUITE_TKIP;
9389 break;
9390
9391 case eCSR_ENCRYPT_TYPE_AES:
9392 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
9393 break;
9394
9395 default:
9396 params.cipher = IW_AUTH_CIPHER_NONE;
9397 break;
9398 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309399
c_hpothuaaf19692014-05-17 17:01:48 +05309400 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9401 TRACE_CODE_HDD_CFG80211_GET_KEY,
9402 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309403
Jeff Johnson295189b2012-06-20 16:38:30 -07009404 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
9405 params.seq_len = 0;
9406 params.seq = NULL;
9407 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
9408 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309409 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009410 return 0;
9411}
9412
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309413#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9414static int wlan_hdd_cfg80211_get_key(
9415 struct wiphy *wiphy,
9416 struct net_device *ndev,
9417 u8 key_index, bool pairwise,
9418 const u8 *mac_addr, void *cookie,
9419 void (*callback)(void *cookie, struct key_params*)
9420 )
9421#else
9422static int wlan_hdd_cfg80211_get_key(
9423 struct wiphy *wiphy,
9424 struct net_device *ndev,
9425 u8 key_index, const u8 *mac_addr, void *cookie,
9426 void (*callback)(void *cookie, struct key_params*)
9427 )
9428#endif
9429{
9430 int ret;
9431
9432 vos_ssr_protect(__func__);
9433#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9434 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
9435 mac_addr, cookie, callback);
9436#else
9437 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
9438 callback);
9439#endif
9440 vos_ssr_unprotect(__func__);
9441
9442 return ret;
9443}
9444
Jeff Johnson295189b2012-06-20 16:38:30 -07009445/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309446 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009447 * This function is used to delete the key information
9448 */
9449#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309450static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009451 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309452 u8 key_index,
9453 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009454 const u8 *mac_addr
9455 )
9456#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309457static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009458 struct net_device *ndev,
9459 u8 key_index,
9460 const u8 *mac_addr
9461 )
9462#endif
9463{
9464 int status = 0;
9465
9466 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309467 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009468 //it is observed that this is invalidating peer
9469 //key index whenever re-key is done. This is affecting data link.
9470 //It should be ok to ignore del_key.
9471#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309472 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
9473 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009474 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
9475 tCsrRoamSetKey setKey;
9476 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309477
Jeff Johnson295189b2012-06-20 16:38:30 -07009478 ENTER();
9479
9480 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
9481 __func__,pAdapter->device_mode);
9482
9483 if (CSR_MAX_NUM_KEY <= key_index)
9484 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309485 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009486 key_index);
9487
9488 return -EINVAL;
9489 }
9490
9491 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9492 setKey.keyId = key_index;
9493
9494 if (mac_addr)
9495 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9496 else
9497 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
9498
9499 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
9500
9501 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009502 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309503 )
9504 {
9505
9506 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07009507 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9508 if( pHostapdState->bssState == BSS_START)
9509 {
9510 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309511
Jeff Johnson295189b2012-06-20 16:38:30 -07009512 if ( status != eHAL_STATUS_SUCCESS )
9513 {
9514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9515 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9516 __LINE__, status );
9517 }
9518 }
9519 }
9520 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309521 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07009522 )
9523 {
9524 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9525
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309526 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9527
9528 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009529 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309530 __func__, setKey.peerMac[0], setKey.peerMac[1],
9531 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07009532 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309533 if(pAdapter->sessionCtx.station.conn_info.connState ==
9534 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07009535 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309536 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009537 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309538
Jeff Johnson295189b2012-06-20 16:38:30 -07009539 if ( 0 != status )
9540 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309541 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009542 "%s: sme_RoamSetKey failure, returned %d",
9543 __func__, status);
9544 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9545 return -EINVAL;
9546 }
9547 }
9548 }
9549#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009550 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009551 return status;
9552}
9553
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309554#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9555static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9556 struct net_device *ndev,
9557 u8 key_index,
9558 bool pairwise,
9559 const u8 *mac_addr
9560 )
9561#else
9562static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9563 struct net_device *ndev,
9564 u8 key_index,
9565 const u8 *mac_addr
9566 )
9567#endif
9568{
9569 int ret;
9570
9571 vos_ssr_protect(__func__);
9572#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9573 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
9574 mac_addr);
9575#else
9576 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
9577#endif
9578 vos_ssr_unprotect(__func__);
9579
9580 return ret;
9581}
9582
Jeff Johnson295189b2012-06-20 16:38:30 -07009583/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309584 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009585 * This function is used to set the default tx key index
9586 */
9587#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309588static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009589 struct net_device *ndev,
9590 u8 key_index,
9591 bool unicast, bool multicast)
9592#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309593static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009594 struct net_device *ndev,
9595 u8 key_index)
9596#endif
9597{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309598 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309599 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309600 hdd_wext_state_t *pWextState;
9601 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309602 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009603
9604 ENTER();
9605
Gopichand Nakkala29149562013-05-10 21:43:41 +05309606 if ((NULL == pAdapter))
9607 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309609 "invalid adapter");
9610 return -EINVAL;
9611 }
9612
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309613 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9614 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
9615 pAdapter->sessionId, key_index));
9616
Gopichand Nakkala29149562013-05-10 21:43:41 +05309617 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9618 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9619
9620 if ((NULL == pWextState) || (NULL == pHddStaCtx))
9621 {
9622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9623 "invalid Wext state or HDD context");
9624 return -EINVAL;
9625 }
9626
Arif Hussain6d2a3322013-11-17 19:50:10 -08009627 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009628 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309629
Jeff Johnson295189b2012-06-20 16:38:30 -07009630 if (CSR_MAX_NUM_KEY <= key_index)
9631 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309632 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009633 key_index);
9634
9635 return -EINVAL;
9636 }
9637
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309638 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9639 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309640 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009641 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309642 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009643 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309644
Jeff Johnson295189b2012-06-20 16:38:30 -07009645 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07009646 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309647 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009648 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309649 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08009650 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309651 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08009652 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07009653 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309654 {
9655 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07009656 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309657
Jeff Johnson295189b2012-06-20 16:38:30 -07009658 tCsrRoamSetKey setKey;
9659 v_U32_t roamId= 0xFF;
9660 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309661
9662 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009663 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309664
Jeff Johnson295189b2012-06-20 16:38:30 -07009665 Keys->defaultIndex = (u8)key_index;
9666 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9667 setKey.keyId = key_index;
9668 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309669
9670 vos_mem_copy(&setKey.Key[0],
9671 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009672 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309673
Gopichand Nakkala29149562013-05-10 21:43:41 +05309674 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309675
9676 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07009677 &pHddStaCtx->conn_info.bssId[0],
9678 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309679
Gopichand Nakkala29149562013-05-10 21:43:41 +05309680 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
9681 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
9682 eCSR_ENCRYPT_TYPE_WEP104)
9683 {
9684 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
9685 even though ap is configured for WEP-40 encryption. In this canse the key length
9686 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
9687 type(104) and switching encryption type to 40*/
9688 pWextState->roamProfile.EncryptionType.encryptionType[0] =
9689 eCSR_ENCRYPT_TYPE_WEP40;
9690 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
9691 eCSR_ENCRYPT_TYPE_WEP40;
9692 }
9693
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309694 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07009695 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309696
Jeff Johnson295189b2012-06-20 16:38:30 -07009697 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309698 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009699 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309700
Jeff Johnson295189b2012-06-20 16:38:30 -07009701 if ( 0 != status )
9702 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309703 hddLog(VOS_TRACE_LEVEL_ERROR,
9704 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009705 status);
9706 return -EINVAL;
9707 }
9708 }
9709 }
9710
9711 /* In SoftAp mode setting key direction for default mode */
9712 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
9713 {
9714 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
9715 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
9716 (eCSR_ENCRYPT_TYPE_AES !=
9717 pWextState->roamProfile.EncryptionType.encryptionType[0])
9718 )
9719 {
9720 /* Saving key direction for default key index to TX default */
9721 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9722 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
9723 }
9724 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309725 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009726 return status;
9727}
9728
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309729#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9730static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9731 struct net_device *ndev,
9732 u8 key_index,
9733 bool unicast, bool multicast)
9734#else
9735static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9736 struct net_device *ndev,
9737 u8 key_index)
9738#endif
9739{
9740 int ret;
9741 vos_ssr_protect(__func__);
9742#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9743 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
9744 multicast);
9745#else
9746 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
9747#endif
9748 vos_ssr_unprotect(__func__);
9749
9750 return ret;
9751}
9752
Jeff Johnson295189b2012-06-20 16:38:30 -07009753/*
9754 * FUNCTION: wlan_hdd_cfg80211_inform_bss
9755 * This function is used to inform the BSS details to nl80211 interface.
9756 */
9757static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
9758 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
9759{
9760 struct net_device *dev = pAdapter->dev;
9761 struct wireless_dev *wdev = dev->ieee80211_ptr;
9762 struct wiphy *wiphy = wdev->wiphy;
9763 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
9764 int chan_no;
9765 int ie_length;
9766 const char *ie;
9767 unsigned int freq;
9768 struct ieee80211_channel *chan;
9769 int rssi = 0;
9770 struct cfg80211_bss *bss = NULL;
9771
Jeff Johnson295189b2012-06-20 16:38:30 -07009772 if( NULL == pBssDesc )
9773 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009774 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009775 return bss;
9776 }
9777
9778 chan_no = pBssDesc->channelId;
9779 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
9780 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
9781
9782 if( NULL == ie )
9783 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009784 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009785 return bss;
9786 }
9787
9788#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9789 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9790 {
9791 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9792 }
9793 else
9794 {
9795 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9796 }
9797#else
9798 freq = ieee80211_channel_to_frequency(chan_no);
9799#endif
9800
9801 chan = __ieee80211_get_channel(wiphy, freq);
9802
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05309803 if (!chan) {
9804 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
9805 return NULL;
9806 }
9807
Abhishek Singhaee43942014-06-16 18:55:47 +05309808 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07009809
Anand N Sunkad9f80b742015-07-30 20:05:51 +05309810 return cfg80211_inform_bss(wiphy, chan,
9811#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9812 CFG80211_BSS_FTYPE_UNKNOWN,
9813#endif
9814 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309815 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07009816 pBssDesc->capabilityInfo,
9817 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05309818 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07009819}
9820
9821
9822
9823/*
9824 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
9825 * This function is used to inform the BSS details to nl80211 interface.
9826 */
9827struct cfg80211_bss*
9828wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
9829 tSirBssDescription *bss_desc
9830 )
9831{
9832 /*
9833 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
9834 already exists in bss data base of cfg80211 for that particular BSS ID.
9835 Using cfg80211_inform_bss_frame to update the bss entry instead of
9836 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
9837 now there is no possibility to get the mgmt(probe response) frame from PE,
9838 converting bss_desc to ieee80211_mgmt(probe response) and passing to
9839 cfg80211_inform_bss_frame.
9840 */
9841 struct net_device *dev = pAdapter->dev;
9842 struct wireless_dev *wdev = dev->ieee80211_ptr;
9843 struct wiphy *wiphy = wdev->wiphy;
9844 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009845#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9846 qcom_ie_age *qie_age = NULL;
9847 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
9848#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009849 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009850#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009851 const char *ie =
9852 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
9853 unsigned int freq;
9854 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309855 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009856 struct cfg80211_bss *bss_status = NULL;
9857 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
9858 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07009859 hdd_context_t *pHddCtx;
9860 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07009861#ifdef WLAN_OPEN_SOURCE
9862 struct timespec ts;
9863#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009864
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309865
Wilson Yangf80a0542013-10-07 13:02:37 -07009866 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9867 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -07009868 if (0 != status)
9869 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009870 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009871 }
9872
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309873 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07009874 if (!mgmt)
9875 {
9876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9877 "%s: memory allocation failed ", __func__);
9878 return NULL;
9879 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009880
Jeff Johnson295189b2012-06-20 16:38:30 -07009881 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07009882
9883#ifdef WLAN_OPEN_SOURCE
9884 /* Android does not want the timestamp from the frame.
9885 Instead it wants a monotonic increasing value */
9886 get_monotonic_boottime(&ts);
9887 mgmt->u.probe_resp.timestamp =
9888 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
9889#else
9890 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009891 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
9892 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07009893
9894#endif
9895
Jeff Johnson295189b2012-06-20 16:38:30 -07009896 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
9897 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009898
9899#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9900 /* GPS Requirement: need age ie per entry. Using vendor specific. */
9901 /* Assuming this is the last IE, copy at the end */
9902 ie_length -=sizeof(qcom_ie_age);
9903 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
9904 qie_age->element_id = QCOM_VENDOR_IE_ID;
9905 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
9906 qie_age->oui_1 = QCOM_OUI1;
9907 qie_age->oui_2 = QCOM_OUI2;
9908 qie_age->oui_3 = QCOM_OUI3;
9909 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
9910 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
9911#endif
9912
Jeff Johnson295189b2012-06-20 16:38:30 -07009913 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05309914 if (bss_desc->fProbeRsp)
9915 {
9916 mgmt->frame_control |=
9917 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
9918 }
9919 else
9920 {
9921 mgmt->frame_control |=
9922 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
9923 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009924
9925#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309926 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009927 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
9928 {
9929 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9930 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309931 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009932 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
9933
9934 {
9935 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9936 }
9937 else
9938 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309939 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
9940 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07009941 kfree(mgmt);
9942 return NULL;
9943 }
9944#else
9945 freq = ieee80211_channel_to_frequency(chan_no);
9946#endif
9947 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009948 /*when the band is changed on the fly using the GUI, three things are done
9949 * 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)
9950 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
9951 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
9952 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
9953 * and discards the channels correponding to previous band and calls back with zero bss results.
9954 * 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
9955 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
9956 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
9957 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
9958 * So drop the bss and continue to next bss.
9959 */
9960 if(chan == NULL)
9961 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309962 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07009963 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009964 return NULL;
9965 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +05309966 /*To keep the rssi icon of the connected AP in the scan window
9967 *and the rssi icon of the wireless networks in sync
9968 * */
9969 if (( eConnectionState_Associated ==
9970 pAdapter->sessionCtx.station.conn_info.connState ) &&
9971 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
9972 pAdapter->sessionCtx.station.conn_info.bssId,
9973 WNI_CFG_BSSID_LEN)) &&
9974 (pHddCtx->hdd_wlan_suspended == FALSE))
9975 {
9976 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
9977 rssi = (pAdapter->rssi * 100);
9978 }
9979 else
9980 {
9981 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
9982 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009983
Nirav Shah20ac06f2013-12-12 18:14:06 +05309984 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +05309985 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
9986 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +05309987
Jeff Johnson295189b2012-06-20 16:38:30 -07009988 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
9989 frame_len, rssi, GFP_KERNEL);
9990 kfree(mgmt);
9991 return bss_status;
9992}
9993
9994/*
9995 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
9996 * This function is used to update the BSS data base of CFG8011
9997 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309998struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009999 tCsrRoamInfo *pRoamInfo
10000 )
10001{
10002 tCsrRoamConnectedProfile roamProfile;
10003 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10004 struct cfg80211_bss *bss = NULL;
10005
10006 ENTER();
10007
10008 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
10009 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
10010
10011 if (NULL != roamProfile.pBssDesc)
10012 {
Girish Gowlif4b68022014-08-28 23:18:57 +053010013 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10014 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070010015
10016 if (NULL == bss)
10017 {
10018 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
10019 __func__);
10020 }
10021
10022 sme_RoamFreeConnectProfile(hHal, &roamProfile);
10023 }
10024 else
10025 {
10026 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
10027 __func__);
10028 }
10029 return bss;
10030}
10031
10032/*
10033 * FUNCTION: wlan_hdd_cfg80211_update_bss
10034 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010035static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
10036 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070010037 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010038{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010039 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010040 tCsrScanResultInfo *pScanResult;
10041 eHalStatus status = 0;
10042 tScanResultHandle pResult;
10043 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010044 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010045 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070010046 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010047
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010048 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10049 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
10050 NO_SESSION, pAdapter->sessionId));
10051
Wilson Yangf80a0542013-10-07 13:02:37 -070010052 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10053
10054 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070010055 {
Wilson Yangf80a0542013-10-07 13:02:37 -070010056 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10057 "%s:LOGP in Progress. Ignore!!!",__func__);
10058 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010059 }
10060
Wilson Yangf80a0542013-10-07 13:02:37 -070010061
10062 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053010063 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070010064 {
10065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10066 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
10067 return VOS_STATUS_E_PERM;
10068 }
10069
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010070 if (pAdapter->request != NULL)
10071 {
10072 if ((pAdapter->request->n_ssids == 1)
10073 && (pAdapter->request->ssids != NULL)
10074 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
10075 is_p2p_scan = true;
10076 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010077 /*
10078 * start getting scan results and populate cgf80211 BSS database
10079 */
10080 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
10081
10082 /* no scan results */
10083 if (NULL == pResult)
10084 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010085 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
10086 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053010087 wlan_hdd_get_frame_logs(pAdapter,
10088 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070010089 return status;
10090 }
10091
10092 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
10093
10094 while (pScanResult)
10095 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010096 /*
10097 * cfg80211_inform_bss() is not updating ie field of bss entry, if
10098 * entry already exists in bss data base of cfg80211 for that
10099 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
10100 * bss entry instead of cfg80211_inform_bss, But this call expects
10101 * mgmt packet as input. As of now there is no possibility to get
10102 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070010103 * ieee80211_mgmt(probe response) and passing to c
10104 * fg80211_inform_bss_frame.
10105 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010106 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
10107 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
10108 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010109 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10110 continue; //Skip the non p2p bss entries
10111 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010112 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10113 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010114
Jeff Johnson295189b2012-06-20 16:38:30 -070010115
10116 if (NULL == bss_status)
10117 {
10118 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010119 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010120 }
10121 else
10122 {
Yue Maf49ba872013-08-19 12:04:25 -070010123 cfg80211_put_bss(
10124#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
10125 wiphy,
10126#endif
10127 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010128 }
10129
10130 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10131 }
10132
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010133 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010134 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010135 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010136}
10137
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010138void
10139hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
10140{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010141 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080010142 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010143} /****** end hddPrintMacAddr() ******/
10144
10145void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010146hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010147{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010148 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010149 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010150 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
10151 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
10152 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010153} /****** end hddPrintPmkId() ******/
10154
10155//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
10156//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
10157
10158//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
10159//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
10160
10161#define dump_bssid(bssid) \
10162 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010163 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
10164 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010165 }
10166
10167#define dump_pmkid(pMac, pmkid) \
10168 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010169 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
10170 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010171 }
10172
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070010173#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010174/*
10175 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
10176 * This function is used to notify the supplicant of a new PMKSA candidate.
10177 */
10178int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010179 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010180 int index, bool preauth )
10181{
Jeff Johnsone7245742012-09-05 17:12:55 -070010182#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010183 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010184 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010185
10186 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070010187 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010188
10189 if( NULL == pRoamInfo )
10190 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010191 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010192 return -EINVAL;
10193 }
10194
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010195 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
10196 {
10197 dump_bssid(pRoamInfo->bssid);
10198 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010199 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010200 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010201#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010202 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010203}
10204#endif //FEATURE_WLAN_LFR
10205
Yue Maef608272013-04-08 23:09:17 -070010206#ifdef FEATURE_WLAN_LFR_METRICS
10207/*
10208 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
10209 * 802.11r/LFR metrics reporting function to report preauth initiation
10210 *
10211 */
10212#define MAX_LFR_METRICS_EVENT_LENGTH 100
10213VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
10214 tCsrRoamInfo *pRoamInfo)
10215{
10216 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10217 union iwreq_data wrqu;
10218
10219 ENTER();
10220
10221 if (NULL == pAdapter)
10222 {
10223 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10224 return VOS_STATUS_E_FAILURE;
10225 }
10226
10227 /* create the event */
10228 memset(&wrqu, 0, sizeof(wrqu));
10229 memset(metrics_notification, 0, sizeof(metrics_notification));
10230
10231 wrqu.data.pointer = metrics_notification;
10232 wrqu.data.length = scnprintf(metrics_notification,
10233 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
10234 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10235
10236 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10237
10238 EXIT();
10239
10240 return VOS_STATUS_SUCCESS;
10241}
10242
10243/*
10244 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
10245 * 802.11r/LFR metrics reporting function to report preauth completion
10246 * or failure
10247 */
10248VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
10249 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
10250{
10251 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10252 union iwreq_data wrqu;
10253
10254 ENTER();
10255
10256 if (NULL == pAdapter)
10257 {
10258 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10259 return VOS_STATUS_E_FAILURE;
10260 }
10261
10262 /* create the event */
10263 memset(&wrqu, 0, sizeof(wrqu));
10264 memset(metrics_notification, 0, sizeof(metrics_notification));
10265
10266 scnprintf(metrics_notification, sizeof(metrics_notification),
10267 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
10268 MAC_ADDR_ARRAY(pRoamInfo->bssid));
10269
10270 if (1 == preauth_status)
10271 strncat(metrics_notification, " TRUE", 5);
10272 else
10273 strncat(metrics_notification, " FALSE", 6);
10274
10275 wrqu.data.pointer = metrics_notification;
10276 wrqu.data.length = strlen(metrics_notification);
10277
10278 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10279
10280 EXIT();
10281
10282 return VOS_STATUS_SUCCESS;
10283}
10284
10285/*
10286 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
10287 * 802.11r/LFR metrics reporting function to report handover initiation
10288 *
10289 */
10290VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
10291 tCsrRoamInfo *pRoamInfo)
10292{
10293 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10294 union iwreq_data wrqu;
10295
10296 ENTER();
10297
10298 if (NULL == pAdapter)
10299 {
10300 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10301 return VOS_STATUS_E_FAILURE;
10302 }
10303
10304 /* create the event */
10305 memset(&wrqu, 0, sizeof(wrqu));
10306 memset(metrics_notification, 0, sizeof(metrics_notification));
10307
10308 wrqu.data.pointer = metrics_notification;
10309 wrqu.data.length = scnprintf(metrics_notification,
10310 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
10311 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10312
10313 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10314
10315 EXIT();
10316
10317 return VOS_STATUS_SUCCESS;
10318}
10319#endif
10320
Jeff Johnson295189b2012-06-20 16:38:30 -070010321/*
10322 * FUNCTION: hdd_cfg80211_scan_done_callback
10323 * scanning callback function, called after finishing scan
10324 *
10325 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010326static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070010327 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
10328{
10329 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010330 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070010331 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010332 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010333 struct cfg80211_scan_request *req = NULL;
10334 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010335 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010336 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010337 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010338 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010339
10340 ENTER();
10341
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010342 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053010343 if (NULL == pHddCtx) {
10344 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010345 goto allow_suspend;
10346 }
10347
10348 pScanInfo = &pHddCtx->scan_info;
10349
Jeff Johnson295189b2012-06-20 16:38:30 -070010350 hddLog(VOS_TRACE_LEVEL_INFO,
10351 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080010352 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010353 __func__, halHandle, pContext, (int) scanId, (int) status);
10354
Kiet Lamac06e2c2013-10-23 16:25:07 +053010355 pScanInfo->mScanPendingCounter = 0;
10356
Jeff Johnson295189b2012-06-20 16:38:30 -070010357 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010358 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070010359 &pScanInfo->scan_req_completion_event,
10360 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010361 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070010362 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010363 hddLog(VOS_TRACE_LEVEL_ERROR,
10364 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070010365 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010366 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010367 }
10368
Yue Maef608272013-04-08 23:09:17 -070010369 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010370 {
10371 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010372 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010373 }
10374
10375 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010376 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070010377 {
10378 hddLog(VOS_TRACE_LEVEL_INFO,
10379 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010380 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070010381 (int) scanId);
10382 }
10383
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010384 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010385 pAdapter);
10386
10387 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010388 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010389
10390
10391 /* If any client wait scan result through WEXT
10392 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010393 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070010394 {
10395 /* The other scan request waiting for current scan finish
10396 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010397 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010398 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010399 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070010400 }
10401 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010402 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010403 {
10404 struct net_device *dev = pAdapter->dev;
10405 union iwreq_data wrqu;
10406 int we_event;
10407 char *msg;
10408
10409 memset(&wrqu, '\0', sizeof(wrqu));
10410 we_event = SIOCGIWSCAN;
10411 msg = NULL;
10412 wireless_send_event(dev, we_event, &wrqu, msg);
10413 }
10414 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010415 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010416
10417 /* Get the Scan Req */
10418 req = pAdapter->request;
10419
10420 if (!req)
10421 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010422 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010423 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010424 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010425 }
10426
Jeff Johnson295189b2012-06-20 16:38:30 -070010427 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070010428 /* Scan is no longer pending */
10429 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010430
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010431 /* last_scan_timestamp is used to decide if new scan
10432 * is needed or not on station interface. If last station
10433 * scan time and new station scan time is less then
10434 * last_scan_timestamp ; driver will return cached scan.
10435 */
10436 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
10437 {
10438 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
10439
10440 if ( req->n_channels )
10441 {
10442 for (i = 0; i < req->n_channels ; i++ )
10443 {
10444 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
10445 }
10446 /* store no of channel scanned */
10447 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
10448 }
10449
10450 }
10451
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070010452 /*
10453 * cfg80211_scan_done informing NL80211 about completion
10454 * of scanning
10455 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010456 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
10457 {
10458 aborted = true;
10459 }
10460 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080010461 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010462
Siddharth Bhal76972212014-10-15 16:22:51 +053010463 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
10464 /* Generate new random mac addr for next scan */
10465 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
10466 hdd_processSpoofMacAddrRequest(pHddCtx);
10467 }
10468
Jeff Johnsone7245742012-09-05 17:12:55 -070010469allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010470 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010471 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010472
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010473 /* Acquire wakelock to handle the case where APP's tries to suspend
10474 * immediatly after the driver gets connect request(i.e after scan)
10475 * from supplicant, this result in app's is suspending and not able
10476 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010477 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010478
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010479#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010480 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010481#endif
10482
Jeff Johnson295189b2012-06-20 16:38:30 -070010483 EXIT();
10484 return 0;
10485}
10486
10487/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053010488 * FUNCTION: hdd_isConnectionInProgress
10489 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010490 *
10491 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010492v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010493{
10494 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10495 hdd_station_ctx_t *pHddStaCtx = NULL;
10496 hdd_adapter_t *pAdapter = NULL;
10497 VOS_STATUS status = 0;
10498 v_U8_t staId = 0;
10499 v_U8_t *staMac = NULL;
10500
c_hpothu9b781ba2013-12-30 20:57:45 +053010501 if (TRUE == pHddCtx->btCoexModeSet)
10502 {
10503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053010504 FL("BTCoex Mode operation in progress"));
10505 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053010506 }
10507
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010508 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10509
10510 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10511 {
10512 pAdapter = pAdapterNode->pAdapter;
10513
10514 if( pAdapter )
10515 {
10516 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010517 "%s: Adapter with device mode %s (%d) exists",
10518 __func__, hdd_device_modetoString(pAdapter->device_mode),
10519 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010520 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053010521 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10522 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
10523 (eConnectionState_Connecting ==
10524 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
10525 {
10526 hddLog(VOS_TRACE_LEVEL_ERROR,
10527 "%s: %p(%d) Connection is in progress", __func__,
10528 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10529 return VOS_TRUE;
10530 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010531 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053010532 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010533 {
10534 hddLog(VOS_TRACE_LEVEL_ERROR,
10535 "%s: %p(%d) Reassociation is in progress", __func__,
10536 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10537 return VOS_TRUE;
10538 }
10539 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010540 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10541 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010542 {
10543 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10544 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010545 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010546 {
10547 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
10548 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010549 "%s: client " MAC_ADDRESS_STR
10550 " is in the middle of WPS/EAPOL exchange.", __func__,
10551 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010552 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010553 }
10554 }
10555 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
10556 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
10557 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010558 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10559 ptSapContext pSapCtx = NULL;
10560 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10561 if(pSapCtx == NULL){
10562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10563 FL("psapCtx is NULL"));
10564 return VOS_FALSE;
10565 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010566 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
10567 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010568 if ((pSapCtx->aStaInfo[staId].isUsed) &&
10569 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010570 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010571 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010572
10573 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010574 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
10575 "middle of WPS/EAPOL exchange.", __func__,
10576 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010577 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010578 }
10579 }
10580 }
10581 }
10582 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10583 pAdapterNode = pNext;
10584 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053010585 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010586}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010587
10588/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010589 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070010590 * this scan respond to scan trigger and update cfg80211 scan database
10591 * later, scan dump command can be used to recieve scan results
10592 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010593int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010594#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10595 struct net_device *dev,
10596#endif
10597 struct cfg80211_scan_request *request)
10598{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010599 hdd_adapter_t *pAdapter = NULL;
10600 hdd_context_t *pHddCtx = NULL;
10601 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010602 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010603 tCsrScanRequest scanRequest;
10604 tANI_U8 *channelList = NULL, i;
10605 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010606 int status;
10607 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010608 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010609 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053010610 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010611 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053010612 v_S7_t rssi=0;
10613 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010614
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010615#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
10616 struct net_device *dev = NULL;
10617 if (NULL == request)
10618 {
10619 hddLog(VOS_TRACE_LEVEL_ERROR,
10620 "%s: scan req param null", __func__);
10621 return -EINVAL;
10622 }
10623 dev = request->wdev->netdev;
10624#endif
10625
10626 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
10627 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
10628 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10629
Jeff Johnson295189b2012-06-20 16:38:30 -070010630 ENTER();
10631
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010632 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10633 __func__, hdd_device_modetoString(pAdapter->device_mode),
10634 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010635
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010636 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010637 if (0 != status)
10638 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010639 return status;
10640 }
10641
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010642 if (NULL == pwextBuf)
10643 {
10644 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
10645 __func__);
10646 return -EIO;
10647 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010648 cfg_param = pHddCtx->cfg_ini;
10649 pScanInfo = &pHddCtx->scan_info;
10650
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053010651 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10652 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
10653 {
10654 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
10655 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
10656 }
10657
Jeff Johnson295189b2012-06-20 16:38:30 -070010658#ifdef WLAN_BTAMP_FEATURE
10659 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010660 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070010661 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010662 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010663 "%s: No scanning when AMP is on", __func__);
10664 return -EOPNOTSUPP;
10665 }
10666#endif
10667 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010668 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010669 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010670 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010671 "%s: Not scanning on device_mode = %s (%d)",
10672 __func__, hdd_device_modetoString(pAdapter->device_mode),
10673 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010674 return -EOPNOTSUPP;
10675 }
10676
10677 if (TRUE == pScanInfo->mScanPending)
10678 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010679 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
10680 {
10681 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
10682 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010683 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010684 }
10685
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053010686 // Don't allow scan if PNO scan is going on.
10687 if (pHddCtx->isPnoEnable)
10688 {
10689 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10690 FL("pno scan in progress"));
10691 return -EBUSY;
10692 }
10693
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010694 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070010695 //Channel and action frame is pending
10696 //Otherwise Cancel Remain On Channel and allow Scan
10697 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010698 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070010699 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010700 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010701 return -EBUSY;
10702 }
10703
Jeff Johnson295189b2012-06-20 16:38:30 -070010704 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
10705 {
10706 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080010707 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010708 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010709 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010710 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
10711 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010712 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010713 "%s: MAX TM Level Scan not allowed", __func__);
10714 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010715 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010716 }
10717 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
10718
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010719 /* Check if scan is allowed at this point of time.
10720 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010721 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010722 {
10723 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
10724 return -EBUSY;
10725 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010726
Jeff Johnson295189b2012-06-20 16:38:30 -070010727 vos_mem_zero( &scanRequest, sizeof(scanRequest));
10728
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010729 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
10730 * Becasue of this, driver is assuming that this is not wildcard scan and so
10731 * is not aging out the scan results.
10732 */
10733 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010734 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010735 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010736 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010737
10738 if ((request->ssids) && (0 < request->n_ssids))
10739 {
10740 tCsrSSIDInfo *SsidInfo;
10741 int j;
10742 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
10743 /* Allocate num_ssid tCsrSSIDInfo structure */
10744 SsidInfo = scanRequest.SSIDs.SSIDList =
10745 ( tCsrSSIDInfo *)vos_mem_malloc(
10746 request->n_ssids*sizeof(tCsrSSIDInfo));
10747
10748 if(NULL == scanRequest.SSIDs.SSIDList)
10749 {
10750 hddLog(VOS_TRACE_LEVEL_ERROR,
10751 "%s: memory alloc failed SSIDInfo buffer", __func__);
10752 return -ENOMEM;
10753 }
10754
10755 /* copy all the ssid's and their length */
10756 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
10757 {
10758 /* get the ssid length */
10759 SsidInfo->SSID.length = request->ssids[j].ssid_len;
10760 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
10761 SsidInfo->SSID.length);
10762 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
10763 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
10764 j, SsidInfo->SSID.ssId);
10765 }
10766 /* set the scan type to active */
10767 scanRequest.scanType = eSIR_ACTIVE_SCAN;
10768 }
10769 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070010770 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010771 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10772 TRACE_CODE_HDD_CFG80211_SCAN,
10773 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070010774 /* set the scan type to active */
10775 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010776 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010777 else
10778 {
10779 /*Set the scan type to default type, in this case it is ACTIVE*/
10780 scanRequest.scanType = pScanInfo->scan_mode;
10781 }
10782 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
10783 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070010784
10785 /* set BSSType to default type */
10786 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
10787
10788 /*TODO: scan the requested channels only*/
10789
10790 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010791 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070010792 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010793 hddLog(VOS_TRACE_LEVEL_WARN,
10794 "No of Scan Channels exceeded limit: %d", request->n_channels);
10795 request->n_channels = MAX_CHANNEL;
10796 }
10797
10798 hddLog(VOS_TRACE_LEVEL_INFO,
10799 "No of Scan Channels: %d", request->n_channels);
10800
10801
10802 if( request->n_channels )
10803 {
10804 char chList [(request->n_channels*5)+1];
10805 int len;
10806 channelList = vos_mem_malloc( request->n_channels );
10807 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053010808 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010809 hddLog(VOS_TRACE_LEVEL_ERROR,
10810 "%s: memory alloc failed channelList", __func__);
10811 status = -ENOMEM;
10812 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053010813 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010814
10815 for( i = 0, len = 0; i < request->n_channels ; i++ )
10816 {
10817 channelList[i] = request->channels[i]->hw_value;
10818 len += snprintf(chList+len, 5, "%d ", channelList[i]);
10819 }
10820
Nirav Shah20ac06f2013-12-12 18:14:06 +053010821 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010822 "Channel-List: %s ", chList);
10823 }
c_hpothu53512302014-04-15 18:49:53 +053010824
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010825 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
10826 scanRequest.ChannelInfo.ChannelList = channelList;
10827
10828 /* set requestType to full scan */
10829 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10830
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010831 /* if there is back to back scan happening in driver with in
10832 * nDeferScanTimeInterval interval driver should defer new scan request
10833 * and should provide last cached scan results instead of new channel list.
10834 * This rule is not applicable if scan is p2p scan.
10835 * This condition will work only in case when last request no of channels
10836 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053010837 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053010838 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010839 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010840
Sushant Kaushik86592172015-04-27 16:35:03 +053010841 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
10842 /* if wps ie is NULL , then only defer scan */
10843 if ( pWpsIe == NULL &&
10844 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053010845 {
10846 if ( pScanInfo->last_scan_timestamp !=0 &&
10847 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
10848 {
10849 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
10850 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
10851 vos_mem_compare(pScanInfo->last_scan_channelList,
10852 channelList, pScanInfo->last_scan_numChannels))
10853 {
10854 hddLog(VOS_TRACE_LEVEL_WARN,
10855 " New and old station scan time differ is less then %u",
10856 pHddCtx->cfg_ini->nDeferScanTimeInterval);
10857
10858 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010859 pAdapter);
10860
Agarwal Ashish57e84372014-12-05 18:26:53 +053010861 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010862 "Return old cached scan as all channels and no of channels are same");
10863
Agarwal Ashish57e84372014-12-05 18:26:53 +053010864 if (0 > ret)
10865 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010866
Agarwal Ashish57e84372014-12-05 18:26:53 +053010867 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010868
10869 status = eHAL_STATUS_SUCCESS;
10870 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053010871 }
10872 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010873 }
10874
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010875 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10876 * search (Flush on both full scan and social scan but not on single
10877 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10878 */
10879
10880 /* Supplicant does single channel scan after 8-way handshake
10881 * and in that case driver shoudnt flush scan results. If
10882 * driver flushes the scan results here and unfortunately if
10883 * the AP doesnt respond to our probe req then association
10884 * fails which is not desired
10885 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010886 if ((request->n_ssids == 1)
10887 && (request->ssids != NULL)
10888 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
10889 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010890
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010891 if( is_p2p_scan ||
10892 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010893 {
10894 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
10895 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
10896 pAdapter->sessionId );
10897 }
10898
10899 if( request->ie_len )
10900 {
10901 /* save this for future association (join requires this) */
10902 /*TODO: Array needs to be converted to dynamic allocation,
10903 * as multiple ie.s can be sent in cfg80211_scan_request structure
10904 * CR 597966
10905 */
10906 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
10907 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
10908 pScanInfo->scanAddIE.length = request->ie_len;
10909
10910 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10911 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10912 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010913 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053010914 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070010915 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010916 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
10917 memcpy( pwextBuf->roamProfile.addIEScan,
10918 request->ie, request->ie_len);
10919 }
10920 else
10921 {
10922 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
10923 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070010924 }
10925
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010926 }
10927 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
10928 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
10929
10930 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
10931 request->ie_len);
10932 if (pP2pIe != NULL)
10933 {
10934#ifdef WLAN_FEATURE_P2P_DEBUG
10935 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
10936 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
10937 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053010938 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010939 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
10940 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10941 "Go nego completed to Connection is started");
10942 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10943 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053010944 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010945 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
10946 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010947 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010948 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
10949 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10950 "Disconnected state to Connection is started");
10951 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10952 "for 4way Handshake");
10953 }
10954#endif
10955
10956 /* no_cck will be set during p2p find to disable 11b rates */
10957 if(TRUE == request->no_cck)
10958 {
10959 hddLog(VOS_TRACE_LEVEL_INFO,
10960 "%s: This is a P2P Search", __func__);
10961 scanRequest.p2pSearch = 1;
10962
10963 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053010964 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010965 /* set requestType to P2P Discovery */
10966 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
10967 }
10968
10969 /*
10970 Skip Dfs Channel in case of P2P Search
10971 if it is set in ini file
10972 */
10973 if(cfg_param->skipDfsChnlInP2pSearch)
10974 {
10975 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010976 }
10977 else
10978 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010979 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010980 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010981
Agarwal Ashish4f616132013-12-30 23:32:50 +053010982 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010983 }
10984 }
10985
10986 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
10987
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010988#ifdef FEATURE_WLAN_TDLS
10989 /* if tdls disagree scan right now, return immediately.
10990 tdls will schedule the scan when scan is allowed. (return SUCCESS)
10991 or will reject the scan if any TDLS is in progress. (return -EBUSY)
10992 */
10993 status = wlan_hdd_tdls_scan_callback (pAdapter,
10994 wiphy,
10995#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10996 dev,
10997#endif
10998 request);
10999 if(status <= 0)
11000 {
11001 if(!status)
11002 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
11003 "scan rejected %d", __func__, status);
11004 else
11005 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
11006 __func__, status);
11007
11008 return status;
11009 }
11010#endif
11011
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011012 /* acquire the wakelock to avoid the apps suspend during the scan. To
11013 * address the following issues.
11014 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
11015 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
11016 * for long time, this result in apps running at full power for long time.
11017 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
11018 * be stuck in full power because of resume BMPS
11019 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011020 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011021
Nirav Shah20ac06f2013-12-12 18:14:06 +053011022 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11023 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011024 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
11025 scanRequest.requestType, scanRequest.scanType,
11026 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053011027 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
11028
Siddharth Bhal76972212014-10-15 16:22:51 +053011029 if (pHddCtx->spoofMacAddr.isEnabled)
11030 {
11031 hddLog(VOS_TRACE_LEVEL_INFO,
11032 "%s: MAC Spoofing enabled for current scan", __func__);
11033 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
11034 * to fill TxBds for probe request during current scan
11035 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011036 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053011037 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011038
11039 if(status != VOS_STATUS_SUCCESS)
11040 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011041 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011042 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053011043#ifdef FEATURE_WLAN_TDLS
11044 wlan_hdd_tdls_scan_done_callback(pAdapter);
11045#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011046 goto free_mem;
11047 }
Siddharth Bhal76972212014-10-15 16:22:51 +053011048 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053011049 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070011050 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011051 pAdapter->sessionId, &scanRequest, &scanId,
11052 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070011053
Jeff Johnson295189b2012-06-20 16:38:30 -070011054 if (eHAL_STATUS_SUCCESS != status)
11055 {
11056 hddLog(VOS_TRACE_LEVEL_ERROR,
11057 "%s: sme_ScanRequest returned error %d", __func__, status);
11058 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011059 if(eHAL_STATUS_RESOURCES == status)
11060 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011061 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
11062 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011063 status = -EBUSY;
11064 } else {
11065 status = -EIO;
11066 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011067 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011068
11069#ifdef FEATURE_WLAN_TDLS
11070 wlan_hdd_tdls_scan_done_callback(pAdapter);
11071#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011072 goto free_mem;
11073 }
11074
11075 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011076 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011077 pAdapter->request = request;
11078 pScanInfo->scanId = scanId;
11079
11080 complete(&pScanInfo->scan_req_completion_event);
11081
11082free_mem:
11083 if( scanRequest.SSIDs.SSIDList )
11084 {
11085 vos_mem_free(scanRequest.SSIDs.SSIDList);
11086 }
11087
11088 if( channelList )
11089 vos_mem_free( channelList );
11090
11091 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011092 return status;
11093}
11094
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011095int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
11096#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11097 struct net_device *dev,
11098#endif
11099 struct cfg80211_scan_request *request)
11100{
11101 int ret;
11102
11103 vos_ssr_protect(__func__);
11104 ret = __wlan_hdd_cfg80211_scan(wiphy,
11105#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11106 dev,
11107#endif
11108 request);
11109 vos_ssr_unprotect(__func__);
11110
11111 return ret;
11112}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011113
11114void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
11115{
11116 v_U8_t iniDot11Mode =
11117 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
11118 eHddDot11Mode hddDot11Mode = iniDot11Mode;
11119
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011120 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
11121 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011122 switch ( iniDot11Mode )
11123 {
11124 case eHDD_DOT11_MODE_AUTO:
11125 case eHDD_DOT11_MODE_11ac:
11126 case eHDD_DOT11_MODE_11ac_ONLY:
11127#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053011128 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
11129 sme_IsFeatureSupportedByFW(DOT11AC) )
11130 hddDot11Mode = eHDD_DOT11_MODE_11ac;
11131 else
11132 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011133#else
11134 hddDot11Mode = eHDD_DOT11_MODE_11n;
11135#endif
11136 break;
11137 case eHDD_DOT11_MODE_11n:
11138 case eHDD_DOT11_MODE_11n_ONLY:
11139 hddDot11Mode = eHDD_DOT11_MODE_11n;
11140 break;
11141 default:
11142 hddDot11Mode = iniDot11Mode;
11143 break;
11144 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011145#ifdef WLAN_FEATURE_AP_HT40_24G
11146 if (operationChannel > SIR_11B_CHANNEL_END)
11147#endif
11148 {
11149 /* This call decides required channel bonding mode */
11150 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011151 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
11152 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011153 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011154}
11155
Jeff Johnson295189b2012-06-20 16:38:30 -070011156/*
11157 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011158 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011159 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011160int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011161 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070011162{
11163 int status = 0;
11164 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080011165 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011166 v_U32_t roamId;
11167 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070011168 eCsrAuthType RSNAuthType;
11169
11170 ENTER();
11171
11172 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080011173 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11174
11175 status = wlan_hdd_validate_context(pHddCtx);
11176 if (status)
11177 {
Yue Mae36e3552014-03-05 17:06:20 -080011178 return status;
11179 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011180
Jeff Johnson295189b2012-06-20 16:38:30 -070011181 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
11182 {
11183 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
11184 return -EINVAL;
11185 }
11186
11187 pRoamProfile = &pWextState->roamProfile;
11188
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011189 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070011190 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011191 hdd_station_ctx_t *pHddStaCtx;
11192 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011193
Siddharth Bhalda0d1622015-04-24 15:47:49 +053011194 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
11195
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011196 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070011197 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
11198 {
11199 /*QoS not enabled in cfg file*/
11200 pRoamProfile->uapsd_mask = 0;
11201 }
11202 else
11203 {
11204 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011205 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070011206 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
11207 }
11208
11209 pRoamProfile->SSIDs.numOfSSIDs = 1;
11210 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
11211 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011212 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070011213 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
11214 ssid, ssid_len);
11215
11216 if (bssid)
11217 {
11218 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
11219 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
11220 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011221 /* Save BSSID in seperate variable as well, as RoamProfile
11222 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070011223 case of join failure we should send valid BSSID to supplicant
11224 */
11225 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
11226 WNI_CFG_BSSID_LEN);
11227 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070011228 else
11229 {
11230 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
11231 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011232
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011233 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
11234 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011235 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
11236 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011237 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011238 /*set gen ie*/
11239 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
11240 /*set auth*/
11241 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
11242 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011243#ifdef FEATURE_WLAN_WAPI
11244 if (pAdapter->wapi_info.nWapiMode)
11245 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011246 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011247 switch (pAdapter->wapi_info.wapiAuthMode)
11248 {
11249 case WAPI_AUTH_MODE_PSK:
11250 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011251 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011252 pAdapter->wapi_info.wapiAuthMode);
11253 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
11254 break;
11255 }
11256 case WAPI_AUTH_MODE_CERT:
11257 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011258 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011259 pAdapter->wapi_info.wapiAuthMode);
11260 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
11261 break;
11262 }
11263 } // End of switch
11264 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
11265 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
11266 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011267 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011268 pRoamProfile->AuthType.numEntries = 1;
11269 pRoamProfile->EncryptionType.numEntries = 1;
11270 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11271 pRoamProfile->mcEncryptionType.numEntries = 1;
11272 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11273 }
11274 }
11275#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011276#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011277 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011278 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11279 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
11280 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011281 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
11282 sizeof (tSirGtkOffloadParams));
11283 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011284 }
11285#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011286 pRoamProfile->csrPersona = pAdapter->device_mode;
11287
Jeff Johnson32d95a32012-09-10 13:15:23 -070011288 if( operatingChannel )
11289 {
11290 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
11291 pRoamProfile->ChannelInfo.numOfChannels = 1;
11292 }
Chet Lanctot186b5732013-03-18 10:26:30 -070011293 else
11294 {
11295 pRoamProfile->ChannelInfo.ChannelList = NULL;
11296 pRoamProfile->ChannelInfo.numOfChannels = 0;
11297 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011298 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
11299 {
11300 hdd_select_cbmode(pAdapter,operatingChannel);
11301 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011302
Agarwal Ashish40f9b872015-09-01 16:17:35 +053011303 /*
11304 * Change conn_state to connecting before sme_RoamConnect(),
11305 * because sme_RoamConnect() has a direct path to call
11306 * hdd_smeRoamCallback(), which will change the conn_state
11307 * If direct path, conn_state will be accordingly changed
11308 * to NotConnected or Associated by either
11309 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
11310 * in sme_RoamCallback()
11311 * if sme_RomConnect is to be queued,
11312 * Connecting state will remain until it is completed.
11313 * If connection state is not changed,
11314 * connection state will remain in eConnectionState_NotConnected state.
11315 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
11316 * if conn state is eConnectionState_NotConnected.
11317 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
11318 * informed of connect result indication which is an issue.
11319 */
11320
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011321 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11322 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053011323 {
11324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053011325 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011326 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
11327 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053011328 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011329 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011330 pAdapter->sessionId, pRoamProfile, &roamId);
11331
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011332 if ((eHAL_STATUS_SUCCESS != status) &&
11333 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11334 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011335
11336 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053011337 hddLog(VOS_TRACE_LEVEL_ERROR,
11338 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
11339 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011340 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011341 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011342 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011343 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011344
11345 pRoamProfile->ChannelInfo.ChannelList = NULL;
11346 pRoamProfile->ChannelInfo.numOfChannels = 0;
11347
Jeff Johnson295189b2012-06-20 16:38:30 -070011348 }
11349 else
11350 {
11351 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
11352 return -EINVAL;
11353 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011354 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011355 return status;
11356}
11357
11358/*
11359 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
11360 * This function is used to set the authentication type (OPEN/SHARED).
11361 *
11362 */
11363static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
11364 enum nl80211_auth_type auth_type)
11365{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011366 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011367 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11368
11369 ENTER();
11370
11371 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011372 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070011373 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011374 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011375 hddLog(VOS_TRACE_LEVEL_INFO,
11376 "%s: set authentication type to AUTOSWITCH", __func__);
11377 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
11378 break;
11379
11380 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011381#ifdef WLAN_FEATURE_VOWIFI_11R
11382 case NL80211_AUTHTYPE_FT:
11383#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011384 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011385 "%s: set authentication type to OPEN", __func__);
11386 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11387 break;
11388
11389 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011390 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011391 "%s: set authentication type to SHARED", __func__);
11392 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
11393 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011394#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011395 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011396 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011397 "%s: set authentication type to CCKM WPA", __func__);
11398 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
11399 break;
11400#endif
11401
11402
11403 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011404 hddLog(VOS_TRACE_LEVEL_ERROR,
11405 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011406 auth_type);
11407 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
11408 return -EINVAL;
11409 }
11410
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011411 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011412 pHddStaCtx->conn_info.authType;
11413 return 0;
11414}
11415
11416/*
11417 * FUNCTION: wlan_hdd_set_akm_suite
11418 * This function is used to set the key mgmt type(PSK/8021x).
11419 *
11420 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011421static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011422 u32 key_mgmt
11423 )
11424{
11425 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11426 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053011427 /* Should be in ieee802_11_defs.h */
11428#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
11429#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070011430 /*set key mgmt type*/
11431 switch(key_mgmt)
11432 {
11433 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053011434 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011435#ifdef WLAN_FEATURE_VOWIFI_11R
11436 case WLAN_AKM_SUITE_FT_PSK:
11437#endif
11438 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070011439 __func__);
11440 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
11441 break;
11442
11443 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053011444 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011445#ifdef WLAN_FEATURE_VOWIFI_11R
11446 case WLAN_AKM_SUITE_FT_8021X:
11447#endif
11448 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070011449 __func__);
11450 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11451 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011452#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011453#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
11454#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
11455 case WLAN_AKM_SUITE_CCKM:
11456 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
11457 __func__);
11458 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
11459 break;
11460#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070011461#ifndef WLAN_AKM_SUITE_OSEN
11462#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
11463 case WLAN_AKM_SUITE_OSEN:
11464 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
11465 __func__);
11466 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11467 break;
11468#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011469
11470 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011471 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011472 __func__, key_mgmt);
11473 return -EINVAL;
11474
11475 }
11476 return 0;
11477}
11478
11479/*
11480 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011481 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070011482 * (NONE/WEP40/WEP104/TKIP/CCMP).
11483 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011484static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
11485 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070011486 bool ucast
11487 )
11488{
11489 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011490 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011491 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11492
11493 ENTER();
11494
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011495 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011496 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053011497 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070011498 __func__, cipher);
11499 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11500 }
11501 else
11502 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011503
Jeff Johnson295189b2012-06-20 16:38:30 -070011504 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011505 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011506 {
11507 case IW_AUTH_CIPHER_NONE:
11508 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11509 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011510
Jeff Johnson295189b2012-06-20 16:38:30 -070011511 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011512 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070011513 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011514
Jeff Johnson295189b2012-06-20 16:38:30 -070011515 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011516 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070011517 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011518
Jeff Johnson295189b2012-06-20 16:38:30 -070011519 case WLAN_CIPHER_SUITE_TKIP:
11520 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
11521 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011522
Jeff Johnson295189b2012-06-20 16:38:30 -070011523 case WLAN_CIPHER_SUITE_CCMP:
11524 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11525 break;
11526#ifdef FEATURE_WLAN_WAPI
11527 case WLAN_CIPHER_SUITE_SMS4:
11528 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
11529 break;
11530#endif
11531
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011532#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011533 case WLAN_CIPHER_SUITE_KRK:
11534 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
11535 break;
11536#endif
11537 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011538 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011539 __func__, cipher);
11540 return -EOPNOTSUPP;
11541 }
11542 }
11543
11544 if (ucast)
11545 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011546 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011547 __func__, encryptionType);
11548 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11549 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011550 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011551 encryptionType;
11552 }
11553 else
11554 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011555 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011556 __func__, encryptionType);
11557 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
11558 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
11559 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
11560 }
11561
11562 return 0;
11563}
11564
11565
11566/*
11567 * FUNCTION: wlan_hdd_cfg80211_set_ie
11568 * This function is used to parse WPA/RSN IE's.
11569 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011570int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011571#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11572 const u8 *ie,
11573#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011574 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011575#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011576 size_t ie_len
11577 )
11578{
11579 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011580#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11581 const u8 *genie = ie;
11582#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011583 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011584#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011585 v_U16_t remLen = ie_len;
11586#ifdef FEATURE_WLAN_WAPI
11587 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
11588 u16 *tmp;
11589 v_U16_t akmsuiteCount;
11590 int *akmlist;
11591#endif
11592 ENTER();
11593
11594 /* clear previous assocAddIE */
11595 pWextState->assocAddIE.length = 0;
11596 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011597 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011598
11599 while (remLen >= 2)
11600 {
11601 v_U16_t eLen = 0;
11602 v_U8_t elementId;
11603 elementId = *genie++;
11604 eLen = *genie++;
11605 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011606
Arif Hussain6d2a3322013-11-17 19:50:10 -080011607 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070011608 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011609
11610 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070011611 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011612 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011613 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 -070011614 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011615 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011616 "%s: Invalid WPA IE", __func__);
11617 return -EINVAL;
11618 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011619 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070011620 {
11621 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011622 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011623 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011624
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011625 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011626 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011627 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
11628 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011629 VOS_ASSERT(0);
11630 return -ENOMEM;
11631 }
11632 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11633 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11634 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011635
Jeff Johnson295189b2012-06-20 16:38:30 -070011636 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
11637 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11638 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11639 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011640 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
11641 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011642 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
11643 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11644 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
11645 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
11646 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
11647 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011648 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053011649 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011650 {
11651 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011652 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011653 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011654
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011655 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011656 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011657 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11658 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011659 VOS_ASSERT(0);
11660 return -ENOMEM;
11661 }
11662 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11663 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11664 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011665
Jeff Johnson295189b2012-06-20 16:38:30 -070011666 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11667 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11668 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011669#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011670 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
11671 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011672 /*Consider WFD IE, only for P2P Client */
11673 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11674 {
11675 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011676 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011677 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011678
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011679 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011680 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011681 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11682 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011683 VOS_ASSERT(0);
11684 return -ENOMEM;
11685 }
11686 // WFD IE is saved to Additional IE ; it should be accumulated to handle
11687 // WPS IE + P2P IE + WFD IE
11688 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11689 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011690
Jeff Johnson295189b2012-06-20 16:38:30 -070011691 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11692 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11693 }
11694#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011695 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011696 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011697 HS20_OUI_TYPE_SIZE)) )
11698 {
11699 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011700 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011701 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011702
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011703 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011704 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011705 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11706 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011707 VOS_ASSERT(0);
11708 return -ENOMEM;
11709 }
11710 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11711 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011712
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011713 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11714 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11715 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011716 /* Appending OSEN Information Element in Assiciation Request */
11717 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
11718 OSEN_OUI_TYPE_SIZE)) )
11719 {
11720 v_U16_t curAddIELen = pWextState->assocAddIE.length;
11721 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
11722 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011723
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011724 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011725 {
11726 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11727 "Need bigger buffer space");
11728 VOS_ASSERT(0);
11729 return -ENOMEM;
11730 }
11731 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11732 pWextState->assocAddIE.length += eLen + 2;
11733
11734 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
11735 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11736 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11737 }
11738
Abhishek Singh4322e622015-06-10 15:42:54 +053011739 /* Update only for WPA IE */
11740 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
11741 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070011742
11743 /* populating as ADDIE in beacon frames */
11744 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011745 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070011746 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
11747 {
11748 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11749 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
11750 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11751 {
11752 hddLog(LOGE,
11753 "Coldn't pass "
11754 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
11755 }
11756 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
11757 else
11758 hddLog(LOGE,
11759 "Could not pass on "
11760 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
11761
11762 /* IBSS mode doesn't contain params->proberesp_ies still
11763 beaconIE's need to be populated in probe response frames */
11764 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
11765 {
11766 u16 rem_probe_resp_ie_len = eLen + 2;
11767 u8 probe_rsp_ie_len[3] = {0};
11768 u8 counter = 0;
11769
11770 /* Check Probe Resp Length if it is greater then 255 then
11771 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
11772 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
11773 not able Store More then 255 bytes into One Variable */
11774
11775 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
11776 {
11777 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
11778 {
11779 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
11780 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
11781 }
11782 else
11783 {
11784 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
11785 rem_probe_resp_ie_len = 0;
11786 }
11787 }
11788
11789 rem_probe_resp_ie_len = 0;
11790
11791 if (probe_rsp_ie_len[0] > 0)
11792 {
11793 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11794 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
11795 (tANI_U8*)(genie - 2),
11796 probe_rsp_ie_len[0], NULL,
11797 eANI_BOOLEAN_FALSE)
11798 == eHAL_STATUS_FAILURE)
11799 {
11800 hddLog(LOGE,
11801 "Could not pass"
11802 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
11803 }
11804 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
11805 }
11806
11807 if (probe_rsp_ie_len[1] > 0)
11808 {
11809 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11810 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
11811 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11812 probe_rsp_ie_len[1], NULL,
11813 eANI_BOOLEAN_FALSE)
11814 == eHAL_STATUS_FAILURE)
11815 {
11816 hddLog(LOGE,
11817 "Could not pass"
11818 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
11819 }
11820 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
11821 }
11822
11823 if (probe_rsp_ie_len[2] > 0)
11824 {
11825 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11826 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
11827 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11828 probe_rsp_ie_len[2], NULL,
11829 eANI_BOOLEAN_FALSE)
11830 == eHAL_STATUS_FAILURE)
11831 {
11832 hddLog(LOGE,
11833 "Could not pass"
11834 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
11835 }
11836 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
11837 }
11838
11839 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11840 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
11841 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11842 {
11843 hddLog(LOGE,
11844 "Could not pass"
11845 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
11846 }
11847 }
11848 else
11849 {
11850 // Reset WNI_CFG_PROBE_RSP Flags
11851 wlan_hdd_reset_prob_rspies(pAdapter);
11852
11853 hddLog(VOS_TRACE_LEVEL_INFO,
11854 "%s: No Probe Response IE received in set beacon",
11855 __func__);
11856 }
11857 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011858 break;
11859 case DOT11F_EID_RSN:
11860 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
11861 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11862 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
11863 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
11864 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
11865 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053011866
11867 /* Appending Extended Capabilities with Interworking bit set
11868 * in Assoc Req.
11869 *
11870 * In assoc req this EXT Cap will only be taken into account if
11871 * interworkingService bit is set to 1. Currently
11872 * driver is only interested in interworkingService capability
11873 * from supplicant. If in future any other EXT Cap info is
11874 * required from supplicat, it needs to be handled while
11875 * sending Assoc Req in LIM.
11876 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011877 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011878 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011879 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011880 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011881 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011882
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011883 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011884 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011885 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11886 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011887 VOS_ASSERT(0);
11888 return -ENOMEM;
11889 }
11890 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11891 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011892
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011893 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11894 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11895 break;
11896 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011897#ifdef FEATURE_WLAN_WAPI
11898 case WLAN_EID_WAPI:
11899 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011900 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011901 pAdapter->wapi_info.nWapiMode);
11902 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011903 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070011904 akmsuiteCount = WPA_GET_LE16(tmp);
11905 tmp = tmp + 1;
11906 akmlist = (int *)(tmp);
11907 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
11908 {
11909 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
11910 }
11911 else
11912 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011913 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070011914 VOS_ASSERT(0);
11915 return -EINVAL;
11916 }
11917
11918 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
11919 {
11920 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011921 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011922 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011923 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011924 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011925 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011926 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011927 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011928 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
11929 }
11930 break;
11931#endif
11932 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011933 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011934 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011935 /* when Unknown IE is received we should break and continue
11936 * to the next IE in the buffer instead we were returning
11937 * so changing this to break */
11938 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011939 }
11940 genie += eLen;
11941 remLen -= eLen;
11942 }
11943 EXIT();
11944 return 0;
11945}
11946
11947/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053011948 * FUNCTION: hdd_isWPAIEPresent
11949 * Parse the received IE to find the WPA IE
11950 *
11951 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011952static bool hdd_isWPAIEPresent(
11953#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
11954 const u8 *ie,
11955#else
11956 u8 *ie,
11957#endif
11958 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053011959{
11960 v_U8_t eLen = 0;
11961 v_U16_t remLen = ie_len;
11962 v_U8_t elementId = 0;
11963
11964 while (remLen >= 2)
11965 {
11966 elementId = *ie++;
11967 eLen = *ie++;
11968 remLen -= 2;
11969 if (eLen > remLen)
11970 {
11971 hddLog(VOS_TRACE_LEVEL_ERROR,
11972 "%s: IE length is wrong %d", __func__, eLen);
11973 return FALSE;
11974 }
11975 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
11976 {
11977 /* OUI - 0x00 0X50 0XF2
11978 WPA Information Element - 0x01
11979 WPA version - 0x01*/
11980 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
11981 return TRUE;
11982 }
11983 ie += eLen;
11984 remLen -= eLen;
11985 }
11986 return FALSE;
11987}
11988
11989/*
Jeff Johnson295189b2012-06-20 16:38:30 -070011990 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011991 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011992 * parameters during connect operation.
11993 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011994int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011995 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011996 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011997{
11998 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011999 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012000 ENTER();
12001
12002 /*set wpa version*/
12003 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
12004
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012005 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012006 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053012007 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012008 {
12009 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12010 }
12011 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
12012 {
12013 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12014 }
12015 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012016
12017 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012018 pWextState->wpaVersion);
12019
12020 /*set authentication type*/
12021 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
12022
12023 if (0 > status)
12024 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012025 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012026 "%s: failed to set authentication type ", __func__);
12027 return status;
12028 }
12029
12030 /*set key mgmt type*/
12031 if (req->crypto.n_akm_suites)
12032 {
12033 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
12034 if (0 > status)
12035 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012036 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070012037 __func__);
12038 return status;
12039 }
12040 }
12041
12042 /*set pairwise cipher type*/
12043 if (req->crypto.n_ciphers_pairwise)
12044 {
12045 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
12046 req->crypto.ciphers_pairwise[0], true);
12047 if (0 > status)
12048 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012049 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012050 "%s: failed to set unicast cipher type", __func__);
12051 return status;
12052 }
12053 }
12054 else
12055 {
12056 /*Reset previous cipher suite to none*/
12057 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
12058 if (0 > status)
12059 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012060 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012061 "%s: failed to set unicast cipher type", __func__);
12062 return status;
12063 }
12064 }
12065
12066 /*set group cipher type*/
12067 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
12068 false);
12069
12070 if (0 > status)
12071 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012072 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070012073 __func__);
12074 return status;
12075 }
12076
Chet Lanctot186b5732013-03-18 10:26:30 -070012077#ifdef WLAN_FEATURE_11W
12078 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
12079#endif
12080
Jeff Johnson295189b2012-06-20 16:38:30 -070012081 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
12082 if (req->ie_len)
12083 {
12084 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
12085 if ( 0 > status)
12086 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012087 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012088 __func__);
12089 return status;
12090 }
12091 }
12092
12093 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012094 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012095 {
12096 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
12097 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
12098 )
12099 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012100 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070012101 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
12102 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012103 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012104 __func__);
12105 return -EOPNOTSUPP;
12106 }
12107 else
12108 {
12109 u8 key_len = req->key_len;
12110 u8 key_idx = req->key_idx;
12111
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012112 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012113 && (CSR_MAX_NUM_KEY > key_idx)
12114 )
12115 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012116 hddLog(VOS_TRACE_LEVEL_INFO,
12117 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012118 __func__, key_idx, key_len);
12119 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012120 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012121 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012122 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012123 (u8)key_len;
12124 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
12125 }
12126 }
12127 }
12128 }
12129
12130 return status;
12131}
12132
12133/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012134 * FUNCTION: wlan_hdd_try_disconnect
12135 * This function is used to disconnect from previous
12136 * connection
12137 */
12138static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
12139{
12140 long ret = 0;
12141 hdd_station_ctx_t *pHddStaCtx;
12142 eMib_dot11DesiredBssType connectedBssType;
12143
12144 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12145
12146 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
12147
12148 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
12149 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
12150 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
12151 {
12152 /* Issue disconnect to CSR */
12153 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12154 if( eHAL_STATUS_SUCCESS ==
12155 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12156 pAdapter->sessionId,
12157 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12158 {
12159 ret = wait_for_completion_interruptible_timeout(
12160 &pAdapter->disconnect_comp_var,
12161 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12162 if (0 >= ret)
12163 {
12164 hddLog(LOGE, FL("Failed to receive disconnect event"));
12165 return -EALREADY;
12166 }
12167 }
12168 }
12169 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
12170 {
12171 ret = wait_for_completion_interruptible_timeout(
12172 &pAdapter->disconnect_comp_var,
12173 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12174 if (0 >= ret)
12175 {
12176 hddLog(LOGE, FL("Failed to receive disconnect event"));
12177 return -EALREADY;
12178 }
12179 }
12180
12181 return 0;
12182}
12183
12184/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053012185 * FUNCTION: __wlan_hdd_cfg80211_connect
12186 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070012187 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012188static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012189 struct net_device *ndev,
12190 struct cfg80211_connect_params *req
12191 )
12192{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012193 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012194 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012195 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053012196 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012197
12198 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012199
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012200 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12201 TRACE_CODE_HDD_CFG80211_CONNECT,
12202 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012203 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012204 "%s: device_mode = %s (%d)", __func__,
12205 hdd_device_modetoString(pAdapter->device_mode),
12206 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012207
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012208 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012209 if (!pHddCtx)
12210 {
12211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12212 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053012213 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012214 }
12215
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012216 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012217 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012218 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012219 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012220 }
12221
Agarwal Ashish51325b52014-06-16 16:50:49 +053012222 if (vos_max_concurrent_connections_reached()) {
12223 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12224 return -ECONNREFUSED;
12225 }
12226
Jeff Johnson295189b2012-06-20 16:38:30 -070012227#ifdef WLAN_BTAMP_FEATURE
12228 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012229 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070012230 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012231 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012232 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012233 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070012234 }
12235#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012236
12237 //If Device Mode is Station Concurrent Sessions Exit BMps
12238 //P2P Mode will be taken care in Open/close adapter
12239 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012240 (vos_concurrent_open_sessions_running())) {
12241 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
12242 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012243 }
12244
12245 /*Try disconnecting if already in connected state*/
12246 status = wlan_hdd_try_disconnect(pAdapter);
12247 if ( 0 > status)
12248 {
12249 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12250 " connection"));
12251 return -EALREADY;
12252 }
12253
Jeff Johnson295189b2012-06-20 16:38:30 -070012254 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012255 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070012256
12257 if ( 0 > status)
12258 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012259 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070012260 __func__);
12261 return status;
12262 }
Mohit Khanna765234a2012-09-11 15:08:35 -070012263 if ( req->channel )
12264 {
12265 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
12266 req->ssid_len, req->bssid,
12267 req->channel->hw_value);
12268 }
12269 else
12270 {
12271 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012272 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070012273 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012274
Sushant Kaushikd7083982015-03-18 14:33:24 +053012275 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012276 {
12277 //ReEnable BMPS if disabled
12278 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
12279 (NULL != pHddCtx))
12280 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012281 if (pHddCtx->hdd_wlan_suspended)
12282 {
12283 hdd_set_pwrparams(pHddCtx);
12284 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012285 //ReEnable Bmps and Imps back
12286 hdd_enable_bmps_imps(pHddCtx);
12287 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053012288 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070012289 return status;
12290 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012291 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012292 EXIT();
12293 return status;
12294}
12295
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012296static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
12297 struct net_device *ndev,
12298 struct cfg80211_connect_params *req)
12299{
12300 int ret;
12301 vos_ssr_protect(__func__);
12302 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
12303 vos_ssr_unprotect(__func__);
12304
12305 return ret;
12306}
Jeff Johnson295189b2012-06-20 16:38:30 -070012307
12308/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012309 * FUNCTION: wlan_hdd_disconnect
12310 * This function is used to issue a disconnect request to SME
12311 */
12312int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
12313{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012314 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012315 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012316 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012317 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012318
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012319 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012320
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012321 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012322 if (0 != status)
12323 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012324 return status;
12325 }
12326
Sushant Kaushikb4834d22015-07-15 15:29:05 +053012327 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
12328 {
12329 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
12330 pAdapter->sessionId);
12331 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012332 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012333
Agarwal Ashish47d18112014-08-04 19:55:07 +053012334 /* Need to apply spin lock before decreasing active sessions
12335 * as there can be chance for double decrement if context switch
12336 * Calls hdd_DisConnectHandler.
12337 */
12338
12339 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012340 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
12341 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012342 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
12343 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053012344 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
12345 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012346
Abhishek Singhf4669da2014-05-26 15:07:49 +053012347 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053012348 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
12349
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012350 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012351
Mihir Shete182a0b22014-08-18 16:08:48 +053012352 /*
12353 * stop tx queues before deleting STA/BSS context from the firmware.
12354 * tx has to be disabled because the firmware can get busy dropping
12355 * the tx frames after BSS/STA has been deleted and will not send
12356 * back a response resulting in WDI timeout
12357 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053012358 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053012359 netif_tx_disable(pAdapter->dev);
12360 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012361
Mihir Shete182a0b22014-08-18 16:08:48 +053012362 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012363 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12364 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012365 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
12366 {
12367 hddLog(VOS_TRACE_LEVEL_INFO,
12368 FL("status = %d, already disconnected"),
12369 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012370
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012371 }
12372 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012373 {
12374 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012375 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012376 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012377 result = -EINVAL;
12378 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012379 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012380 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012381 &pAdapter->disconnect_comp_var,
12382 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012383 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012384 {
12385 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012386 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012387 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012388 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012389 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012390 {
12391 hddLog(VOS_TRACE_LEVEL_ERROR,
12392 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012393 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012394 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012395disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012396 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12397 FL("Set HDD connState to eConnectionState_NotConnected"));
12398 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
12399
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012400 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012401 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012402}
12403
12404
12405/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012406 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070012407 * This function is used to issue a disconnect request to SME
12408 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012409static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012410 struct net_device *dev,
12411 u16 reason
12412 )
12413{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012414 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012415 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012416 tCsrRoamProfile *pRoamProfile;
12417 hdd_station_ctx_t *pHddStaCtx;
12418 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012419#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012420 tANI_U8 staIdx;
12421#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012422
Jeff Johnson295189b2012-06-20 16:38:30 -070012423 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012424
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012425 if (!pAdapter) {
12426 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
12427 return -EINVAL;
12428 }
12429
12430 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12431 if (!pHddStaCtx) {
12432 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
12433 return -EINVAL;
12434 }
12435
12436 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12437 status = wlan_hdd_validate_context(pHddCtx);
12438 if (0 != status)
12439 {
12440 return status;
12441 }
12442
12443 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
12444
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012445 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12446 TRACE_CODE_HDD_CFG80211_DISCONNECT,
12447 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012448 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
12449 __func__, hdd_device_modetoString(pAdapter->device_mode),
12450 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012451
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012452 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
12453 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070012454
Jeff Johnson295189b2012-06-20 16:38:30 -070012455 if (NULL != pRoamProfile)
12456 {
12457 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012458 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
12459 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070012460 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012461 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070012462 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012463 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012464 switch(reason)
12465 {
12466 case WLAN_REASON_MIC_FAILURE:
12467 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
12468 break;
12469
12470 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
12471 case WLAN_REASON_DISASSOC_AP_BUSY:
12472 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
12473 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
12474 break;
12475
12476 case WLAN_REASON_PREV_AUTH_NOT_VALID:
12477 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053012478 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070012479 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
12480 break;
12481
Jeff Johnson295189b2012-06-20 16:38:30 -070012482 default:
12483 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
12484 break;
12485 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012486 pScanInfo = &pHddCtx->scan_info;
12487 if (pScanInfo->mScanPending)
12488 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012489 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012490 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012491 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012492 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012493 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053012494 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012495#ifdef FEATURE_WLAN_TDLS
12496 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012497 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012498 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012499 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
12500 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012501 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012502 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012503 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012504 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012505 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012506 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012507 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012508 status = sme_DeleteTdlsPeerSta(
12509 WLAN_HDD_GET_HAL_CTX(pAdapter),
12510 pAdapter->sessionId,
12511 mac);
12512 if (status != eHAL_STATUS_SUCCESS) {
12513 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
12514 return -EPERM;
12515 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012516 }
12517 }
12518#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012519 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012520 status = wlan_hdd_disconnect(pAdapter, reasonCode);
12521 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070012522 {
12523 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012524 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012525 __func__, (int)status );
12526 return -EINVAL;
12527 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012528 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012529 else
12530 {
12531 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
12532 "called while in %d state", __func__,
12533 pHddStaCtx->conn_info.connState);
12534 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012535 }
12536 else
12537 {
12538 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
12539 }
12540
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012541 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012542 return status;
12543}
12544
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012545static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
12546 struct net_device *dev,
12547 u16 reason
12548 )
12549{
12550 int ret;
12551 vos_ssr_protect(__func__);
12552 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
12553 vos_ssr_unprotect(__func__);
12554
12555 return ret;
12556}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012557
Jeff Johnson295189b2012-06-20 16:38:30 -070012558/*
12559 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012560 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012561 * settings in IBSS mode.
12562 */
12563static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012564 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012565 struct cfg80211_ibss_params *params
12566 )
12567{
12568 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012569 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012570 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12571 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012572
Jeff Johnson295189b2012-06-20 16:38:30 -070012573 ENTER();
12574
12575 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070012576 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070012577
12578 if (params->ie_len && ( NULL != params->ie) )
12579 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012580 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12581 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012582 {
12583 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12584 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12585 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012586 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012587 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012588 tDot11fIEWPA dot11WPAIE;
12589 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012590 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012591
Wilson Yang00256342013-10-10 23:13:38 -070012592 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012593 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12594 params->ie_len, DOT11F_EID_WPA);
12595 if ( NULL != ie )
12596 {
12597 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12598 // Unpack the WPA IE
12599 //Skip past the EID byte and length byte - and four byte WiFi OUI
12600 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
12601 &ie[2+4],
12602 ie[1] - 4,
12603 &dot11WPAIE);
12604 /*Extract the multicast cipher, the encType for unicast
12605 cipher for wpa-none is none*/
12606 encryptionType =
12607 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
12608 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012609 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012610
Jeff Johnson295189b2012-06-20 16:38:30 -070012611 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
12612
12613 if (0 > status)
12614 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012615 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012616 __func__);
12617 return status;
12618 }
12619 }
12620
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012621 pWextState->roamProfile.AuthType.authType[0] =
12622 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012623 eCSR_AUTH_TYPE_OPEN_SYSTEM;
12624
12625 if (params->privacy)
12626 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012627 /* Security enabled IBSS, At this time there is no information available
12628 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070012629 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012630 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070012631 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012632 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070012633 *enable privacy bit in beacons */
12634
12635 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12636 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012637 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
12638 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070012639 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12640 pWextState->roamProfile.EncryptionType.numEntries = 1;
12641 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070012642 return status;
12643}
12644
12645/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012646 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012647 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012648 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012649static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012650 struct net_device *dev,
12651 struct cfg80211_ibss_params *params
12652 )
12653{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012654 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012655 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12656 tCsrRoamProfile *pRoamProfile;
12657 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012658 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12659 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012660 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070012661
12662 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012663
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012664 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12665 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
12666 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012667 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012668 "%s: device_mode = %s (%d)", __func__,
12669 hdd_device_modetoString(pAdapter->device_mode),
12670 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012671
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012672 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012673 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012674 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012675 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012676 }
12677
12678 if (NULL == pWextState)
12679 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012680 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012681 __func__);
12682 return -EIO;
12683 }
12684
Agarwal Ashish51325b52014-06-16 16:50:49 +053012685 if (vos_max_concurrent_connections_reached()) {
12686 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12687 return -ECONNREFUSED;
12688 }
12689
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012690 /*Try disconnecting if already in connected state*/
12691 status = wlan_hdd_try_disconnect(pAdapter);
12692 if ( 0 > status)
12693 {
12694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12695 " IBSS connection"));
12696 return -EALREADY;
12697 }
12698
Jeff Johnson295189b2012-06-20 16:38:30 -070012699 pRoamProfile = &pWextState->roamProfile;
12700
12701 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
12702 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012703 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012704 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012705 return -EINVAL;
12706 }
12707
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012708 /* BSSID is provided by upper layers hence no need to AUTO generate */
12709 if (NULL != params->bssid) {
12710 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12711 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
12712 hddLog (VOS_TRACE_LEVEL_ERROR,
12713 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12714 return -EIO;
12715 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012716 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012717 }
krunal sonie9002db2013-11-25 14:24:17 -080012718 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
12719 {
12720 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12721 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
12722 {
12723 hddLog (VOS_TRACE_LEVEL_ERROR,
12724 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12725 return -EIO;
12726 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012727
12728 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080012729 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012730 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080012731 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012732
Jeff Johnson295189b2012-06-20 16:38:30 -070012733 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070012734 if (NULL !=
12735#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12736 params->chandef.chan)
12737#else
12738 params->channel)
12739#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012740 {
12741 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012742 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12743 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
12744 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12745 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012746
12747 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012748 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070012749 ieee80211_frequency_to_channel(
12750#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12751 params->chandef.chan->center_freq);
12752#else
12753 params->channel->center_freq);
12754#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012755
12756 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12757 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070012758 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012759 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
12760 __func__);
12761 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012762 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012763
12764 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012765 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012766 if (channelNum == validChan[indx])
12767 {
12768 break;
12769 }
12770 }
12771 if (indx >= numChans)
12772 {
12773 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012774 __func__, channelNum);
12775 return -EINVAL;
12776 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012777 /* Set the Operational Channel */
12778 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
12779 channelNum);
12780 pRoamProfile->ChannelInfo.numOfChannels = 1;
12781 pHddStaCtx->conn_info.operationChannel = channelNum;
12782 pRoamProfile->ChannelInfo.ChannelList =
12783 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070012784 }
12785
12786 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012787 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070012788 if (status < 0)
12789 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070012791 __func__);
12792 return status;
12793 }
12794
12795 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012796 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012797 params->ssid_len, params->bssid,
12798 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012799
12800 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012801 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012802
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012803 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012804 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012805}
12806
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012807static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
12808 struct net_device *dev,
12809 struct cfg80211_ibss_params *params
12810 )
12811{
12812 int ret = 0;
12813
12814 vos_ssr_protect(__func__);
12815 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
12816 vos_ssr_unprotect(__func__);
12817
12818 return ret;
12819}
12820
Jeff Johnson295189b2012-06-20 16:38:30 -070012821/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012822 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012823 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012824 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012825static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012826 struct net_device *dev
12827 )
12828{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012829 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012830 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12831 tCsrRoamProfile *pRoamProfile;
12832 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012833 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012834
12835 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012836
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012837 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12838 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
12839 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012840 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012841 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012842 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012843 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012844 }
12845
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012846 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
12847 hdd_device_modetoString(pAdapter->device_mode),
12848 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012849 if (NULL == pWextState)
12850 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012851 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012852 __func__);
12853 return -EIO;
12854 }
12855
12856 pRoamProfile = &pWextState->roamProfile;
12857
12858 /* Issue disconnect only if interface type is set to IBSS */
12859 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
12860 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012861 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070012862 __func__);
12863 return -EINVAL;
12864 }
12865
12866 /* Issue Disconnect request */
12867 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12868 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12869 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
12870
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012871 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012872 return 0;
12873}
12874
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012875static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
12876 struct net_device *dev
12877 )
12878{
12879 int ret = 0;
12880
12881 vos_ssr_protect(__func__);
12882 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
12883 vos_ssr_unprotect(__func__);
12884
12885 return ret;
12886}
12887
Jeff Johnson295189b2012-06-20 16:38:30 -070012888/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012889 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070012890 * This function is used to set the phy parameters
12891 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
12892 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012893static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012894 u32 changed)
12895{
12896 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
12897 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012898 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012899
12900 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012901
12902 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012903 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
12904 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012905
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012906 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012907 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012908 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012909 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012910 }
12911
Jeff Johnson295189b2012-06-20 16:38:30 -070012912 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
12913 {
12914 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
12915 WNI_CFG_RTS_THRESHOLD_STAMAX :
12916 wiphy->rts_threshold;
12917
12918 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012919 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070012920 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012921 hddLog(VOS_TRACE_LEVEL_ERROR,
12922 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012923 __func__, rts_threshold);
12924 return -EINVAL;
12925 }
12926
12927 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
12928 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012929 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012930 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012931 hddLog(VOS_TRACE_LEVEL_ERROR,
12932 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012933 __func__, rts_threshold);
12934 return -EIO;
12935 }
12936
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012937 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012938 rts_threshold);
12939 }
12940
12941 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
12942 {
12943 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
12944 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
12945 wiphy->frag_threshold;
12946
12947 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012948 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012949 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012950 hddLog(VOS_TRACE_LEVEL_ERROR,
12951 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012952 frag_threshold);
12953 return -EINVAL;
12954 }
12955
12956 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
12957 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012958 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012959 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012960 hddLog(VOS_TRACE_LEVEL_ERROR,
12961 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012962 __func__, frag_threshold);
12963 return -EIO;
12964 }
12965
12966 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
12967 frag_threshold);
12968 }
12969
12970 if ((changed & WIPHY_PARAM_RETRY_SHORT)
12971 || (changed & WIPHY_PARAM_RETRY_LONG))
12972 {
12973 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
12974 wiphy->retry_short :
12975 wiphy->retry_long;
12976
12977 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
12978 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
12979 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012980 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012981 __func__, retry_value);
12982 return -EINVAL;
12983 }
12984
12985 if (changed & WIPHY_PARAM_RETRY_SHORT)
12986 {
12987 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
12988 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012989 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012990 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012991 hddLog(VOS_TRACE_LEVEL_ERROR,
12992 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012993 __func__, retry_value);
12994 return -EIO;
12995 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012996 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012997 __func__, retry_value);
12998 }
12999 else if (changed & WIPHY_PARAM_RETRY_SHORT)
13000 {
13001 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
13002 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013003 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013004 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013005 hddLog(VOS_TRACE_LEVEL_ERROR,
13006 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013007 __func__, retry_value);
13008 return -EIO;
13009 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013010 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013011 __func__, retry_value);
13012 }
13013 }
13014
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013015 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013016 return 0;
13017}
13018
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013019static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
13020 u32 changed)
13021{
13022 int ret;
13023
13024 vos_ssr_protect(__func__);
13025 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
13026 vos_ssr_unprotect(__func__);
13027
13028 return ret;
13029}
13030
Jeff Johnson295189b2012-06-20 16:38:30 -070013031/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013032 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013033 * This function is used to set the txpower
13034 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013035static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013036#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13037 struct wireless_dev *wdev,
13038#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013039#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013040 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013041#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013042 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013043#endif
13044 int dbm)
13045{
13046 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013047 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013048 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13049 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013050 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013051
13052 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013053
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013054 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13055 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
13056 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013057 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013058 if (0 != status)
13059 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013060 return status;
13061 }
13062
13063 hHal = pHddCtx->hHal;
13064
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013065 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
13066 dbm, ccmCfgSetCallback,
13067 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013068 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013069 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013070 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
13071 return -EIO;
13072 }
13073
13074 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
13075 dbm);
13076
13077 switch(type)
13078 {
13079 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
13080 /* Fall through */
13081 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
13082 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
13083 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013084 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
13085 __func__);
13086 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013087 }
13088 break;
13089 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013090 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070013091 __func__);
13092 return -EOPNOTSUPP;
13093 break;
13094 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013095 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
13096 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070013097 return -EIO;
13098 }
13099
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013100 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013101 return 0;
13102}
13103
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013104static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
13105#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13106 struct wireless_dev *wdev,
13107#endif
13108#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13109 enum tx_power_setting type,
13110#else
13111 enum nl80211_tx_power_setting type,
13112#endif
13113 int dbm)
13114{
13115 int ret;
13116 vos_ssr_protect(__func__);
13117 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
13118#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13119 wdev,
13120#endif
13121#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13122 type,
13123#else
13124 type,
13125#endif
13126 dbm);
13127 vos_ssr_unprotect(__func__);
13128
13129 return ret;
13130}
13131
Jeff Johnson295189b2012-06-20 16:38:30 -070013132/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013133 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013134 * This function is used to read the txpower
13135 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013136static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013137#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13138 struct wireless_dev *wdev,
13139#endif
13140 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070013141{
13142
13143 hdd_adapter_t *pAdapter;
13144 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013145 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013146
Jeff Johnsone7245742012-09-05 17:12:55 -070013147 ENTER();
13148
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013149 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013150 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013151 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013152 *dbm = 0;
13153 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013154 }
13155
Jeff Johnson295189b2012-06-20 16:38:30 -070013156 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
13157 if (NULL == pAdapter)
13158 {
13159 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
13160 return -ENOENT;
13161 }
13162
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053013163 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13164 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
13165 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013166 wlan_hdd_get_classAstats(pAdapter);
13167 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
13168
Jeff Johnsone7245742012-09-05 17:12:55 -070013169 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013170 return 0;
13171}
13172
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013173static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
13174#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13175 struct wireless_dev *wdev,
13176#endif
13177 int *dbm)
13178{
13179 int ret;
13180
13181 vos_ssr_protect(__func__);
13182 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
13183#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13184 wdev,
13185#endif
13186 dbm);
13187 vos_ssr_unprotect(__func__);
13188
13189 return ret;
13190}
13191
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013192static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013193#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13194 const u8* mac,
13195#else
13196 u8* mac,
13197#endif
13198 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070013199{
13200 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13201 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13202 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053013203 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013204
13205 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
13206 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070013207
13208 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
13209 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
13210 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
13211 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
13212 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
13213 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
13214 tANI_U16 maxRate = 0;
13215 tANI_U16 myRate;
13216 tANI_U16 currentRate = 0;
13217 tANI_U8 maxSpeedMCS = 0;
13218 tANI_U8 maxMCSIdx = 0;
13219 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053013220 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013221 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013222 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013223
Leo Chang6f8870f2013-03-26 18:11:36 -070013224#ifdef WLAN_FEATURE_11AC
13225 tANI_U32 vht_mcs_map;
13226 eDataRate11ACMaxMcs vhtMaxMcs;
13227#endif /* WLAN_FEATURE_11AC */
13228
Jeff Johnsone7245742012-09-05 17:12:55 -070013229 ENTER();
13230
Jeff Johnson295189b2012-06-20 16:38:30 -070013231 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
13232 (0 == ssidlen))
13233 {
13234 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
13235 " Invalid ssidlen, %d", __func__, ssidlen);
13236 /*To keep GUI happy*/
13237 return 0;
13238 }
13239
Mukul Sharma811205f2014-07-09 21:07:30 +053013240 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
13241 {
13242 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13243 "%s: Roaming in progress, so unable to proceed this request", __func__);
13244 return 0;
13245 }
13246
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013247 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013248 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013249 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013250 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013251 }
13252
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053013253 wlan_hdd_get_station_stats(pAdapter);
13254 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013255
Kiet Lam3b17fc82013-09-27 05:24:08 +053013256 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
13257 sinfo->filled |= STATION_INFO_SIGNAL;
13258
c_hpothu09f19542014-05-30 21:53:31 +053013259 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053013260 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
13261 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053013262 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053013263 {
13264 rate_flags = pAdapter->maxRateFlags;
13265 }
c_hpothu44ff4e02014-05-08 00:13:57 +053013266
Jeff Johnson295189b2012-06-20 16:38:30 -070013267 //convert to the UI units of 100kbps
13268 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
13269
13270#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070013271 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 -070013272 sinfo->signal,
13273 pCfg->reportMaxLinkSpeed,
13274 myRate,
13275 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013276 (int) pCfg->linkSpeedRssiMid,
13277 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070013278 (int) rate_flags,
13279 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013280#endif //LINKSPEED_DEBUG_ENABLED
13281
13282 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
13283 {
13284 // we do not want to necessarily report the current speed
13285 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
13286 {
13287 // report the max possible speed
13288 rssidx = 0;
13289 }
13290 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
13291 {
13292 // report the max possible speed with RSSI scaling
13293 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
13294 {
13295 // report the max possible speed
13296 rssidx = 0;
13297 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013298 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070013299 {
13300 // report middle speed
13301 rssidx = 1;
13302 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013303 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
13304 {
13305 // report middle speed
13306 rssidx = 2;
13307 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013308 else
13309 {
13310 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013311 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070013312 }
13313 }
13314 else
13315 {
13316 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
13317 hddLog(VOS_TRACE_LEVEL_ERROR,
13318 "%s: Invalid value for reportMaxLinkSpeed: %u",
13319 __func__, pCfg->reportMaxLinkSpeed);
13320 rssidx = 0;
13321 }
13322
13323 maxRate = 0;
13324
13325 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013326 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
13327 OperationalRates, &ORLeng))
13328 {
13329 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13330 /*To keep GUI happy*/
13331 return 0;
13332 }
13333
Jeff Johnson295189b2012-06-20 16:38:30 -070013334 for (i = 0; i < ORLeng; i++)
13335 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013336 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013337 {
13338 /* Validate Rate Set */
13339 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
13340 {
13341 currentRate = supported_data_rate[j].supported_rate[rssidx];
13342 break;
13343 }
13344 }
13345 /* Update MAX rate */
13346 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13347 }
13348
13349 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013350 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
13351 ExtendedRates, &ERLeng))
13352 {
13353 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13354 /*To keep GUI happy*/
13355 return 0;
13356 }
13357
Jeff Johnson295189b2012-06-20 16:38:30 -070013358 for (i = 0; i < ERLeng; i++)
13359 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013360 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013361 {
13362 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
13363 {
13364 currentRate = supported_data_rate[j].supported_rate[rssidx];
13365 break;
13366 }
13367 }
13368 /* Update MAX rate */
13369 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13370 }
c_hpothu79aab322014-07-14 21:11:01 +053013371
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013372 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053013373 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013374 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053013375 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070013376 {
c_hpothu79aab322014-07-14 21:11:01 +053013377 if (rate_flags & eHAL_TX_RATE_VHT80)
13378 mode = 2;
13379 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
13380 mode = 1;
13381 else
13382 mode = 0;
13383
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013384 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
13385 MCSRates, &MCSLeng))
13386 {
13387 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13388 /*To keep GUI happy*/
13389 return 0;
13390 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013391 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070013392#ifdef WLAN_FEATURE_11AC
13393 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013394 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070013395 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013396 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013397 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070013398 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070013399 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013400 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013401 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013402 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070013403 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013404 maxMCSIdx = 7;
13405 }
13406 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
13407 {
13408 maxMCSIdx = 8;
13409 }
13410 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
13411 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013412 //VHT20 is supporting 0~8
13413 if (rate_flags & eHAL_TX_RATE_VHT20)
13414 maxMCSIdx = 8;
13415 else
13416 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070013417 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013418
c_hpothu79aab322014-07-14 21:11:01 +053013419 if (0 != rssidx)/*check for scaled */
13420 {
13421 //get middle rate MCS index if rssi=1/2
13422 for (i=0; i <= maxMCSIdx; i++)
13423 {
13424 if (sinfo->signal <= rssiMcsTbl[mode][i])
13425 {
13426 maxMCSIdx = i;
13427 break;
13428 }
13429 }
13430 }
13431
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013432 if (rate_flags & eHAL_TX_RATE_VHT80)
13433 {
13434 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
13435 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
13436 }
13437 else if (rate_flags & eHAL_TX_RATE_VHT40)
13438 {
13439 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
13440 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
13441 }
13442 else if (rate_flags & eHAL_TX_RATE_VHT20)
13443 {
13444 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
13445 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
13446 }
13447
Leo Chang6f8870f2013-03-26 18:11:36 -070013448 maxSpeedMCS = 1;
13449 if (currentRate > maxRate)
13450 {
13451 maxRate = currentRate;
13452 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013453
Leo Chang6f8870f2013-03-26 18:11:36 -070013454 }
13455 else
13456#endif /* WLAN_FEATURE_11AC */
13457 {
13458 if (rate_flags & eHAL_TX_RATE_HT40)
13459 {
13460 rateFlag |= 1;
13461 }
13462 if (rate_flags & eHAL_TX_RATE_SGI)
13463 {
13464 rateFlag |= 2;
13465 }
13466
Girish Gowli01abcee2014-07-31 20:18:55 +053013467 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053013468 if (rssidx == 1 || rssidx == 2)
13469 {
13470 //get middle rate MCS index if rssi=1/2
13471 for (i=0; i <= 7; i++)
13472 {
13473 if (sinfo->signal <= rssiMcsTbl[mode][i])
13474 {
13475 temp = i+1;
13476 break;
13477 }
13478 }
13479 }
c_hpothu79aab322014-07-14 21:11:01 +053013480
13481 for (i = 0; i < MCSLeng; i++)
13482 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013483 for (j = 0; j < temp; j++)
13484 {
13485 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
13486 {
13487 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053013488 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013489 break;
13490 }
13491 }
13492 if ((j < temp) && (currentRate > maxRate))
13493 {
13494 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070013495 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013496 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053013497 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013498 }
13499 }
13500
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013501 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
13502 {
13503 maxRate = myRate;
13504 maxSpeedMCS = 1;
13505 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13506 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013507 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053013508 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070013509 {
13510 maxRate = myRate;
13511 if (rate_flags & eHAL_TX_RATE_LEGACY)
13512 {
13513 maxSpeedMCS = 0;
13514 }
13515 else
13516 {
13517 maxSpeedMCS = 1;
13518 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13519 }
13520 }
13521
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013522 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070013523 {
13524 sinfo->txrate.legacy = maxRate;
13525#ifdef LINKSPEED_DEBUG_ENABLED
13526 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
13527#endif //LINKSPEED_DEBUG_ENABLED
13528 }
13529 else
13530 {
13531 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070013532#ifdef WLAN_FEATURE_11AC
13533 sinfo->txrate.nss = 1;
13534 if (rate_flags & eHAL_TX_RATE_VHT80)
13535 {
13536 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013537 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070013538 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013539 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070013540 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013541 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13542 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13543 }
13544 else if (rate_flags & eHAL_TX_RATE_VHT20)
13545 {
13546 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13547 }
13548#endif /* WLAN_FEATURE_11AC */
13549 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
13550 {
13551 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13552 if (rate_flags & eHAL_TX_RATE_HT40)
13553 {
13554 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13555 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013556 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013557 if (rate_flags & eHAL_TX_RATE_SGI)
13558 {
13559 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13560 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013561
Jeff Johnson295189b2012-06-20 16:38:30 -070013562#ifdef LINKSPEED_DEBUG_ENABLED
13563 pr_info("Reporting MCS rate %d flags %x\n",
13564 sinfo->txrate.mcs,
13565 sinfo->txrate.flags );
13566#endif //LINKSPEED_DEBUG_ENABLED
13567 }
13568 }
13569 else
13570 {
13571 // report current rate instead of max rate
13572
13573 if (rate_flags & eHAL_TX_RATE_LEGACY)
13574 {
13575 //provide to the UI in units of 100kbps
13576 sinfo->txrate.legacy = myRate;
13577#ifdef LINKSPEED_DEBUG_ENABLED
13578 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
13579#endif //LINKSPEED_DEBUG_ENABLED
13580 }
13581 else
13582 {
13583 //must be MCS
13584 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013585#ifdef WLAN_FEATURE_11AC
13586 sinfo->txrate.nss = 1;
13587 if (rate_flags & eHAL_TX_RATE_VHT80)
13588 {
13589 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13590 }
13591 else
13592#endif /* WLAN_FEATURE_11AC */
13593 {
13594 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13595 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013596 if (rate_flags & eHAL_TX_RATE_SGI)
13597 {
13598 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13599 }
13600 if (rate_flags & eHAL_TX_RATE_HT40)
13601 {
13602 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13603 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013604#ifdef WLAN_FEATURE_11AC
13605 else if (rate_flags & eHAL_TX_RATE_VHT80)
13606 {
13607 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
13608 }
13609#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070013610#ifdef LINKSPEED_DEBUG_ENABLED
13611 pr_info("Reporting actual MCS rate %d flags %x\n",
13612 sinfo->txrate.mcs,
13613 sinfo->txrate.flags );
13614#endif //LINKSPEED_DEBUG_ENABLED
13615 }
13616 }
13617 sinfo->filled |= STATION_INFO_TX_BITRATE;
13618
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013619 sinfo->tx_packets =
13620 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
13621 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
13622 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
13623 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
13624
13625 sinfo->tx_retries =
13626 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
13627 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
13628 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
13629 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
13630
13631 sinfo->tx_failed =
13632 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
13633 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
13634 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
13635 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
13636
13637 sinfo->filled |=
13638 STATION_INFO_TX_PACKETS |
13639 STATION_INFO_TX_RETRIES |
13640 STATION_INFO_TX_FAILED;
13641
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013642 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13643 TRACE_CODE_HDD_CFG80211_GET_STA,
13644 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013645 EXIT();
13646 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013647}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013648#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13649static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13650 const u8* mac, struct station_info *sinfo)
13651#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013652static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13653 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013654#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013655{
13656 int ret;
13657
13658 vos_ssr_protect(__func__);
13659 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
13660 vos_ssr_unprotect(__func__);
13661
13662 return ret;
13663}
13664
13665static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070013666 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070013667{
13668 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013669 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013670 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013671 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013672
Jeff Johnsone7245742012-09-05 17:12:55 -070013673 ENTER();
13674
Jeff Johnson295189b2012-06-20 16:38:30 -070013675 if (NULL == pAdapter)
13676 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013677 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013678 return -ENODEV;
13679 }
13680
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013681 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13682 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
13683 pAdapter->sessionId, timeout));
13684
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013685 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013686 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013687 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013688 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013689 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013690 }
13691
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013692 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
13693 (TRUE == pHddCtx->hdd_wlan_suspended) &&
13694 (pHddCtx->cfg_ini->fhostArpOffload) &&
13695 (eConnectionState_Associated ==
13696 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13697 {
Amar Singhald53568e2013-09-26 11:03:45 -070013698
13699 hddLog(VOS_TRACE_LEVEL_INFO,
13700 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053013701 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013702 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13703 {
13704 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013705 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013706 __func__, vos_status);
13707 }
13708 }
13709
Jeff Johnson295189b2012-06-20 16:38:30 -070013710 /**The get power cmd from the supplicant gets updated by the nl only
13711 *on successful execution of the function call
13712 *we are oppositely mapped w.r.t mode in the driver
13713 **/
13714 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
13715
13716 if (VOS_STATUS_E_FAILURE == vos_status)
13717 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13719 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013720 return -EINVAL;
13721 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013722 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013723 return 0;
13724}
13725
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013726static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
13727 struct net_device *dev, bool mode, int timeout)
13728{
13729 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013730
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013731 vos_ssr_protect(__func__);
13732 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
13733 vos_ssr_unprotect(__func__);
13734
13735 return ret;
13736}
Jeff Johnson295189b2012-06-20 16:38:30 -070013737#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013738static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
13739 struct net_device *netdev,
13740 u8 key_index)
13741{
13742 ENTER();
13743 return 0;
13744}
13745
Jeff Johnson295189b2012-06-20 16:38:30 -070013746static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013747 struct net_device *netdev,
13748 u8 key_index)
13749{
13750 int ret;
13751 vos_ssr_protect(__func__);
13752 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
13753 vos_ssr_unprotect(__func__);
13754 return ret;
13755}
13756#endif //LINUX_VERSION_CODE
13757
13758#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13759static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13760 struct net_device *dev,
13761 struct ieee80211_txq_params *params)
13762{
13763 ENTER();
13764 return 0;
13765}
13766#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13767static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13768 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013769{
Jeff Johnsone7245742012-09-05 17:12:55 -070013770 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013771 return 0;
13772}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013773#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070013774
13775#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13776static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013777 struct net_device *dev,
13778 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013779{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013780 int ret;
13781
13782 vos_ssr_protect(__func__);
13783 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
13784 vos_ssr_unprotect(__func__);
13785 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013786}
13787#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13788static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
13789 struct ieee80211_txq_params *params)
13790{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013791 int ret;
13792
13793 vos_ssr_protect(__func__);
13794 ret = __wlan_hdd_set_txq_params(wiphy, params);
13795 vos_ssr_unprotect(__func__);
13796 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013797}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013798#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013799
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013800static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013801 struct net_device *dev,
13802 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070013803{
13804 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013805 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013806 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013807 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013808 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013809 v_CONTEXT_t pVosContext = NULL;
13810 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013811
Jeff Johnsone7245742012-09-05 17:12:55 -070013812 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013813
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013814 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070013815 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013816 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013817 return -EINVAL;
13818 }
13819
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013820 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13821 TRACE_CODE_HDD_CFG80211_DEL_STA,
13822 pAdapter->sessionId, pAdapter->device_mode));
13823
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013824 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13825 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013826 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013827 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013828 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013829 }
13830
Jeff Johnson295189b2012-06-20 16:38:30 -070013831 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013832 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013833 )
13834 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013835 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13836 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13837 if(pSapCtx == NULL){
13838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13839 FL("psapCtx is NULL"));
13840 return -ENOENT;
13841 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013842 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013843 {
13844 v_U16_t i;
13845 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13846 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013847 if ((pSapCtx->aStaInfo[i].isUsed) &&
13848 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070013849 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013850 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013851 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013852 ETHER_ADDR_LEN);
13853
Jeff Johnson295189b2012-06-20 16:38:30 -070013854 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013855 "%s: Delete STA with MAC::"
13856 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013857 __func__,
13858 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
13859 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013860 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013861 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013862 }
13863 }
13864 }
13865 else
13866 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013867
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013868 vos_status = hdd_softap_GetStaId(pAdapter,
13869 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013870 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13871 {
13872 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013873 "%s: Skip this DEL STA as this is not used::"
13874 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013875 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013876 return -ENOENT;
13877 }
13878
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013879 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013880 {
13881 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013882 "%s: Skip this DEL STA as deauth is in progress::"
13883 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013884 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013885 return -ENOENT;
13886 }
13887
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013888 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013889
Jeff Johnson295189b2012-06-20 16:38:30 -070013890 hddLog(VOS_TRACE_LEVEL_INFO,
13891 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013892 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013893 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013894 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013895
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013896 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013897 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13898 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013899 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013900 hddLog(VOS_TRACE_LEVEL_INFO,
13901 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013902 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013903 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013904 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013905 return -ENOENT;
13906 }
13907
Jeff Johnson295189b2012-06-20 16:38:30 -070013908 }
13909 }
13910
13911 EXIT();
13912
13913 return 0;
13914}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013915
13916#ifdef CFG80211_DEL_STA_V2
13917static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13918 struct net_device *dev,
13919 struct station_del_parameters *param)
13920#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013921#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13922static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13923 struct net_device *dev, const u8 *mac)
13924#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013925static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13926 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013927#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013928#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013929{
13930 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013931 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070013932
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013933 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013934
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013935#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013936 if (NULL == param) {
13937 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013938 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013939 return -EINVAL;
13940 }
13941
13942 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
13943 param->subtype, &delStaParams);
13944
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013945#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053013946 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013947 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013948#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013949 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
13950
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013951 vos_ssr_unprotect(__func__);
13952
13953 return ret;
13954}
13955
13956static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013957 struct net_device *dev,
13958#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13959 const u8 *mac,
13960#else
13961 u8 *mac,
13962#endif
13963 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013964{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013965 hdd_adapter_t *pAdapter;
13966 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013967 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013968#ifdef FEATURE_WLAN_TDLS
13969 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013970
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013971 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013972
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013973 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13974 if (NULL == pAdapter)
13975 {
13976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13977 "%s: Adapter is NULL",__func__);
13978 return -EINVAL;
13979 }
13980 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13981 status = wlan_hdd_validate_context(pHddCtx);
13982 if (0 != status)
13983 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013984 return status;
13985 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013986
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013987 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13988 TRACE_CODE_HDD_CFG80211_ADD_STA,
13989 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013990 mask = params->sta_flags_mask;
13991
13992 set = params->sta_flags_set;
13993
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053013994 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013995 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
13996 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013997
13998 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13999 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014000 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014001 }
14002 }
14003#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014004 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014005 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014006}
14007
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014008#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14009static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14010 struct net_device *dev, const u8 *mac,
14011 struct station_parameters *params)
14012#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014013static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14014 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014015#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014016{
14017 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014018
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014019 vos_ssr_protect(__func__);
14020 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
14021 vos_ssr_unprotect(__func__);
14022
14023 return ret;
14024}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014025#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070014026
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014027static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070014028 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014029{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014030 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14031 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014032 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014033 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014034 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014035 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070014036
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014037 ENTER();
14038
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014039 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014040 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014041 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014042 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014043 return -EINVAL;
14044 }
14045
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014046 if (!pmksa) {
14047 hddLog(LOGE, FL("pmksa is NULL"));
14048 return -EINVAL;
14049 }
14050
14051 if (!pmksa->bssid || !pmksa->pmkid) {
14052 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
14053 pmksa->bssid, pmksa->pmkid);
14054 return -EINVAL;
14055 }
14056
14057 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
14058 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14059
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014060 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14061 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014062 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014063 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014064 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014065 }
14066
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014067 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014068 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14069
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014070 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
14071 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014072
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014073 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014074 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014075 &pmk_id, 1, FALSE);
14076
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014077 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14078 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
14079 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014080
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014081 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014082 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014083}
14084
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014085static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
14086 struct cfg80211_pmksa *pmksa)
14087{
14088 int ret;
14089
14090 vos_ssr_protect(__func__);
14091 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
14092 vos_ssr_unprotect(__func__);
14093
14094 return ret;
14095}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014096
Wilson Yang6507c4e2013-10-01 20:11:19 -070014097
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014098static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070014099 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014100{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014101 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14102 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014103 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014104 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014105
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014106 ENTER();
14107
Wilson Yang6507c4e2013-10-01 20:11:19 -070014108 /* Validate pAdapter */
14109 if (NULL == pAdapter)
14110 {
14111 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
14112 return -EINVAL;
14113 }
14114
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014115 if (!pmksa) {
14116 hddLog(LOGE, FL("pmksa is NULL"));
14117 return -EINVAL;
14118 }
14119
14120 if (!pmksa->bssid) {
14121 hddLog(LOGE, FL("pmksa->bssid is NULL"));
14122 return -EINVAL;
14123 }
14124
Kiet Lam98c46a12014-10-31 15:34:57 -070014125 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
14126 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14127
Wilson Yang6507c4e2013-10-01 20:11:19 -070014128 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14129 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014130 if (0 != status)
14131 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014132 return status;
14133 }
14134
14135 /*Retrieve halHandle*/
14136 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14137
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014138 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14139 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
14140 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014141 /* Delete the PMKID CSR cache */
14142 if (eHAL_STATUS_SUCCESS !=
14143 sme_RoamDelPMKIDfromCache(halHandle,
14144 pAdapter->sessionId, pmksa->bssid, FALSE)) {
14145 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
14146 MAC_ADDR_ARRAY(pmksa->bssid));
14147 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014148 }
14149
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014150 EXIT();
14151 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014152}
14153
Wilson Yang6507c4e2013-10-01 20:11:19 -070014154
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014155static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
14156 struct cfg80211_pmksa *pmksa)
14157{
14158 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014159
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014160 vos_ssr_protect(__func__);
14161 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
14162 vos_ssr_unprotect(__func__);
14163
14164 return ret;
14165
14166}
14167
14168static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014169{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014170 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14171 tHalHandle halHandle;
14172 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014173 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014174
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014175 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070014176
14177 /* Validate pAdapter */
14178 if (NULL == pAdapter)
14179 {
14180 hddLog(VOS_TRACE_LEVEL_ERROR,
14181 "%s: Invalid Adapter" ,__func__);
14182 return -EINVAL;
14183 }
14184
14185 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14186 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014187 if (0 != status)
14188 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014189 return status;
14190 }
14191
14192 /*Retrieve halHandle*/
14193 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14194
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014195 /* Flush the PMKID cache in CSR */
14196 if (eHAL_STATUS_SUCCESS !=
14197 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
14198 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
14199 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014200 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014201 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080014202 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014203}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014204
14205static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
14206{
14207 int ret;
14208
14209 vos_ssr_protect(__func__);
14210 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
14211 vos_ssr_unprotect(__func__);
14212
14213 return ret;
14214}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014215#endif
14216
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014217#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014218static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14219 struct net_device *dev,
14220 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014221{
14222 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14223 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014224 hdd_context_t *pHddCtx;
14225 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014226
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014227 ENTER();
14228
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014229 if (NULL == pAdapter)
14230 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014231 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014232 return -ENODEV;
14233 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014234 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14235 ret = wlan_hdd_validate_context(pHddCtx);
14236 if (0 != ret)
14237 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014238 return ret;
14239 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014240 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014241 if (NULL == pHddStaCtx)
14242 {
14243 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
14244 return -EINVAL;
14245 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014246
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014247 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14248 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
14249 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014250 // Added for debug on reception of Re-assoc Req.
14251 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
14252 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014253 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014254 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080014255 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014256 }
14257
14258#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080014259 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014260 ftie->ie_len);
14261#endif
14262
14263 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014264 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
14265 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014266 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014267
14268 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014269 return 0;
14270}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014271
14272static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14273 struct net_device *dev,
14274 struct cfg80211_update_ft_ies_params *ftie)
14275{
14276 int ret;
14277
14278 vos_ssr_protect(__func__);
14279 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
14280 vos_ssr_unprotect(__func__);
14281
14282 return ret;
14283}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014284#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014285
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014286#ifdef FEATURE_WLAN_SCAN_PNO
14287
14288void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
14289 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
14290{
14291 int ret;
14292 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
14293 hdd_context_t *pHddCtx;
14294
Nirav Shah80830bf2013-12-31 16:35:12 +053014295 ENTER();
14296
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014297 if (NULL == pAdapter)
14298 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014300 "%s: HDD adapter is Null", __func__);
14301 return ;
14302 }
14303
14304 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14305 if (NULL == pHddCtx)
14306 {
14307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14308 "%s: HDD context is Null!!!", __func__);
14309 return ;
14310 }
14311
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014312 spin_lock(&pHddCtx->schedScan_lock);
14313 if (TRUE == pHddCtx->isWiphySuspended)
14314 {
14315 pHddCtx->isSchedScanUpdatePending = TRUE;
14316 spin_unlock(&pHddCtx->schedScan_lock);
14317 hddLog(VOS_TRACE_LEVEL_INFO,
14318 "%s: Update cfg80211 scan database after it resume", __func__);
14319 return ;
14320 }
14321 spin_unlock(&pHddCtx->schedScan_lock);
14322
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014323 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
14324
14325 if (0 > ret)
14326 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
14327
14328 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14330 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014331}
14332
14333/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014334 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014335 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014336 */
14337static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
14338{
14339 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14340 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014341 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014342 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14343 int status = 0;
14344 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
14345
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014346 /* The current firmware design does not allow PNO during any
14347 * active sessions. Hence, determine the active sessions
14348 * and return a failure.
14349 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014350 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
14351 {
14352 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014353 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014354
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014355 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
14356 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
14357 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
14358 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
14359 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053014360 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014361 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014362 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014363 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014364 }
14365 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14366 pAdapterNode = pNext;
14367 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014368 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014369}
14370
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014371void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
14372{
14373 hdd_adapter_t *pAdapter = callbackContext;
14374 hdd_context_t *pHddCtx;
14375
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014376 ENTER();
14377
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014378 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
14379 {
14380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14381 FL("Invalid adapter or adapter has invalid magic"));
14382 return;
14383 }
14384
14385 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14386 if (0 != wlan_hdd_validate_context(pHddCtx))
14387 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014388 return;
14389 }
14390
c_hpothub53c45d2014-08-18 16:53:14 +053014391 if (VOS_STATUS_SUCCESS != status)
14392 {
14393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014394 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053014395 pHddCtx->isPnoEnable = FALSE;
14396 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014397
14398 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
14399 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014400 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014401}
14402
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014403/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014404 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
14405 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014406 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014407static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014408 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14409{
14410 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014411 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014412 hdd_context_t *pHddCtx;
14413 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014414 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053014415 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
14416 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014417 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14418 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014419 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014420 hdd_config_t *pConfig = NULL;
14421 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014422
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014423 ENTER();
14424
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014425 if (NULL == pAdapter)
14426 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014427 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014428 "%s: HDD adapter is Null", __func__);
14429 return -ENODEV;
14430 }
14431
14432 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014433 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014434
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014435 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014436 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014437 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014438 }
14439
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014440 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014441 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14442 if (NULL == hHal)
14443 {
14444 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14445 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014446 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014447 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014448 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14449 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
14450 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053014451 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014452 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053014453 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014454 {
14455 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14456 "%s: aborting the existing scan is unsuccessfull", __func__);
14457 return -EBUSY;
14458 }
14459
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014460 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014461 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014462 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014463 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014464 return -EBUSY;
14465 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014466
c_hpothu37f21312014-04-09 21:49:54 +053014467 if (TRUE == pHddCtx->isPnoEnable)
14468 {
14469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14470 FL("already PNO is enabled"));
14471 return -EBUSY;
14472 }
c_hpothu225aa7c2014-10-22 17:45:13 +053014473
14474 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
14475 {
14476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14477 "%s: abort ROC failed ", __func__);
14478 return -EBUSY;
14479 }
14480
c_hpothu37f21312014-04-09 21:49:54 +053014481 pHddCtx->isPnoEnable = TRUE;
14482
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014483 pnoRequest.enable = 1; /*Enable PNO */
14484 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014485
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014486 if (( !pnoRequest.ucNetworksCount ) ||
14487 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014488 {
14489 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014490 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014491 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014492 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014493 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014494 goto error;
14495 }
14496
14497 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
14498 {
14499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014500 "%s: Incorrect number of channels %d",
14501 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014502 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014503 goto error;
14504 }
14505
14506 /* Framework provides one set of channels(all)
14507 * common for all saved profile */
14508 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14509 channels_allowed, &num_channels_allowed))
14510 {
14511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14512 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014513 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014514 goto error;
14515 }
14516 /* Checking each channel against allowed channel list */
14517 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053014518 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014519 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014520 char chList [(request->n_channels*5)+1];
14521 int len;
14522 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014523 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014524 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014525 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014526 if (request->channels[i]->hw_value == channels_allowed[indx])
14527 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014528 if ((!pConfig->enableDFSPnoChnlScan) &&
14529 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
14530 {
14531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14532 "%s : Dropping DFS channel : %d",
14533 __func__,channels_allowed[indx]);
14534 num_ignore_dfs_ch++;
14535 break;
14536 }
14537
Nirav Shah80830bf2013-12-31 16:35:12 +053014538 valid_ch[num_ch++] = request->channels[i]->hw_value;
14539 len += snprintf(chList+len, 5, "%d ",
14540 request->channels[i]->hw_value);
14541 break ;
14542 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014543 }
14544 }
Nirav Shah80830bf2013-12-31 16:35:12 +053014545 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014546
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014547 /*If all channels are DFS and dropped, then ignore the PNO request*/
14548 if (num_ignore_dfs_ch == request->n_channels)
14549 {
14550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14551 "%s : All requested channels are DFS channels", __func__);
14552 ret = -EINVAL;
14553 goto error;
14554 }
14555 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014556
14557 pnoRequest.aNetworks =
14558 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14559 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014560 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014561 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14562 FL("failed to allocate memory aNetworks %u"),
14563 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14564 goto error;
14565 }
14566 vos_mem_zero(pnoRequest.aNetworks,
14567 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14568
14569 /* Filling per profile params */
14570 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
14571 {
14572 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014573 request->match_sets[i].ssid.ssid_len;
14574
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014575 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
14576 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014577 {
14578 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014579 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014580 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014581 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014582 goto error;
14583 }
14584
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014585 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014586 request->match_sets[i].ssid.ssid,
14587 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14589 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014590 i, pnoRequest.aNetworks[i].ssId.ssId);
14591 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
14592 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
14593 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014594
14595 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014596 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
14597 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014598
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014599 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014600 }
14601
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014602 for (i = 0; i < request->n_ssids; i++)
14603 {
14604 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014605 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014606 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014607 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014608 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014609 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014610 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014611 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014612 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014613 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014614 break;
14615 }
14616 j++;
14617 }
14618 }
14619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14620 "Number of hidden networks being Configured = %d",
14621 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080014623 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014624
14625 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14626 if (pnoRequest.p24GProbeTemplate == NULL)
14627 {
14628 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14629 FL("failed to allocate memory p24GProbeTemplate %u"),
14630 SIR_PNO_MAX_PB_REQ_SIZE);
14631 goto error;
14632 }
14633
14634 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14635 if (pnoRequest.p5GProbeTemplate == NULL)
14636 {
14637 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14638 FL("failed to allocate memory p5GProbeTemplate %u"),
14639 SIR_PNO_MAX_PB_REQ_SIZE);
14640 goto error;
14641 }
14642
14643 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14644 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14645
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053014646 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
14647 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014648 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014649 pnoRequest.us24GProbeTemplateLen = request->ie_len;
14650 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
14651 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014652
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014653 pnoRequest.us5GProbeTemplateLen = request->ie_len;
14654 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
14655 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014656 }
14657
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014658 /* Driver gets only one time interval which is hardcoded in
14659 * supplicant for 10000ms. Taking power consumption into account 6 timers
14660 * will be used, Timervalue is increased exponentially i.e 10,20,40,
14661 * 80,160,320 secs. And number of scan cycle for each timer
14662 * is configurable through INI param gPNOScanTimerRepeatValue.
14663 * If it is set to 0 only one timer will be used and PNO scan cycle
14664 * will be repeated after each interval specified by supplicant
14665 * till PNO is disabled.
14666 */
14667 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014668 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014669 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014670 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014671 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
14672
14673 tempInterval = (request->interval)/1000;
14674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14675 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
14676 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014677 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014678 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014679 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014680 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014681 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014682 tempInterval *= 2;
14683 }
14684 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014685 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014686
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014687 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014688
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014689 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014690 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
14691 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014692 pAdapter->pno_req_status = 0;
14693
Nirav Shah80830bf2013-12-31 16:35:12 +053014694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14695 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014696 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
14697 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053014698
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014699 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014700 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014701 hdd_cfg80211_sched_scan_done_callback, pAdapter);
14702 if (eHAL_STATUS_SUCCESS != status)
14703 {
14704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014705 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014706 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014707 goto error;
14708 }
14709
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014710 ret = wait_for_completion_timeout(
14711 &pAdapter->pno_comp_var,
14712 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
14713 if (0 >= ret)
14714 {
14715 // Did not receive the response for PNO enable in time.
14716 // Assuming the PNO enable was success.
14717 // Returning error from here, because we timeout, results
14718 // in side effect of Wifi (Wifi Setting) not to work.
14719 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14720 FL("Timed out waiting for PNO to be Enabled"));
14721 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014722 }
14723
14724 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053014725 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014726
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014727error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014728 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14729 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053014730 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014731 if (pnoRequest.aNetworks)
14732 vos_mem_free(pnoRequest.aNetworks);
14733 if (pnoRequest.p24GProbeTemplate)
14734 vos_mem_free(pnoRequest.p24GProbeTemplate);
14735 if (pnoRequest.p5GProbeTemplate)
14736 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014737
14738 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014739 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014740}
14741
14742/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014743 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
14744 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014745 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014746static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
14747 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14748{
14749 int ret;
14750
14751 vos_ssr_protect(__func__);
14752 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
14753 vos_ssr_unprotect(__func__);
14754
14755 return ret;
14756}
14757
14758/*
14759 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
14760 * Function to disable PNO
14761 */
14762static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014763 struct net_device *dev)
14764{
14765 eHalStatus status = eHAL_STATUS_FAILURE;
14766 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14767 hdd_context_t *pHddCtx;
14768 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014769 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014770 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014771
14772 ENTER();
14773
14774 if (NULL == pAdapter)
14775 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014777 "%s: HDD adapter is Null", __func__);
14778 return -ENODEV;
14779 }
14780
14781 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014782
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014783 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014784 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014785 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014786 "%s: HDD context is Null", __func__);
14787 return -ENODEV;
14788 }
14789
14790 /* The return 0 is intentional when isLogpInProgress and
14791 * isLoadUnloadInProgress. We did observe a crash due to a return of
14792 * failure in sched_scan_stop , especially for a case where the unload
14793 * of the happens at the same time. The function __cfg80211_stop_sched_scan
14794 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
14795 * success. If it returns a failure , then its next invocation due to the
14796 * clean up of the second interface will have the dev pointer corresponding
14797 * to the first one leading to a crash.
14798 */
14799 if (pHddCtx->isLogpInProgress)
14800 {
14801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14802 "%s: LOGP in Progress. Ignore!!!", __func__);
14803 return ret;
14804 }
14805
Mihir Shete18156292014-03-11 15:38:30 +053014806 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014807 {
14808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14809 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14810 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014811 }
14812
14813 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14814 if (NULL == hHal)
14815 {
14816 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14817 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014818 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014819 }
14820
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014821 pnoRequest.enable = 0; /* Disable PNO */
14822 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014823
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014824 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14825 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
14826 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014827 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014828 pAdapter->sessionId,
14829 NULL, pAdapter);
14830 if (eHAL_STATUS_SUCCESS != status)
14831 {
14832 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14833 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014834 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014835 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014836 }
c_hpothu37f21312014-04-09 21:49:54 +053014837 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014838
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014839error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014841 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014842
14843 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014844 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014845}
14846
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014847/*
14848 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
14849 * NL interface to disable PNO
14850 */
14851static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
14852 struct net_device *dev)
14853{
14854 int ret;
14855
14856 vos_ssr_protect(__func__);
14857 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
14858 vos_ssr_unprotect(__func__);
14859
14860 return ret;
14861}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014862#endif /*FEATURE_WLAN_SCAN_PNO*/
14863
14864
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014865#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014866#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014867static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14868 struct net_device *dev,
14869 u8 *peer, u8 action_code,
14870 u8 dialog_token,
14871 u16 status_code, u32 peer_capability,
14872 const u8 *buf, size_t len)
14873#else /* TDLS_MGMT_VERSION2 */
14874#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
14875static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14876 struct net_device *dev,
14877 const u8 *peer, u8 action_code,
14878 u8 dialog_token, u16 status_code,
14879 u32 peer_capability, bool initiator,
14880 const u8 *buf, size_t len)
14881#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
14882static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14883 struct net_device *dev,
14884 const u8 *peer, u8 action_code,
14885 u8 dialog_token, u16 status_code,
14886 u32 peer_capability, const u8 *buf,
14887 size_t len)
14888#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
14889static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14890 struct net_device *dev,
14891 u8 *peer, u8 action_code,
14892 u8 dialog_token,
14893 u16 status_code, u32 peer_capability,
14894 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014895#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014896static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14897 struct net_device *dev,
14898 u8 *peer, u8 action_code,
14899 u8 dialog_token,
14900 u16 status_code, const u8 *buf,
14901 size_t len)
14902#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014903#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014904{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014905 hdd_adapter_t *pAdapter;
14906 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014907 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070014908 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080014909 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070014910 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014911 int ret;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053014912#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014913 u32 peer_capability = 0;
14914#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014915 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053014916 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014917
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014918 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14919 if (NULL == pAdapter)
14920 {
14921 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14922 "%s: Adapter is NULL",__func__);
14923 return -EINVAL;
14924 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014925 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14926 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
14927 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053014928
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014929 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014930 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014931 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014932 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014933 "Invalid arguments");
14934 return -EINVAL;
14935 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053014936
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014937 if (pHddCtx->isLogpInProgress)
14938 {
14939 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14940 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053014941 wlan_hdd_tdls_set_link_status(pAdapter,
14942 peer,
14943 eTDLS_LINK_IDLE,
14944 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014945 return -EBUSY;
14946 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053014947
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014948 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
14949 {
14950 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14951 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14952 return -EAGAIN;
14953 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053014954
Hoonki Lee27511902013-03-14 18:19:06 -070014955 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014956 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070014958 "%s: TDLS mode is disabled OR not enabled in FW."
14959 MAC_ADDRESS_STR " action %d declined.",
14960 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014961 return -ENOTSUPP;
14962 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014963
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053014964 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14965
14966 if( NULL == pHddStaCtx )
14967 {
14968 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14969 "%s: HDD station context NULL ",__func__);
14970 return -EINVAL;
14971 }
14972
14973 /* STA should be connected and authenticated
14974 * before sending any TDLS frames
14975 */
14976 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
14977 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
14978 {
14979 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14980 "STA is not connected or unauthenticated. "
14981 "connState %u, uIsAuthenticated %u",
14982 pHddStaCtx->conn_info.connState,
14983 pHddStaCtx->conn_info.uIsAuthenticated);
14984 return -EAGAIN;
14985 }
14986
Hoonki Lee27511902013-03-14 18:19:06 -070014987 /* other than teardown frame, other mgmt frames are not sent if disabled */
14988 if (SIR_MAC_TDLS_TEARDOWN != action_code)
14989 {
14990 /* if tdls_mode is disabled to respond to peer's request */
14991 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
14992 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014993 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070014994 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014995 " TDLS mode is disabled. action %d declined.",
14996 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070014997
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053014998 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070014999 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053015000
15001 if (vos_max_concurrent_connections_reached())
15002 {
15003 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15004 return -EINVAL;
15005 }
Hoonki Lee27511902013-03-14 18:19:06 -070015006 }
15007
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015008 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
15009 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053015010 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015011 {
15012 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015013 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015014 " TDLS setup is ongoing. action %d declined.",
15015 __func__, MAC_ADDR_ARRAY(peer), action_code);
15016 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015017 }
15018 }
15019
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015020 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
15021 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080015022 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015023 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15024 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015025 {
15026 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
15027 we return error code at 'add_station()'. Hence we have this
15028 check again in addtion to add_station().
15029 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015030 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015031 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015032 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15033 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015034 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
15035 __func__, MAC_ADDR_ARRAY(peer), action_code,
15036 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053015037 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080015038 }
15039 else
15040 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015041 /* maximum reached. tweak to send error code to peer and return
15042 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015043 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15045 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015046 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
15047 __func__, MAC_ADDR_ARRAY(peer), status_code,
15048 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070015049 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015050 /* fall through to send setup resp with failure status
15051 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015052 }
15053 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015054 else
15055 {
15056 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053015057 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015058 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015059 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015060 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015061 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
15062 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015063 return -EPERM;
15064 }
15065 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015066 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015067
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015068 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015069 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015070 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
15071 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015072
Hoonki Leea34dd892013-02-05 22:56:02 -080015073 /*Except teardown responder will not be used so just make 0*/
15074 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015075 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080015076 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015077
15078 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015079 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015080
15081 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
15082 responder = pTdlsPeer->is_responder;
15083 else
Hoonki Leea34dd892013-02-05 22:56:02 -080015084 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015086 "%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 -070015087 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
15088 dialog_token, status_code, len);
15089 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080015090 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015091 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015092
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015093 /* For explicit trigger of DIS_REQ come out of BMPS for
15094 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070015095 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015096 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
15097 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070015098 {
15099 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
15100 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015101 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015102 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015103 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
15104 if (status != VOS_STATUS_SUCCESS) {
15105 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
15106 }
Hoonki Lee14621352013-04-16 17:51:19 -070015107 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015108 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015109 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015110 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
15111 }
15112 }
Hoonki Lee14621352013-04-16 17:51:19 -070015113 }
15114
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015115 /* make sure doesn't call send_mgmt() while it is pending */
15116 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
15117 {
15118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015119 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015120 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015121 ret = -EBUSY;
15122 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015123 }
15124
15125 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015126 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
15127
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015128 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
15129 pAdapter->sessionId, peer, action_code, dialog_token,
15130 status_code, peer_capability, (tANI_U8 *)buf, len,
15131 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015132
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015133 if (VOS_STATUS_SUCCESS != status)
15134 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015135 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15136 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015137 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015138 ret = -EINVAL;
15139 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015140 }
15141
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015142 if ((SIR_MAC_TDLS_DIS_REQ == action_code) ||
15143 (SIR_MAC_TDLS_DIS_RSP == action_code))
15144 {
15145 /* for DIS_REQ/DIS_RSP, supplicant don't consider the return status.
15146 * So we no need to wait for tdls_mgmt_comp for sending ack status.
15147 */
15148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15149 "%s: tx done for frm %u", __func__, action_code);
15150 return 0;
15151 }
15152
15153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15154 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
15155 WAIT_TIME_TDLS_MGMT);
15156
Hoonki Leed37cbb32013-04-20 00:31:14 -070015157 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
15158 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
15159
15160 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015161 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070015162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015163 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070015164 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015165 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080015166
15167 if (pHddCtx->isLogpInProgress)
15168 {
15169 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15170 "%s: LOGP in Progress. Ignore!!!", __func__);
15171 return -EAGAIN;
15172 }
15173
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015174 ret = -EINVAL;
15175 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015176 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015177 else
15178 {
15179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15180 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
15181 __func__, rc, pAdapter->mgmtTxCompletionStatus);
15182 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015183
Gopichand Nakkala05922802013-03-14 12:23:19 -070015184 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070015185 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015186 ret = max_sta_failed;
15187 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070015188 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015189
Hoonki Leea34dd892013-02-05 22:56:02 -080015190 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
15191 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015192 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015193 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15194 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015195 }
15196 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
15197 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015198 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015199 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15200 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015201 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015202
15203 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015204
15205tx_failed:
15206 /* add_station will be called before sending TDLS_SETUP_REQ and
15207 * TDLS_SETUP_RSP and as part of add_station driver will enable
15208 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
15209 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
15210 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
15211 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
15212 */
15213
15214 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
15215 (SIR_MAC_TDLS_SETUP_RSP == action_code))
15216 wlan_hdd_tdls_check_bmps(pAdapter);
15217 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015218}
15219
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015220#if TDLS_MGMT_VERSION2
15221static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15222 u8 *peer, u8 action_code, u8 dialog_token,
15223 u16 status_code, u32 peer_capability,
15224 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015225#else /* TDLS_MGMT_VERSION2 */
15226#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
15227static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15228 struct net_device *dev,
15229 const u8 *peer, u8 action_code,
15230 u8 dialog_token, u16 status_code,
15231 u32 peer_capability, bool initiator,
15232 const u8 *buf, size_t len)
15233#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15234static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15235 struct net_device *dev,
15236 const u8 *peer, u8 action_code,
15237 u8 dialog_token, u16 status_code,
15238 u32 peer_capability, const u8 *buf,
15239 size_t len)
15240#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
15241static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15242 struct net_device *dev,
15243 u8 *peer, u8 action_code,
15244 u8 dialog_token,
15245 u16 status_code, u32 peer_capability,
15246 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015247#else
15248static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15249 u8 *peer, u8 action_code, u8 dialog_token,
15250 u16 status_code, const u8 *buf, size_t len)
15251#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015252#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015253{
15254 int ret;
15255
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015256 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015257#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015258 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15259 dialog_token, status_code,
15260 peer_capability, buf, len);
15261#else /* TDLS_MGMT_VERSION2 */
15262#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
15263 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15264 dialog_token, status_code,
15265 peer_capability, initiator,
15266 buf, len);
15267#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
15268 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15269 dialog_token, status_code,
15270 peer_capability, buf, len);
15271#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
15272 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15273 dialog_token, status_code,
15274 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015275#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015276 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15277 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015278#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015279#endif
15280 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015281
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015282 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015283}
Atul Mittal115287b2014-07-08 13:26:33 +053015284
15285int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015286#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15287 const u8 *peer,
15288#else
Atul Mittal115287b2014-07-08 13:26:33 +053015289 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015290#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015291 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053015292 cfg80211_exttdls_callback callback)
15293{
15294
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015295 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053015296 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015297 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053015298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15299 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
15300 __func__, MAC_ADDR_ARRAY(peer));
15301
15302 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15303 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15304
15305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015306 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15307 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15308 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015309 return -ENOTSUPP;
15310 }
15311
15312 /* To cater the requirement of establishing the TDLS link
15313 * irrespective of the data traffic , get an entry of TDLS peer.
15314 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015315 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015316 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
15317 if (pTdlsPeer == NULL) {
15318 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15319 "%s: peer " MAC_ADDRESS_STR " not existing",
15320 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015321 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015322 return -EINVAL;
15323 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015324 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015325
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015326 /* check FW TDLS Off Channel capability */
15327 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015328 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015329 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015330 {
15331 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
15332 pTdlsPeer->peerParams.global_operating_class =
15333 tdls_peer_params->global_operating_class;
15334 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
15335 pTdlsPeer->peerParams.min_bandwidth_kbps =
15336 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015337 /* check configured channel is valid, non dfs and
15338 * not current operating channel */
15339 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
15340 tdls_peer_params->channel)) &&
15341 (pHddStaCtx) &&
15342 (tdls_peer_params->channel !=
15343 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015344 {
15345 pTdlsPeer->isOffChannelConfigured = TRUE;
15346 }
15347 else
15348 {
15349 pTdlsPeer->isOffChannelConfigured = FALSE;
15350 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15351 "%s: Configured Tdls Off Channel is not valid", __func__);
15352
15353 }
15354 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015355 "%s: tdls_off_channel %d isOffChannelConfigured %d "
15356 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015357 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015358 pTdlsPeer->isOffChannelConfigured,
15359 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015360 }
15361 else
15362 {
15363 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015364 "%s: TDLS off channel FW capability %d, "
15365 "host capab %d or Invalid TDLS Peer Params", __func__,
15366 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
15367 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015368 }
15369
Atul Mittal115287b2014-07-08 13:26:33 +053015370 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
15371
15372 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15373 " %s TDLS Add Force Peer Failed",
15374 __func__);
15375 return -EINVAL;
15376 }
15377 /*EXT TDLS*/
15378
15379 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
15380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15381 " %s TDLS set callback Failed",
15382 __func__);
15383 return -EINVAL;
15384 }
15385
15386 return(0);
15387
15388}
15389
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015390int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
15391#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15392 const u8 *peer
15393#else
15394 u8 *peer
15395#endif
15396)
Atul Mittal115287b2014-07-08 13:26:33 +053015397{
15398
15399 hddTdlsPeer_t *pTdlsPeer;
15400 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15402 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
15403 __func__, MAC_ADDR_ARRAY(peer));
15404
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015405 if (0 != wlan_hdd_validate_context(pHddCtx)) {
15406 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
15407 return -EINVAL;
15408 }
15409
Atul Mittal115287b2014-07-08 13:26:33 +053015410 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15411 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15412
15413 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015414 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15415 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15416 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015417 return -ENOTSUPP;
15418 }
15419
15420
15421 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15422
15423 if ( NULL == pTdlsPeer ) {
15424 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015425 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053015426 __func__, MAC_ADDR_ARRAY(peer));
15427 return -EINVAL;
15428 }
15429 else {
15430 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
15431 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015432 /* if channel switch is configured, reset
15433 the channel for this peer */
15434 if (TRUE == pTdlsPeer->isOffChannelConfigured)
15435 {
15436 pTdlsPeer->peerParams.channel = 0;
15437 pTdlsPeer->isOffChannelConfigured = FALSE;
15438 }
Atul Mittal115287b2014-07-08 13:26:33 +053015439 }
15440
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015441 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
15442 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053015443 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015444 }
Atul Mittal115287b2014-07-08 13:26:33 +053015445
15446 /*EXT TDLS*/
15447
15448 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
15449
15450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15451 " %s TDLS set callback Failed",
15452 __func__);
15453 return -EINVAL;
15454 }
15455 return(0);
15456
15457}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015458static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015459#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15460 const u8 *peer,
15461#else
15462 u8 *peer,
15463#endif
15464 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015465{
15466 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15467 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015468 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015469 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015470
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015471 ENTER();
15472
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015473 if (!pAdapter) {
15474 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15475 return -EINVAL;
15476 }
15477
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015478 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15479 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
15480 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015481 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015482 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070015484 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015485 return -EINVAL;
15486 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015487
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015488 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015489 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015490 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015491 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015492 }
15493
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015494
15495 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015496 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015497 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015499 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
15500 "Cannot process TDLS commands",
15501 pHddCtx->cfg_ini->fEnableTDLSSupport,
15502 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015503 return -ENOTSUPP;
15504 }
15505
15506 switch (oper) {
15507 case NL80211_TDLS_ENABLE_LINK:
15508 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015509 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015510 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015511 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053015512 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015513 tANI_U16 numCurrTdlsPeers = 0;
15514 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015515 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015516
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15518 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
15519 __func__, MAC_ADDR_ARRAY(peer));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015520 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015521 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015522 if ( NULL == pTdlsPeer ) {
15523 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15524 " (oper %d) not exsting. ignored",
15525 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15526 return -EINVAL;
15527 }
15528
15529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15530 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15531 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15532 "NL80211_TDLS_ENABLE_LINK");
15533
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070015534 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
15535 {
15536 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
15537 MAC_ADDRESS_STR " failed",
15538 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
15539 return -EINVAL;
15540 }
15541
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053015542 /* before starting tdls connection, set tdls
15543 * off channel established status to default value */
15544 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015545 /* TDLS Off Channel, Disable tdls channel switch,
15546 when there are more than one tdls link */
15547 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053015548 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015549 {
15550 /* get connected peer and send disable tdls off chan */
15551 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015552 if ((connPeer) &&
15553 (connPeer->isOffChannelSupported == TRUE) &&
15554 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015555 {
15556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15557 "%s: More then one peer connected, Disable "
15558 "TDLS channel switch", __func__);
15559
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015560 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015561 ret = sme_SendTdlsChanSwitchReq(
15562 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015563 pAdapter->sessionId,
15564 connPeer->peerMac,
15565 connPeer->peerParams.channel,
15566 TDLS_OFF_CHANNEL_BW_OFFSET,
15567 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015568 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015569 hddLog(VOS_TRACE_LEVEL_ERROR,
15570 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015571 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015572 }
15573 else
15574 {
15575 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15576 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015577 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015578 "isOffChannelConfigured %d",
15579 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015580 (connPeer ? (connPeer->isOffChannelSupported)
15581 : -1),
15582 (connPeer ? (connPeer->isOffChannelConfigured)
15583 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015584 }
15585 }
15586
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015587 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015588 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015589 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053015590
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015591 if (0 != wlan_hdd_tdls_get_link_establish_params(
15592 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015593 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015594 return -EINVAL;
15595 }
15596 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015597
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015598 ret = sme_SendTdlsLinkEstablishParams(
15599 WLAN_HDD_GET_HAL_CTX(pAdapter),
15600 pAdapter->sessionId, peer,
15601 &tdlsLinkEstablishParams);
15602 if (ret != VOS_STATUS_SUCCESS) {
15603 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
15604 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015605 /* Send TDLS peer UAPSD capabilities to the firmware and
15606 * register with the TL on after the response for this operation
15607 * is received .
15608 */
15609 ret = wait_for_completion_interruptible_timeout(
15610 &pAdapter->tdls_link_establish_req_comp,
15611 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
15612 if (ret <= 0)
15613 {
15614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015615 FL("Link Establish Request Failed Status %ld"),
15616 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015617 return -EINVAL;
15618 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015619 }
Atul Mittal115287b2014-07-08 13:26:33 +053015620 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15621 eTDLS_LINK_CONNECTED,
15622 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015623 staDesc.ucSTAId = pTdlsPeer->staId;
15624 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015625 ret = WLANTL_UpdateTdlsSTAClient(
15626 pHddCtx->pvosContext,
15627 &staDesc);
15628 if (ret != VOS_STATUS_SUCCESS) {
15629 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
15630 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053015631
Gopichand Nakkala471708b2013-06-04 20:03:01 +053015632 /* Mark TDLS client Authenticated .*/
15633 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
15634 pTdlsPeer->staId,
15635 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015636 if (VOS_STATUS_SUCCESS == status)
15637 {
Hoonki Lee14621352013-04-16 17:51:19 -070015638 if (pTdlsPeer->is_responder == 0)
15639 {
15640 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
15641
15642 wlan_hdd_tdls_timer_restart(pAdapter,
15643 &pTdlsPeer->initiatorWaitTimeoutTimer,
15644 WAIT_TIME_TDLS_INITIATOR);
15645 /* suspend initiator TX until it receives direct packet from the
15646 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015647 ret = WLANTL_SuspendDataTx(
15648 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15649 &staId, NULL);
15650 if (ret != VOS_STATUS_SUCCESS) {
15651 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
15652 }
Hoonki Lee14621352013-04-16 17:51:19 -070015653 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015654
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015655 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015656 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015657 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015658 suppChannelLen =
15659 tdlsLinkEstablishParams.supportedChannelsLen;
15660
15661 if ((suppChannelLen > 0) &&
15662 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
15663 {
15664 tANI_U8 suppPeerChannel = 0;
15665 int i = 0;
15666 for (i = 0U; i < suppChannelLen; i++)
15667 {
15668 suppPeerChannel =
15669 tdlsLinkEstablishParams.supportedChannels[i];
15670
15671 pTdlsPeer->isOffChannelSupported = FALSE;
15672 if (suppPeerChannel ==
15673 pTdlsPeer->peerParams.channel)
15674 {
15675 pTdlsPeer->isOffChannelSupported = TRUE;
15676 break;
15677 }
15678 }
15679 }
15680 else
15681 {
15682 pTdlsPeer->isOffChannelSupported = FALSE;
15683 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015684 }
15685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15686 "%s: TDLS channel switch request for channel "
15687 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015688 "%d isOffChannelSupported %d", __func__,
15689 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015690 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015691 suppChannelLen,
15692 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015693
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015694 /* TDLS Off Channel, Enable tdls channel switch,
15695 when their is only one tdls link and it supports */
15696 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15697 if ((numCurrTdlsPeers == 1) &&
15698 (TRUE == pTdlsPeer->isOffChannelSupported) &&
15699 (TRUE == pTdlsPeer->isOffChannelConfigured))
15700 {
15701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15702 "%s: Send TDLS channel switch request for channel %d",
15703 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015704
15705 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015706 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
15707 pAdapter->sessionId,
15708 pTdlsPeer->peerMac,
15709 pTdlsPeer->peerParams.channel,
15710 TDLS_OFF_CHANNEL_BW_OFFSET,
15711 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015712 if (ret != VOS_STATUS_SUCCESS) {
15713 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
15714 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015715 }
15716 else
15717 {
15718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15719 "%s: TDLS channel switch request not sent"
15720 " numCurrTdlsPeers %d "
15721 "isOffChannelSupported %d "
15722 "isOffChannelConfigured %d",
15723 __func__, numCurrTdlsPeers,
15724 pTdlsPeer->isOffChannelSupported,
15725 pTdlsPeer->isOffChannelConfigured);
15726 }
15727
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015728 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015729 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015730
15731 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015732 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
15733 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015734 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015735 int ac;
15736 uint8 ucAc[4] = { WLANTL_AC_VO,
15737 WLANTL_AC_VI,
15738 WLANTL_AC_BK,
15739 WLANTL_AC_BE };
15740 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
15741 for(ac=0; ac < 4; ac++)
15742 {
15743 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15744 pTdlsPeer->staId, ucAc[ac],
15745 tlTid[ac], tlTid[ac], 0, 0,
15746 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015747 if (status != VOS_STATUS_SUCCESS) {
15748 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
15749 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015750 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015751 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015752 }
15753
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015754 }
15755 break;
15756 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080015757 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015758 tANI_U16 numCurrTdlsPeers = 0;
15759 hddTdlsPeer_t *connPeer = NULL;
15760
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15762 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
15763 __func__, MAC_ADDR_ARRAY(peer));
15764
Sunil Dutt41de4e22013-11-14 18:09:02 +053015765 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15766
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015767
Sunil Dutt41de4e22013-11-14 18:09:02 +053015768 if ( NULL == pTdlsPeer ) {
15769 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15770 " (oper %d) not exsting. ignored",
15771 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15772 return -EINVAL;
15773 }
15774
15775 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15776 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15777 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15778 "NL80211_TDLS_DISABLE_LINK");
15779
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015780 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080015781 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015782 long status;
15783
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053015784 /* set tdls off channel status to false for this peer */
15785 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053015786 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15787 eTDLS_LINK_TEARING,
15788 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
15789 eTDLS_LINK_UNSPECIFIED:
15790 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015791 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
15792
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015793 status = sme_DeleteTdlsPeerSta(
15794 WLAN_HDD_GET_HAL_CTX(pAdapter),
15795 pAdapter->sessionId, peer );
15796 if (status != VOS_STATUS_SUCCESS) {
15797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15798 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015799
15800 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
15801 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053015802 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053015803 eTDLS_LINK_IDLE,
15804 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015805 if (status <= 0)
15806 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15808 "%s: Del station failed status %ld",
15809 __func__, status);
15810 return -EPERM;
15811 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015812
15813 /* TDLS Off Channel, Enable tdls channel switch,
15814 when their is only one tdls link and it supports */
15815 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15816 if (numCurrTdlsPeers == 1)
15817 {
15818 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
15819 if ((connPeer) &&
15820 (connPeer->isOffChannelSupported == TRUE) &&
15821 (connPeer->isOffChannelConfigured == TRUE))
15822 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015823 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015824 status = sme_SendTdlsChanSwitchReq(
15825 WLAN_HDD_GET_HAL_CTX(pAdapter),
15826 pAdapter->sessionId,
15827 connPeer->peerMac,
15828 connPeer->peerParams.channel,
15829 TDLS_OFF_CHANNEL_BW_OFFSET,
15830 TDLS_CHANNEL_SWITCH_ENABLE);
15831 if (status != VOS_STATUS_SUCCESS) {
15832 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
15833 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015834 }
15835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15836 "%s: TDLS channel switch "
15837 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015838 "isOffChannelConfigured %d "
15839 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015840 __func__,
15841 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015842 (connPeer ? connPeer->isOffChannelConfigured : -1),
15843 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015844 }
15845 else
15846 {
15847 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15848 "%s: TDLS channel switch request not sent "
15849 "numCurrTdlsPeers %d ",
15850 __func__, numCurrTdlsPeers);
15851 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015852 }
15853 else
15854 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015855 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15856 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080015857 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015858 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015859 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015860 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015861 {
Atul Mittal115287b2014-07-08 13:26:33 +053015862 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015863
Atul Mittal115287b2014-07-08 13:26:33 +053015864 if (0 != status)
15865 {
15866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015867 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053015868 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015869 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053015870 break;
15871 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015872 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015873 {
Atul Mittal115287b2014-07-08 13:26:33 +053015874 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
15875 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015876 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053015877 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015878
Atul Mittal115287b2014-07-08 13:26:33 +053015879 if (0 != status)
15880 {
15881 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015882 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053015883 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053015884 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053015885 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015886 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015887 case NL80211_TDLS_DISCOVERY_REQ:
15888 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015889 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015890 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015891 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015892 return -ENOTSUPP;
15893 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15895 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015896 return -ENOTSUPP;
15897 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015898
15899 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015900 return 0;
15901}
Chilam NG571c65a2013-01-19 12:27:36 +053015902
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015903static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015904#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15905 const u8 *peer,
15906#else
15907 u8 *peer,
15908#endif
15909 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015910{
15911 int ret;
15912
15913 vos_ssr_protect(__func__);
15914 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
15915 vos_ssr_unprotect(__func__);
15916
15917 return ret;
15918}
15919
Chilam NG571c65a2013-01-19 12:27:36 +053015920int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
15921 struct net_device *dev, u8 *peer)
15922{
Arif Hussaina7c8e412013-11-20 11:06:42 -080015923 hddLog(VOS_TRACE_LEVEL_INFO,
15924 "tdls send discover req: "MAC_ADDRESS_STR,
15925 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053015926
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015927#if TDLS_MGMT_VERSION2
15928 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15929 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15930#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015931#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
15932 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15933 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
15934#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15935 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15936 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15937#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
15938 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15939 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15940#else
Chilam NG571c65a2013-01-19 12:27:36 +053015941 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15942 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015943#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015944#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053015945}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015946#endif
15947
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015948#ifdef WLAN_FEATURE_GTK_OFFLOAD
15949/*
15950 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
15951 * Callback rountine called upon receiving response for
15952 * get offload info
15953 */
15954void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
15955 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
15956{
15957
15958 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015959 tANI_U8 tempReplayCounter[8];
15960 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015961
15962 ENTER();
15963
15964 if (NULL == pAdapter)
15965 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053015966 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015967 "%s: HDD adapter is Null", __func__);
15968 return ;
15969 }
15970
15971 if (NULL == pGtkOffloadGetInfoRsp)
15972 {
15973 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15974 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
15975 return ;
15976 }
15977
15978 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
15979 {
15980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15981 "%s: wlan Failed to get replay counter value",
15982 __func__);
15983 return ;
15984 }
15985
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015986 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15987 /* Update replay counter */
15988 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
15989 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15990
15991 {
15992 /* changing from little to big endian since supplicant
15993 * works on big endian format
15994 */
15995 int i;
15996 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15997
15998 for (i = 0; i < 8; i++)
15999 {
16000 tempReplayCounter[7-i] = (tANI_U8)p[i];
16001 }
16002 }
16003
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016004 /* Update replay counter to NL */
16005 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016006 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016007}
16008
16009/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016010 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016011 * This function is used to offload GTK rekeying job to the firmware.
16012 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016013int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016014 struct cfg80211_gtk_rekey_data *data)
16015{
16016 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16017 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16018 hdd_station_ctx_t *pHddStaCtx;
16019 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016020 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016021 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016022 eHalStatus status = eHAL_STATUS_FAILURE;
16023
16024 ENTER();
16025
16026 if (NULL == pAdapter)
16027 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016028 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016029 "%s: HDD adapter is Null", __func__);
16030 return -ENODEV;
16031 }
16032
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016033 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16034 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
16035 pAdapter->sessionId, pAdapter->device_mode));
16036
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016037 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016038 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016039 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016040 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016041 }
16042
16043 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16044 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16045 if (NULL == hHal)
16046 {
16047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16048 "%s: HAL context is Null!!!", __func__);
16049 return -EAGAIN;
16050 }
16051
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016052 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
16053 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
16054 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
16055 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016056 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016057 {
16058 /* changing from big to little endian since driver
16059 * works on little endian format
16060 */
16061 tANI_U8 *p =
16062 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
16063 int i;
16064
16065 for (i = 0; i < 8; i++)
16066 {
16067 p[7-i] = data->replay_ctr[i];
16068 }
16069 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016070
16071 if (TRUE == pHddCtx->hdd_wlan_suspended)
16072 {
16073 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016074 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
16075 sizeof (tSirGtkOffloadParams));
16076 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016077 pAdapter->sessionId);
16078
16079 if (eHAL_STATUS_SUCCESS != status)
16080 {
16081 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16082 "%s: sme_SetGTKOffload failed, returned %d",
16083 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016084
16085 /* Need to clear any trace of key value in the memory.
16086 * Thus zero out the memory even though it is local
16087 * variable.
16088 */
16089 vos_mem_zero(&hddGtkOffloadReqParams,
16090 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016091 return status;
16092 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016093 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16094 "%s: sme_SetGTKOffload successfull", __func__);
16095 }
16096 else
16097 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16099 "%s: wlan not suspended GTKOffload request is stored",
16100 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016101 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016102
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016103 /* Need to clear any trace of key value in the memory.
16104 * Thus zero out the memory even though it is local
16105 * variable.
16106 */
16107 vos_mem_zero(&hddGtkOffloadReqParams,
16108 sizeof(hddGtkOffloadReqParams));
16109
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016110 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016111 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016112}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016113
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016114int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
16115 struct cfg80211_gtk_rekey_data *data)
16116{
16117 int ret;
16118
16119 vos_ssr_protect(__func__);
16120 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
16121 vos_ssr_unprotect(__func__);
16122
16123 return ret;
16124}
16125#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016126/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016127 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016128 * This function is used to set access control policy
16129 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016130static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16131 struct net_device *dev,
16132 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016133{
16134 int i;
16135 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16136 hdd_hostapd_state_t *pHostapdState;
16137 tsap_Config_t *pConfig;
16138 v_CONTEXT_t pVosContext = NULL;
16139 hdd_context_t *pHddCtx;
16140 int status;
16141
16142 ENTER();
16143
16144 if (NULL == pAdapter)
16145 {
16146 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16147 "%s: HDD adapter is Null", __func__);
16148 return -ENODEV;
16149 }
16150
16151 if (NULL == params)
16152 {
16153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16154 "%s: params is Null", __func__);
16155 return -EINVAL;
16156 }
16157
16158 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16159 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016160 if (0 != status)
16161 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016162 return status;
16163 }
16164
16165 pVosContext = pHddCtx->pvosContext;
16166 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
16167
16168 if (NULL == pHostapdState)
16169 {
16170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16171 "%s: pHostapdState is Null", __func__);
16172 return -EINVAL;
16173 }
16174
16175 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
16176 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016177 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16178 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
16179 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016180
16181 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
16182 {
16183 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
16184
16185 /* default value */
16186 pConfig->num_accept_mac = 0;
16187 pConfig->num_deny_mac = 0;
16188
16189 /**
16190 * access control policy
16191 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
16192 * listed in hostapd.deny file.
16193 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
16194 * listed in hostapd.accept file.
16195 */
16196 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
16197 {
16198 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
16199 }
16200 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
16201 {
16202 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
16203 }
16204 else
16205 {
16206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16207 "%s:Acl Policy : %d is not supported",
16208 __func__, params->acl_policy);
16209 return -ENOTSUPP;
16210 }
16211
16212 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
16213 {
16214 pConfig->num_accept_mac = params->n_acl_entries;
16215 for (i = 0; i < params->n_acl_entries; i++)
16216 {
16217 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16218 "** Add ACL MAC entry %i in WhiletList :"
16219 MAC_ADDRESS_STR, i,
16220 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16221
16222 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
16223 sizeof(qcmacaddr));
16224 }
16225 }
16226 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
16227 {
16228 pConfig->num_deny_mac = params->n_acl_entries;
16229 for (i = 0; i < params->n_acl_entries; i++)
16230 {
16231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16232 "** Add ACL MAC entry %i in BlackList :"
16233 MAC_ADDRESS_STR, i,
16234 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16235
16236 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
16237 sizeof(qcmacaddr));
16238 }
16239 }
16240
16241 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
16242 {
16243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16244 "%s: SAP Set Mac Acl fail", __func__);
16245 return -EINVAL;
16246 }
16247 }
16248 else
16249 {
16250 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016251 "%s: Invalid device_mode = %s (%d)",
16252 __func__, hdd_device_modetoString(pAdapter->device_mode),
16253 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016254 return -EINVAL;
16255 }
16256
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016257 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016258 return 0;
16259}
16260
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016261static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16262 struct net_device *dev,
16263 const struct cfg80211_acl_data *params)
16264{
16265 int ret;
16266 vos_ssr_protect(__func__);
16267 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
16268 vos_ssr_unprotect(__func__);
16269
16270 return ret;
16271}
16272
Leo Chang9056f462013-08-01 19:21:11 -070016273#ifdef WLAN_NL80211_TESTMODE
16274#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070016275void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070016276(
16277 void *pAdapter,
16278 void *indCont
16279)
16280{
Leo Changd9df8aa2013-09-26 13:32:26 -070016281 tSirLPHBInd *lphbInd;
16282 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053016283 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070016284
16285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016286 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070016287
c_hpothu73f35e62014-04-18 13:40:08 +053016288 if (pAdapter == NULL)
16289 {
16290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16291 "%s: pAdapter is NULL\n",__func__);
16292 return;
16293 }
16294
Leo Chang9056f462013-08-01 19:21:11 -070016295 if (NULL == indCont)
16296 {
16297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016298 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070016299 return;
16300 }
16301
c_hpothu73f35e62014-04-18 13:40:08 +053016302 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070016303 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070016304 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053016305 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070016306 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070016307 GFP_ATOMIC);
16308 if (!skb)
16309 {
16310 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16311 "LPHB timeout, NL buffer alloc fail");
16312 return;
16313 }
16314
Leo Changac3ba772013-10-07 09:47:04 -070016315 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070016316 {
16317 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16318 "WLAN_HDD_TM_ATTR_CMD put fail");
16319 goto nla_put_failure;
16320 }
Leo Changac3ba772013-10-07 09:47:04 -070016321 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070016322 {
16323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16324 "WLAN_HDD_TM_ATTR_TYPE put fail");
16325 goto nla_put_failure;
16326 }
Leo Changac3ba772013-10-07 09:47:04 -070016327 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070016328 sizeof(tSirLPHBInd), lphbInd))
16329 {
16330 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16331 "WLAN_HDD_TM_ATTR_DATA put fail");
16332 goto nla_put_failure;
16333 }
Leo Chang9056f462013-08-01 19:21:11 -070016334 cfg80211_testmode_event(skb, GFP_ATOMIC);
16335 return;
16336
16337nla_put_failure:
16338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16339 "NLA Put fail");
16340 kfree_skb(skb);
16341
16342 return;
16343}
16344#endif /* FEATURE_WLAN_LPHB */
16345
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016346static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070016347{
16348 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
16349 int err = 0;
16350#ifdef FEATURE_WLAN_LPHB
16351 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070016352 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016353
16354 ENTER();
16355
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016356 err = wlan_hdd_validate_context(pHddCtx);
16357 if (0 != err)
16358 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016359 return err;
16360 }
Leo Chang9056f462013-08-01 19:21:11 -070016361#endif /* FEATURE_WLAN_LPHB */
16362
16363 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
16364 if (err)
16365 {
16366 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16367 "%s Testmode INV ATTR", __func__);
16368 return err;
16369 }
16370
16371 if (!tb[WLAN_HDD_TM_ATTR_CMD])
16372 {
16373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16374 "%s Testmode INV CMD", __func__);
16375 return -EINVAL;
16376 }
16377
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016378 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16379 TRACE_CODE_HDD_CFG80211_TESTMODE,
16380 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070016381 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
16382 {
16383#ifdef FEATURE_WLAN_LPHB
16384 /* Low Power Heartbeat configuration request */
16385 case WLAN_HDD_TM_CMD_WLAN_HB:
16386 {
16387 int buf_len;
16388 void *buf;
16389 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080016390 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070016391
16392 if (!tb[WLAN_HDD_TM_ATTR_DATA])
16393 {
16394 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16395 "%s Testmode INV DATA", __func__);
16396 return -EINVAL;
16397 }
16398
16399 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
16400 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080016401
16402 hb_params_temp =(tSirLPHBReq *)buf;
16403 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
16404 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
16405 return -EINVAL;
16406
Leo Chang9056f462013-08-01 19:21:11 -070016407 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
16408 if (NULL == hb_params)
16409 {
16410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16411 "%s Request Buffer Alloc Fail", __func__);
16412 return -EINVAL;
16413 }
16414
16415 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070016416 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
16417 hb_params,
16418 wlan_hdd_cfg80211_lphb_ind_handler);
16419 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070016420 {
Leo Changd9df8aa2013-09-26 13:32:26 -070016421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16422 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070016423 vos_mem_free(hb_params);
16424 }
Leo Chang9056f462013-08-01 19:21:11 -070016425 return 0;
16426 }
16427#endif /* FEATURE_WLAN_LPHB */
16428 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16430 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070016431 return -EOPNOTSUPP;
16432 }
16433
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016434 EXIT();
16435 return err;
Leo Chang9056f462013-08-01 19:21:11 -070016436}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016437
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053016438static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
16439#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
16440 struct wireless_dev *wdev,
16441#endif
16442 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016443{
16444 int ret;
16445
16446 vos_ssr_protect(__func__);
16447 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
16448 vos_ssr_unprotect(__func__);
16449
16450 return ret;
16451}
Leo Chang9056f462013-08-01 19:21:11 -070016452#endif /* CONFIG_NL80211_TESTMODE */
16453
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016454static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016455 struct net_device *dev,
16456 int idx, struct survey_info *survey)
16457{
16458 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16459 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053016460 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016461 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053016462 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016463 v_S7_t snr,rssi;
16464 int status, i, j, filled = 0;
16465
16466 ENTER();
16467
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016468 if (NULL == pAdapter)
16469 {
16470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16471 "%s: HDD adapter is Null", __func__);
16472 return -ENODEV;
16473 }
16474
16475 if (NULL == wiphy)
16476 {
16477 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16478 "%s: wiphy is Null", __func__);
16479 return -ENODEV;
16480 }
16481
16482 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16483 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016484 if (0 != status)
16485 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016486 return status;
16487 }
16488
Mihir Sheted9072e02013-08-21 17:02:29 +053016489 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16490
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016491 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053016492 0 != pAdapter->survey_idx ||
16493 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016494 {
16495 /* The survey dump ops when implemented completely is expected to
16496 * return a survey of all channels and the ops is called by the
16497 * kernel with incremental values of the argument 'idx' till it
16498 * returns -ENONET. But we can only support the survey for the
16499 * operating channel for now. survey_idx is used to track
16500 * that the ops is called only once and then return -ENONET for
16501 * the next iteration
16502 */
16503 pAdapter->survey_idx = 0;
16504 return -ENONET;
16505 }
16506
Mukul Sharma9d5233b2015-06-11 20:28:20 +053016507 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16508 {
16509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16510 "%s: Roaming in progress, hence return ", __func__);
16511 return -ENONET;
16512 }
16513
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016514 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16515
16516 wlan_hdd_get_snr(pAdapter, &snr);
16517 wlan_hdd_get_rssi(pAdapter, &rssi);
16518
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016519 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16520 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
16521 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016522 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
16523 hdd_wlan_get_freq(channel, &freq);
16524
16525
16526 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
16527 {
16528 if (NULL == wiphy->bands[i])
16529 {
16530 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
16531 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
16532 continue;
16533 }
16534
16535 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
16536 {
16537 struct ieee80211_supported_band *band = wiphy->bands[i];
16538
16539 if (band->channels[j].center_freq == (v_U16_t)freq)
16540 {
16541 survey->channel = &band->channels[j];
16542 /* The Rx BDs contain SNR values in dB for the received frames
16543 * while the supplicant expects noise. So we calculate and
16544 * return the value of noise (dBm)
16545 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
16546 */
16547 survey->noise = rssi - snr;
16548 survey->filled = SURVEY_INFO_NOISE_DBM;
16549 filled = 1;
16550 }
16551 }
16552 }
16553
16554 if (filled)
16555 pAdapter->survey_idx = 1;
16556 else
16557 {
16558 pAdapter->survey_idx = 0;
16559 return -ENONET;
16560 }
16561
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016562 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016563 return 0;
16564}
16565
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016566static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
16567 struct net_device *dev,
16568 int idx, struct survey_info *survey)
16569{
16570 int ret;
16571
16572 vos_ssr_protect(__func__);
16573 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
16574 vos_ssr_unprotect(__func__);
16575
16576 return ret;
16577}
16578
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016579/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016580 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016581 * this is called when cfg80211 driver resume
16582 * driver updates latest sched_scan scan result(if any) to cfg80211 database
16583 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016584int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016585{
16586 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16587 hdd_adapter_t *pAdapter;
16588 hdd_adapter_list_node_t *pAdapterNode, *pNext;
16589 VOS_STATUS status = VOS_STATUS_SUCCESS;
16590
16591 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016592
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016593 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016594 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016595 return 0;
16596 }
16597
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016598 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
16599 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016600 spin_lock(&pHddCtx->schedScan_lock);
16601 pHddCtx->isWiphySuspended = FALSE;
16602 if (TRUE != pHddCtx->isSchedScanUpdatePending)
16603 {
16604 spin_unlock(&pHddCtx->schedScan_lock);
16605 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16606 "%s: Return resume is not due to PNO indication", __func__);
16607 return 0;
16608 }
16609 // Reset flag to avoid updatating cfg80211 data old results again
16610 pHddCtx->isSchedScanUpdatePending = FALSE;
16611 spin_unlock(&pHddCtx->schedScan_lock);
16612
16613 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
16614
16615 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
16616 {
16617 pAdapter = pAdapterNode->pAdapter;
16618 if ( (NULL != pAdapter) &&
16619 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
16620 {
16621 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016622 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16624 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016625 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016626 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016627 {
16628 /* Acquire wakelock to handle the case where APP's tries to
16629 * suspend immediately after updating the scan results. Whis
16630 * results in app's is in suspended state and not able to
16631 * process the connect request to AP
16632 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053016633 hdd_prevent_suspend_timeout(2000,
16634 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016635 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016636 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016637
16638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16639 "%s : cfg80211 scan result database updated", __func__);
16640
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016641 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016642 return 0;
16643
16644 }
16645 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16646 pAdapterNode = pNext;
16647 }
16648
16649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16650 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016651 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016652 return 0;
16653}
16654
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016655int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
16656{
16657 int ret;
16658
16659 vos_ssr_protect(__func__);
16660 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
16661 vos_ssr_unprotect(__func__);
16662
16663 return ret;
16664}
16665
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016666/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016667 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016668 * this is called when cfg80211 driver suspends
16669 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016670int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016671 struct cfg80211_wowlan *wow)
16672{
16673 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016674 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016675
16676 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016677
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016678 ret = wlan_hdd_validate_context(pHddCtx);
16679 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016680 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016681 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016682 }
16683
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016684
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016685 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16686 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
16687 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016688 pHddCtx->isWiphySuspended = TRUE;
16689
16690 EXIT();
16691
16692 return 0;
16693}
16694
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016695int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
16696 struct cfg80211_wowlan *wow)
16697{
16698 int ret;
16699
16700 vos_ssr_protect(__func__);
16701 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
16702 vos_ssr_unprotect(__func__);
16703
16704 return ret;
16705}
Jeff Johnson295189b2012-06-20 16:38:30 -070016706/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016707static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070016708{
16709 .add_virtual_intf = wlan_hdd_add_virtual_intf,
16710 .del_virtual_intf = wlan_hdd_del_virtual_intf,
16711 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
16712 .change_station = wlan_hdd_change_station,
16713#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
16714 .add_beacon = wlan_hdd_cfg80211_add_beacon,
16715 .del_beacon = wlan_hdd_cfg80211_del_beacon,
16716 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016717#else
16718 .start_ap = wlan_hdd_cfg80211_start_ap,
16719 .change_beacon = wlan_hdd_cfg80211_change_beacon,
16720 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070016721#endif
16722 .change_bss = wlan_hdd_cfg80211_change_bss,
16723 .add_key = wlan_hdd_cfg80211_add_key,
16724 .get_key = wlan_hdd_cfg80211_get_key,
16725 .del_key = wlan_hdd_cfg80211_del_key,
16726 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016727#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070016728 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016729#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016730 .scan = wlan_hdd_cfg80211_scan,
16731 .connect = wlan_hdd_cfg80211_connect,
16732 .disconnect = wlan_hdd_cfg80211_disconnect,
16733 .join_ibss = wlan_hdd_cfg80211_join_ibss,
16734 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
16735 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
16736 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
16737 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070016738 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
16739 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053016740 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070016741#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16742 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
16743 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
16744 .set_txq_params = wlan_hdd_set_txq_params,
16745#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016746 .get_station = wlan_hdd_cfg80211_get_station,
16747 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
16748 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016749 .add_station = wlan_hdd_cfg80211_add_station,
16750#ifdef FEATURE_WLAN_LFR
16751 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
16752 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
16753 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
16754#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016755#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
16756 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
16757#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016758#ifdef FEATURE_WLAN_TDLS
16759 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
16760 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
16761#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016762#ifdef WLAN_FEATURE_GTK_OFFLOAD
16763 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
16764#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016765#ifdef FEATURE_WLAN_SCAN_PNO
16766 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
16767 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
16768#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016769 .resume = wlan_hdd_cfg80211_resume_wlan,
16770 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016771 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070016772#ifdef WLAN_NL80211_TESTMODE
16773 .testmode_cmd = wlan_hdd_cfg80211_testmode,
16774#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016775 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070016776};
16777